C++一些基本复合数据类型,字符串、string类型、结构、枚举、共用体、指针
背景
C++复合类型
复合类型
字符串
面向行的输入: getline()读取整行,通过回车键输入的换行符结束。
$ cin.getline(str,num); 将一串字符读入到一个包含num个元素的数组中。
面向行的输入: get() 与getline()相似,但读取换行符,需再次调用来换行。
cin.get(str,num); //读取第一行
cin.get(); //使用不带参数调用可读取下一个字符,即使是换行符
cin.get(str1,num); //读取第二行
#include <iostream>
#include <string>
int main()
{
using namespace std;
const int Size = 20;
//char name1[Size];
//char name2[Size];
string name1,name2;
cout << "Enter your first name: ";
//cin.getline(name1,Size); 不能与string类型的变量搭配。
cin >> name1;
cout << "Enter your last name: ";
//cin.get(name2,Size);
//cin.get();
cin >> name2;
cout << "Here's information in a single string: " << name1 << ", " << name2;
cout << endl;
return 0;
}
//使用char数组和头文件cstring中函数,拼接名字
#include <iostream>
#include <cstring>
int main()
{
using namespace std;
const int Size = 15;
char name1[Size];
char name2[Size];
cout << "Enetr your first name: ";
cin >> name1;
cout << "Enter your last name: ";
cin >> name2;
cout << "Here's the information in a string string: " << name1 << ", " << name2;
cout << endl;
return 0;
}
string类型
string类型的变量,std::string str;
1、声明创建时长度为0,程序执行时自动调整str字符串的长度;
2、与普通字符串数组的区别是,string类对象可以赋值给另一个string类对象;
3、字符串合并,可直接使用运算符‘+ =’.
#include<iostream>
#include<string>
int main()
{
using namespace std;
string name, dessert;
cout << "Enter your name:\n";
cin >> name;
cout << "Enter your favorite dessert: \n";
cin >> dessert;
cout << "I have some delicious " << dessert;
cout << "for you, " << name << endl;
return 0;
}
枚举
枚举enum:一种创建符号常量的方式,可以代替const
1、默认情况下,将整数赋值给枚举量,第一个为0,第二个为1,也可以显式指定整数值给枚举量,下一个枚举量默认加1
2、在不强制转换类型时,只能将定义枚举时使用的枚举量赋值给这种枚举型的变量
//枚举型变量: spectrum 枚举值:
enum spectrum =
{
red, orange, yellow, green, blue, violet, indigo, ultraviolet
};
//声明枚举类型的变量
spectrum band;
//枚举量赋值
band = bule; //只能将已存在的枚举量赋值给枚举型变量band
int color = blue; //枚举量是整型,可以被提升为int型,但是int类型不能自动转换为枚举类型,bulue = 3非法
共用体union
共用体union: 一种数据格式,能够储存不同的数据类型,但同时只能存储其中的一种类型。且必须有足够的空间来存储最大的成员,共用体的最大长度为其最大成员的长度
union onein4all
{
int int_val;
long long_val;
double double_val;
char char_val[10];
}
//使用时只能同时使用其中一种类型
onein4all pail;
pail.int_val = 15; //存储一个整型数据
pail.double = 1.25; //存储一个小数
结构体
1、练习结构体的声明与初始化
2、声明结构变量: 结构体数组
#include <iostream>
struct CandyBar
{
char brand[20];
double weight;
int Calori;
};
int main(int argc, char const *argv[])
{
using namespace std;
//结构体初始化
CandyBar snack = {"Mocha Munch",2.3,350};
cout << "Expand your guest list: " << snack.brand << "," << snack.weight << ", " << snack.Calori;
cout << endl;
//声明结构变量
CandyBar snacks[2] =
{
{"KFC",3.1,520},
{"MacDonald",4.2,600}
};
cout << "The first snack list: " << snacks[0].brand << ", " << snacks[0].weight << ", " << snacks[0].Calori;
cout << endl;
cout << "The second snack list: " << snacks[1].brand << ", " << snacks[1].weight << ", " << snacks[1].Calori;
cout << endl;
return 0;
}
指针
3、使用new为结构分配内存。C++使用关键字new允许程序在运行时请求正确数量的内存,以及使用指针来跟踪新分配的内存的位置
4、指针: int* 是一种复合类型,是指向int的指针
5、int * pt = new int; //程序运行时为一个int值分配未命名的内存,并使用指针pt来访问这个值
6、typeName * pointer = new typeName; //为一个数据对象(结构、基本类型)获得并指定分配的通用格式
7、new从堆或自由存储区的内存区域分配内存,常规变量声明的值存储在栈的内存区域
8、delete: 释放由new分配的内存,一定要配对使用 / int * pt = new int; …; delete pt; delete要加上指向内存块的地址,删除pt指向的内存,但不会删除指针pt本身
9、new的用武之地在于对大型数据(数组、字符串和结构),如使用new创建动态数组: / int * psome = new int [10]; …; delete [] psome; 方括号告诉程序应释放整个数组,而不仅仅是指针指向的元素,注意:psome是指向第一个int(数组第一个元素)的指针
10、通过指针psome使用动态数组: 把指针当做数组名使用,可直接使用psome[index]来操作数组元素,例如,对于第一个元素可以使用psome[0],而不是 *psome
11、指针与数组名的区别: 不能修改数组名的值,但指针是变量,可以修改它的值,如 psome = psome + 1; 表示psome现在指向的数组位置是当前元素的下一个元素
12、数组: short tell[10]; &tell 对数组名运用取地址运算符时,得到的是整个数组的地址。tell是数组第一个元素的地址,等价于&tell[0]. 虽然两者地址相同,但是 / 从概念上&tell是一个20字节(假设short是2个字节)内存块的地址,而tell即&tell[0]是一个2字节内存块的地址
new创建动态结构
1、创建: inflatable * ps = new inflatable; //把一块存储inflatable结构的一块可用的内存地址赋给ps
2、使用: ps表示结构本身,(ps).price 是该结构的price成员
3、释放: delete ps;
变量类型
自动变量: 在函数内部定义的常规变量使用自动存储空间,函数结束自动消亡。存储在栈中,执行代码块时变量将依次加入到栈中,离开时按相反顺序释放,称为后进先出(LIFO ),因此程序执行过程中栈将不断地增大和缩小。
静态变量: 函数外定义 或 声明变量使用关键字static。
动态变量: new/delete,管理一个内存池,称为自由存储空间或堆。允许跨函数释放,但内存管理复杂。在栈中,自动添加和删除机制使得占用内存总是连续的,但new和delete相互影响可能导致占用的自由存储区域不连续,跟踪新分配额内存的位置困难。
数组替代品–模板类vertor和array
1、模板类vector: 类似于string类,一种动态数组,可以在程序运行时设置vector对象的长度,可以在结尾附加新数据或在中间插入新数据。
说明:头文件 #include
使用:模板使用不同语法来指出它存储的数据类型和元素个数
vector<typeName> vt(n_elem)
//声明创建一个名为vt的vector对象,它可存储n_elem个类型为typeName的元素。如 vector<int> vt(1), vt的初始长度可以为零,使用vectord的各种方法调整。
特点: 比数组功能强大,效率稍低。
2、模板类array: 与数组一样,长度固定,也使用栈(静态内存分配),位于名称空间std中。
array<typeName, n_elem> arr;
//声明创建一个名为arr的array对象,它包含n_elem个类型为typeName的元素,如array<int,4> arr;
3、模板类的一些成员函数,如vt.at()、vt.begin()、vt.end()等,可防止越界。
无论数组、vector对象,还是array对象,都可以使用数组表示法访问各个元素。
array对象和数组存储在相同的内存区域(栈)中,而vertor存储在堆。
array对象可以赋值给另一个array对象,如array<int,4> a1,a2; a1 = a2; 而数组必须逐元素赋值。


