复合类型
C++的基本类型可以进行组合,组合成为更加复杂的类型,这就是复合类型。C++中的常用复合类型有数组、枚举、结构体和共用体。复合数据类型的每个变量均可以存储多项信息
数组
数组的优点在于,一个数组可以把许多个值存储在同一个变量名下,但不能把不同类型的数据混杂保存在同一个数组里
type name[n];
其中type代表变量的类型,name是数组变量的名字(仍需遵守与其他变量相同的命名规则),n是该数组所能容纳的数据项的个数(数组中的每一项数据称为一个元素)。
一般通过数组的下标来访问某给定数组里的各个元素。数组的下标是一组从0开始编号的整数,最大编号为数组元素的总个数减去1。
可以用以下语法在创建数组时对它的元素进行赋值。
int numbers[3] = {0, 1, 2}; //只能在声明变量时进行
int numbers[] = {0, 1, 2}; //编译器将根据大括号里的值的个数自动地创建出一个长度与之相匹配的数组。
多维数组
多维数组类似多级间指,可以理解为保存数组的数组
type name[r][j];
根据具体的编程需要,多维数组的维数可以无限扩大,但保存在多维数组里的每一个值必须是同样的类型.
动态数组
动态数组是指在编译时不能确定数组长度,程序在运行时根据具体情况或条件,需要动态分配内存空间的数组。有两种情况,一种是根据具体需要存储的数据长度来申请固定长度的数组空间,另一种是在需要往数组内添加或删除数据时修改数组的长度,常通过链式结构实现。
动态定义数组时,一般利用指针或关键字new来实现。
[]内的数必须是常量或常量表达式,或者用宏定义define来定义维数,define的维数在编译时更方便修改
数组存储
列存储是指将数组元素按照列向量排列,第n+1个列向量紧接在第n个列向量的后面。
行存储是指将数组元素按照行向量排列,第n+1个行向量紧接在第n个行向量的后面。
二者主要还是行列顺序的区别。
可以参考数组按行按列存储
数组初始化
C++的数组初始化处理既可以在定义时,也可以在定义后。
- 在定义时用以逗号分隔,放在大括号中的数据表示初始化数组中的元素。
int array_1[3] = {1, 2, 3}
int array_2[2][3] = {{1, 2, 3}, {4, 5, 6}}
- 在程序执行时用赋值语句对其进行初始化。
int array[12][12];
for(int i = 0; i < 12; i ++){
for(int j = 0; j < 12; j ++){
array[i][j] = i * j;
}
}
指针和数组
指针是一个保存地址的变量,C++中的数组表示的是一个首地址,所以数组名就是指向该数组第1个元素的指针。要访问数组中的某个元素,只需要指导其在数组中的位置,然后从第一个元素的指针开始按位置在连续的一块内存空间里查找即可。
二维数组就是保存了指向数组的指针的数组,看起来很绕,但仔细体会还是很容易懂的。
由此也就有了两种访问数组元素的方法
一种是通过下标访问,另一种是通过指针和指针运算访问,原理上其实是相同的。
枚举
枚举类型也是一种用户自定义类型,是由若干个有名字常量组成的有限集合。
enum<枚举类型名>{
<枚举元素1>[=<整型常量1>];
...
<枚举元素2>[=<整型常量2>];
}
enum是定义枚举类型的关键字。<枚举类型名>是用户定义的标识符。<枚举元素>也称枚举常量,也是用户定义的标识符。C++语言允许用<整型常量>为枚举元素指定一个值。如果省略<整型常量>,默认<枚举元素n>的值为n-1。
枚举变量可以在定义枚举类型的同时声明,也可以用枚举类型声明。
在程序中可以将枚举元素视为一个整型常量,枚举变量的值为该枚举类型定义中的某个元素的值。枚举变量可以进行算术运算、赋值运算、关系运算或逻辑运算等。
如果某个枚举中所有枚举子的值均非负,该枚举的表示范围就是[0:2k-1];如果存在负的枚举值,该枚举的取值范围就是[-2k,2^k-1]。
一个存在枚举取值范围之内的整型值可以显示地转换成一个枚举值
-
枚举类型可以用于switch。。。case语句
-
枚举类型不支持直接的cin>>和 cout<<
-
枚举元素之间比较可以用<,>,<=,>=,==,!=
-
枚举类型可作为函数的返回类型
-
枚举是用户自定义类型,可以为它定义自身的操作,如++,–,但在未作定义前,不能因为枚举像整型就默认使用
结构体
结构(structure)是一种由程序员定义的、由其他变量类型组合而成的数据类型。
struct structurename{
type varName;
type varName;
...
};
结构的定义必须以一个右大括号和一个分号结束。
当需要处理一些具有多种属性的数据时,结构往往时很好的选择。C++对一个结构所能包含的变量的个数没有限制,那些变量通常称为该结构的成员,它们可 以是任何一种合法的数据类型。
定义后的使用:
structureName myVar;
myVar.memberName = Value; //成员赋值
employee el = {40, "Charles", 12.34}; //声明时赋值
可以通过指向结构的指针结合“->”来访问结构内的成员,或者对指针使用解引用操作符‘*’。
联合
即共用体。联合也可以容纳多种不同类型的值,但它每次只能存储这些值中的某一个。
union unionName{
type member_1;
type member_2;
type member_3;
...
};
之后的使用:
unionName var;
var.member_1 = (type)tem1;
var.member_2 = (type)tem2;
以上语句的第二条把tem1赋给member_1。第三条语句执行时,把tem2赋给membe_2,并且丢弃成员member_1里的值。
typedef
typedef 原类型名称 新类型名称;
typedef的主要应用有如下几种形式。
- 为基本数据类型定义新的类型名。
typedef int COUNT;
typedef double AREA;
可以丰富数据类型中包含的属性信息,同时也是为了满足系统移植的需要。
2. 为自定义数据类型定义简洁的类型名称
struct Point{
double x;
double y;
double z;
};
struct Point oPoint1 = {100, 100, 0};
struct Point oPoint2;
结构体structPoint为新的数据类型,在定义变量的时候要有保留字struct,而不能像int和double那样直接使用Point来定义变量。
typedef struct tagPoint{
double x;
double y;
double z;
} Point;
此时定义变量可以
Point oPoint;
- 为数组定义简洁的类型名称
int a[10], b[10], c[10], d[10];
可以将长度为10的整型数组看作一个新的数据类型,再利用typedef为其重定义一个新的名称
typedef int INT_ ARRAY_ 10[ 10];
typedef int INT_ ARRAY_ 20[ 20];
INT_ ARRAY_ 10 a, b, c, d;
INT_ ARRAY_ 20 e;
- 为指针定义简洁的名称
typedef char * STRING;
STRING csName={“ Jhon”};
typedef int (*MyFUN)( int a, int b);
"MyFUN"代表"int*XFunction(inta,intb)"类型指针的新名称.
- typedef的目的是为已知数据类型增加一个新的名称,因此并没有引入新的数据类型。
- typedef只适于类型名称定义,不适合变量的定义。
- typedef与#define具有相似的之处,但实质不同。