1.简介
本篇原文为:C语言中的struct详解:定义、赋值、指针、嵌套与位字段。
更多C++进阶、rust、python、逆向等等教程,可点击此链接查看:酷程网
C 语言内置的数据类型,除了最基本的几种原始类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用中并不够用。
实际使用中,主要有下面两种情况,需要更灵活强大的复合类型。
- 复杂的物体需要使用多个变量描述,这些变量都是相关的,最好有某种机制将它们联系起来。
- 某些函数需要传入多个参数,如果一个个按照顺序传入,非常麻烦,最好能组合成一个复合结构传入。
为了解决这些问题,C 语言提供了struct
关键字,允许自定义复合数据类型,将不同类型的值组合在一起,这样不仅为编程提供方便,也有利于增强代码的可读性。
C 语言没有其他语言的对象(object)和类(class)的概念,struct 结构很大程度上提供了对象和类的功能。
下面是struct
自定义数据类型的一个例子:
struct fraction {
int numerator;
int denominator;
};
上面示例定义了一个分数的数据类型struct fraction
,包含两个属性numerator
和denominator
。
注意,作为一个自定义的数据类型,它的类型名要包括struct
关键字,比如上例是struct fraction
,单独的fraction
没有任何意义,甚至脚本还可以另外定义名为fraction
的变量,虽然这样很容易造成混淆。
另外,struct
语句结尾的分号不能省略,否则很容易产生错误。
定义了新的数据类型以后,就可以声明该类型的变量,这与声明其他类型变量的写法是一样的:
struct fraction f1;
f1.numerator = 22;
f1.denominator = 7;
上面示例中,先声明了一个struct fraction
类型的变量f1
,这时编译器就会为f1
分配内存,接着就可以为f1
的不同属性赋值。
可以看到,struct 结构的属性通过点(.
)来表示,比如numerator
属性要写成f1.numerator
。
再提醒一下,声明自定义类型的变量时,类型名前面,不要忘记加上struct
关键字。也就是说,必须使用struct fraction f1
声明变量,不能写成fraction f1
。
除了逐一对属性赋值,也可以使用大括号,一次性对 struct 结构的所有属性赋值:
struct car {
char* name;
float price;
int speed;
};
struct car saturn = {
"Saturn SL/2", 16000.99, 175};
上面示例中,变量saturn
是struct car
类型,大括号里面同时对它的三个属性赋值,如果大括号里面的值的数量,少于属性的数量,那么缺失的属性自动初始化为0
。
注意,大括号里面的值的顺序,必须与 struct 类型声明时属性的顺序一致,否则,必须为每个值指定属性名:
struct car saturn = {
.speed=172, .name="Saturn SL/2"};
上面示例中,初始化的属性少于声明时的属性,这时剩下的那些属性都会初始化为0
。
注意{}中字段名前面有一个点.
,不要写会报错。
声明变量以后,可以修改某个属性的值:
struct car saturn = {
.speed=172, .name="Saturn SL/2"};
saturn.speed = 168;
上面示例将speed
属性的值改成168
。
struct 的数据类型声明语句与变量的声明语句,可以合并为一个语句。
struct book {
char title[500];
char author[100];
float value;
} b1;
上面的语句同时声明了数据类型book
和该类型的变量b1
。如果类型标识符book
只用在这一个地方,后面不再用到,这里可以将类型名省略。
struct {
char title[500];
char author[100];
float value;
} b1;
上面示例中,struct
声明了一个匿名数据类型,然后又声明了这个类型的变量b1
。
与其他变量声明语句一样,可以在声明变量的同时,对变量赋值:
struct {
char title[500];
char author[100];
float value;
} b1 = {
"Harry Potter", "J. K. Rowling", 10.0},
b2 = {
"Cancer Ward", "Aleksandr Solzhenitsyn", 7.85};
上面示例中,在声明变量b1
和b2
的同时,为它们赋值。
下一章介绍的typedef
命令可以为 struct 结构指定一个别名,这样使用起来更简洁:
typedef struct cell_phone {
int cell_no;
float minu