复合类型是指基于基本整型和浮点类类型而创建的数据格式。
1. 数组
1.1 声明数组时,必须指定元素数目,且元素数目必须是编译时已知的,所以变量(运行时设置的)不可以用来指定数目;
1.2 如果只对数组的一部分进行初始化,则编译器将其他元素设置为0;
所以初始化整个数组为0可以--int array[10] = {0};
注: C++ 11支持去掉代码中的等号以及0,且不支持缩窄转换;
2. 字符串(C-风格字符串)
2.1 C++处理字符串有两种方式--C-风格字符串 & string类库;
2.2 C-风格字符串以空字符'\0'结尾,没有这种特征则不能称之为C-风格字符串,所以char数组保存字符串时其长度至少应该是strlen(str)+1;
2.3
任何两个由空格' '、制表符'\t'或者换行符'\n'分隔的字符串常量都可以自动拼接为一个字符串常量;
printf("a" "b\n")的输出字符串为"ab\n\0",输出内容为"ab\n";
2.4 cin通过空白' '来确定字符串的结束位置,弥补功能缺陷需要使用std::cin.getline()或者std::cin.get();
std::cin.getline() 丢弃输入流的换行符,std::cin.get() 保留输入流的换行符;
3. 字符串(string类库)
3.1 使用string类需引用头文件string(位于命名空间std之中);
3.2 string类和char数组的区别反映了OOP的思想,string对象是个变量,不需要像数组那样在编译时预先分配好内存,而是在运行时根据实际状况灵活的进行调整;
3.3 不同于C-风格字符串常量的拼接方法,string对象的拼接使用'+'号;
3.4 C字符串函数strlen()、strcpy()、strcat()、strncpy()和strncat()既可以用在C-风格字符串上也可以对string对象使用,当然string类库有自己封装的功能可以完成类似的功能;
4. 结构体
4.1 结构体是一种数据格式,可以存储多种数据类型,C++鼓励外部结构声明,但不提倡外部变量;
4.2 结构体的声明可以省略结构体名称,同时可以声明变量和进行初始化;
结构体初始化和数组类似,可以使用列表初始化,且当列表为空时,所有成员被设置为0;
4.3 结构体重允许指定占用特定位数的结构成员,如:
struct
{
int i : 4;
};
表示成员变量i占用四个字节,不过这种功能一般用于底层编程中;
5. 共用体
5.1 共用体也是一种数据格式,它也能够存储不同类型的数据,不过每次只能存储一个成员;
它的主要功能是节省空间;
5.2 共用体有匿名和未匿名区分;
6. 枚举
6.1 枚举通常被用作符号常量;
6.2 枚举提供了一种创建符号常量的方式,默认情况下,将整数值赋给枚举量,从0开始依次类推;
当然也可以显示的设置枚举量的值,如果只设置了部分值,如:
enum word{a, b=0, c, d=1, e, f=6, g};
则 a=0, b=0, c=1, d=1, e=2, f=6, g=7;
6.3 枚举量之间可以互相赋值,所以枚举的变量最多只有n个可能的值,n为枚举量个数,如:
a=b;// valid
a=1;// invalid
同时,也可以将int类型的值强制转换为枚举类型来对枚举量进行复制,前提是该int类型的值在该枚举类型中本来就有对应的枚举量,如:
a=word(1);// valid
a=word(3);// invald
6.4 枚举量可以被用于表达式,此时它会被强制转化为int类型,如:
int i=a+b;// i=0+0
a = b+c;// invalid, a=0+1
6.5 枚举的取值范围通过取2的幂来完成,如果枚举量最小值为不小于0则取下限为0,否则参照取上限并加上负号;
枚举量上限为最小的大于最大枚举量的2的幂;
7. 指针和自由存储空间
7.1 *运算符--解除引用运算符;
C风格指针声明: int *ptr;
C++风格指针声明: int* ptr;
声明时每个变量都要使用一个*运算符,所以C风格指针声明更不容易出错;
7.2 创建指针时,计算机只分配存储地址的内存;
7.3 指针与整数的区别在于:
指针描述的是地址,而整数是可以执行各种算数运算的数字;
所以不可以直接将一个整数(哪怕本质上是一个有效地址)赋值给指针;
7.4 指针和变量的区别在于:
指针是为可以通过名称直接访问的内存所提供的别名;
变量是在编译时分配的有名称的内存;
7.5 new是C++用来实现分配内存的运算符,malloc是C用来实现类似功能的库函数;--详见
《内存泄漏》
7.6 delete是C++用来实现释放内存运算符,必须与new配对使用,否则将造成内存泄露(memory leak);--详见
《内存泄漏》
另外,delete可以对空指针(NULL)使用;
7.7 如果使用new []为数组分配内存,则应该使用delete []对其释放;
[]指出应该释放整个数组,而不是指针指向的那一个元素(数组的首个元素);
new使得可以使用变量声明数组,这也体现了OOP的思想,即在运行时创建数组(动态编联),而不是在编译时已经固定了数组的内存大小(静态编联);
7.8 数组和指针基本是等价的,即可以使用数组指针像数组那样来访问元素;
它们的根本区别是,指针可以修改,对指针加一可以则将指向下一个元素的地址,所以这个步长根据指针类型会有很大的差别;
另外一个区别是,数组通过sizeof得到的是数组的长度,而指针得到的是指针长度;
7.9 char数组名,char指针和引号括起的字符串常量通常被解释为字符串的第一个字符的地址;
char指针指向字符串常量时通常要加前缀const,以此表明不可以对其进行修改,如:
const char* cp = "hello";
一般来说给cout提供一个指针,它将打印地址,但当指针类型为char *时,它将显示字符串;
8. vector和array
8.1 vector和array可以作为数组的替代品,它们都是模板类;
vector类似string,采用的是动态内存分配;
array和数组 一样也是静态分配,即需要在编译前指定数组长度;
8.2 array和数组的区别在于array可以像变量那样进行赋值,而数组的之间赋值则需要遍历整个数组;
相应地,array的效率略低于数组;