C语言学习之复合数据类型
一、结构体
前面的数组它是同种类型数据的集合,那要是不同种类型的数据怎么办,就需要用到这里的结构体。结构体它的成员可以是基本数据类型,也可以是复合数据类型。
1. 结构体类型的定义
struct point {
int x;
int y;
};
注意结构体类型的定义要以';'结尾。定义了一个结构体类型就相当于新定义了一个数据类型,我们可以使用这个数据类型来定义变量,和基本数据类型一样没有什么区别,例如:
struct point a, b, c;
结构体类型要包括struct关键字和结构体的名字。
我们也可以在定义结构体的时候就定义变量,例如:
struct point {
int x;
int y;
} a, b, c;
我们甚至可以将这个结构体的名字给省略掉,例如:struct {
int x;
int y;
} a, b, c;
但是这样就不能使用这个结构体类型去定义新的变量,除非你明确了我不需要这个结构体类型了,但是写上名字总是好的。
2. 结构体变量的初始化
同其它数据类型定义的变量一样,我们也可以在定义结构体变量的时候对它进行初始化,例如:
struct point a = {3, 4};
我们要操作结构体中某个成员时,使用'.'操作符,例如:
a.x = 3;
3. 结构体数组定义
我们可以定义结构体数组,只是数组成员的类型它是结构体类型罢了。
struct point p[10];
4. 结构体指针
我们也可以定义结构体变量的指针,例如:
struct point* pp;
我们可以将pp指向某个结构体变量,要访问那个结构体变量的某个成员可以这样:
(*pp).x = 3;
(*pp).y = 4;
这个括号不能省略,因为'.'操作符比'*'的优先级高,除了使用这种方式外,还可以使用结构体指针独有的方式,就是'->'操作符。
pp->x = 3;
pp->y = 4;
5. 结构体类型作为函数返回值
struct point makepoint(int x, int y)
{
struct point temp;
temp.x = x;
temp.y = y;
return temp;
}
6. 结构体类型作为函数参数
struct point addpoint(struct point p1, struct point p2)
{
p1.x += p2.x;
p1.y += p2.y;
return p1;
}
二、位段
位段定义同结构体类似,但它的成员是一个或多个位的字段,成员的类型必须是int、signed int或unsinged int类型。
struct CHAR {
unsigned ch :7;
unsigned font:6;
unsigned size:19;
};
冒号后面跟的数字表示该位段所占用的位的数目。
使用位段能节省存储空间。
三、联合体
联合体中的所有成员都引用相同的内存位置。
union {
float f;
int i;
} fi;
联合体类型大小为它所有成员最大数据类型的大小。
这里我们就定义了一个联合体,因为它的所有成员都引用相同的内存位置,在32位机器中,float和int类型都是4字节大小,如果联合体fi的f成员被使用,那么这4字节空间就被当作浮点值使用,如果成员i被使用,那么这4字节空间就被当作整型数据来使用,所以关键就是我们怎么看待这段内存空间。联合体类型主要用于数据类型不明确或者不确定的变量。
四、枚举
enum week {
SUNDAY,
MONDAY,
TUESDAY,
THURSDAY,
FRIDAY,
STURDAY,
};
我们定义了一个枚举类型week,我们可以使用这个枚举类型去定义一个变量:
enum week today = MONDAY;
其实枚举类型本质上是int类型,花括号里面列举出了它可能取值,里面的枚举值它是一个符号常量,这个符号常量从0开始依次增1。也可以给某个符号常量显示指定一个值,如果没有显示指定一个值,那么这个符号常量的值默认就是前面一个符号常量值加1。