字符和字符串
1. C-stype string
C风格字符串:以null character结尾('\0')
->放在数组中的char序列只有以\0结尾才是一个字符串,否则只是一个char数组。
->char cat[] = "pangpang";
->sizeof(数组名) 返回数组占用空间大小(元素个数x每个元素的大小)
所以 sizeof(cat)包含了\0的大小。strlen(cat) 不包含\0的大小。
sizeof(cat) == strlen(cat) + 1
2. cin
使用空白字符(空格 tab键 换行符)来确定字符串的结束位置,并自动在结尾添加\0。
所以用cin只能读取一个单词 不能读取一个句子
3.getline()
读取整行,通过换行符确定输入结尾,不保存换行符 末尾加\0。cin.getline()
cin.getline(car, 20);
4.get()
读取整行,但是不丢弃换行符,而是将其留在输入队列中。
如果连续调用两次get(),第二次获取的就是这个换行符。
cin.get(name1, size1); // 读取第一行
cin.get(); // 处理输入队列中上面语句留下的换行符
cin.get(name2, size2); // 读取第二行
-------------------------------------
cin.get(name1, size1).get(); // get返回的是cin对象,通过此对象再调用get()函数
cin.getline() 返回的也是cin对象
getline(cin, string)
5.std::string对象
可以使用C风格字符串初始化string对象。
可以使用cin键盘输入存储到string对象。
可以使用cout显示string对象。
可以使用数据表示法访问存储在string对象中的字符。string[n]
6.C风格字符串与string对比
strcat拼接 strcpy拷贝
string可以直接调用成员方法和操作符
★C++的初始化列表可以避免缩窄转换,编译时会报错
结构体
1.struct struct_name {};
C语言声明结构体struct_name类型的变量:struct struct_name struct_var_name;
C++声明结构体struct_name类型的变量:struct_name struct_var_name;
2.结构体中的位字段
struct name
{
unsigned int SN:4;
...
}
共用体union
1.长度是最大长度成员的长度,每次只能存储一个值
2.匿名共用体anonymous union,没有名称,其成员是位于相同地址处的变量
struct widget
{
char brand[20];
union
{
long id;
char id_char;
}
}
widget prize;
prize.id;
prize.id_char;
枚举enum
1.提供创建符号常量的方式,可以替代const。
2.定义新类型
指针与数组
1.int* p1, p2; // p1是指向int的指针,p2是int类型变量
2.对空指针使用delete是安全的
3.动态数组,指针和数组名的用法几乎相同
1.差别,数组名不是变量,不能修改值。
2.sizeof(数组名)得到数组的长度,sizeof(指针)得到指针的大小。
int* pInt = new int[3];
pInt[0] = 1;
pInt[1] = 2;
pInt = pInt +1;
4.指针和数组基本等价的原因是指针算术和C++内部处理数组的方式。
C++将数组名解释为地址,数组第一个元素的地址。
pInt[1] <=> *(pInt+1)
5.数组的地址与指针
short tell[10];
tell -> 数组第一个元素的地址&tell[0]
&tell -> 整个数组的地址,从数值上看与tell值相等,但是意思不同
tell+1 -> 地址加 1 个short
&tell+1 -> 地址加20个short
short(*pas)[20] = &tell; // 其类型为short(*)[20]
(*pas0[0]是tell数组的第一个元素
6.char* ps; cin >> ps; cout << ps;都是严重错误。ps没有分配空间
7.const char* pStr = "cat";
pStr为"cat"的地址;"cat"是字符串字面值常量,pStr只能用来访问,不能用来修改。
8.如果给cout一个指针,则打印地址。但是如果是char*,则打印字符串,
如果要打印字符串的地址,那么要打印(int*)ps。
9.自动存储:自动变量automatic variable
使用自动存储空间,存储在栈中,先定义的后释放:先进后出LIFO
静态存储:函数外定义或者函数内定义为static XXX
动态存储:new/delete管理的内存池,称为堆(heap)或者自由存储空间(free store)
10.const struct_name *art[3] = {&s1, &s2, &s3}; // 指针数组art[0]是一个指针
auto ppArt = art; pArt的类型为const sturct_name ** 指向art数组的一个指针
// art是数组名,是指向第一个元素的指针,pArt是一个指针,指向const struct_name的指针
vector & array
1.vector是动态数组。
效率比数组低,是new创建动态数组的替代品。内部使用new/delete自动管理内存。
vector<typeName> vect(n); // n可以是常量也可以是变量
2.array固定长度,使用栈存储数据,效率与数组相同。
array<typeName, n_element> arr; // n_element不能是变量
★C++11中均可使用初始化列表初始化,C++98不可以。
3.vector array 数组都支持下标访问;array 数组在栈区,vector在堆区;
array对象可以给另一个array对象赋值(大小一致),数组和vector必须逐元素复制数据。
4.下标访问 VA .at()
at() 运行时捕捉非法索引,代价是效率比下标低;下标访问不会报错,产生未知行为。