1. 什么是结构体?
结构体是一种自定义数据类型,它由不同数据类型的变量组成。我们可以将这些变量放到一个结构体中来描述一个实体,比如一个人、一辆车或者一支队伍等。在C语言中,结构体在定义时使用struct
关键字。
结构体的定义格式如下:
struct 结构体名
{
成员1;
成员2;
......
};
其中,结构体名表示要定义的结构体名称,成员表示结构体中包含的变量。
1.1 结构体示例:
下面是一个简单的结构体示例:定义一个人物信息的结构体:
struct person
{
char name[20]; // 姓名
int age; // 年龄
char gender; // 性别
float height; // 身高
};
上面定义了一个person
结构体,其中包含了4个成员变量:name
、age
、gender
、height
。其中,name
是字符型数组,用于保存姓名;age
是整型变量,用于保存年龄;gender
是字符型变量,用于保存性别;height
是浮点型变量,用于保存身高。
2. 结构体的使用
定义了一个结构体后,就可以创建该结构体的变量,并访问结构体中的成员变量。
2.1 创建结构体变量
创建结构体变量的格式如下:
struct 结构体名 变量名;
例如创建一个名为p1
的person
类型的变量:
struct person p1;
2.2 访问结构体成员
访问结构体成员的格式如下:
结构体变量名.成员名
例如访问p1
的name
成员:
p1.name
2.3 修改结构体成员的值
修改结构体成员的值也可以通过结构体变量名和成员名来完成,如下:
p1.age = 20;
以上代码将p1
的age
成员的值修改为20。
3. 结构体数组
结构体数组是指由结构体变量组成的数组,在C语言中,结构体数组也是一种数据类型。
3.1 创建结构体数组
创建结构体数组的格式如下:
struct 结构体名 变量名[元素个数];
例如创建一个包含3个person
类型变量的数组:
struct person p[3];
3.2 访问结构体数组成员
访问结构体数组成员的格式和访问普通数组成员相同,如下:
p[0].name /* 访问第一个元素的name成员 */
p[1].age /* 访问第二个元素的age成员 */
4. 结构体指针
结构体指针是指向结构体变量的指针,它指向的是结构体变量的内存地址。
4.1 创建结构体指针
结构体指针的创建格式如下:
struct 结构体名 *指针变量名;
例如创建一个指向person
类型变量的指针:
struct person *p;
4.2 给结构体指针赋值
给结构体指针赋值可以通过直接赋值或者取地址符来完成,如下:
struct person p1; /* 定义一个person类型的变量p1 */
p = &p1; /* 将p指向p1的地址,&用来取地址 */
4.3 访问结构体指针成员
访问结构体指针成员的格式和访问结构体变量成员的格式相同,如下:
(*p).name /* 访问p指向的变量的name成员,(*)用来解引用 */
p->age /* 访问p指向的变量的age成员,->是一种简写形式 */
5. 结构体嵌套
结构体嵌套是指一个结构体中包含另外一个或多个结构体,通过结构体嵌套可以更好地描述实体之间的关系。
5.1 结构体嵌套示例:
下面是一个示例,定义了一个worker
结构体和一个department
结构体,worker
结构体中包含department
结构体:
/* 定义一个表示部门的结构体 */
struct department
{
char name[20]; // 部门名
char manager[20]; // 部门经理
};
/* 定义一个表示员工的结构体 */
struct worker
{
char name[20]; // 员工名
int age; // 员工年龄
struct department dept; // 所在部门信息
};
在上面的示例中,department
结构体中包含了name
和manager
成员变量,worker
结构体中包含了name
、age
和dept
成员变量,其中dept
又是一个department
结构体。
5.2 访问结构体嵌套成员
访问结构体嵌套成员时,需要通过.
或->
来访问,如下:
worker w1 = {"Tom", 20, {"IT Dept.", "James"}};
printf("Worker name: %s\n", w1.name); /* 访问w1的name变量 */
printf("Worker age: %d\n", w1.age); /* 访问w1的age变量 */
printf("Worker department: %s\n", w1.dept.name); /* 访问w1的dept结构体的name变量 */
printf("Worker manager: %s\n", w1.dept.manager); /* 访问w1的dept结构体的manager变量 */
6. 结构体作为函数参数
结构体作为函数参数时,可以将结构体作为一个整体来传递,也可以将结构体指针作为参数传递。
6.1 将结构体作为函数参数
将结构体作为函数参数,可以直接传递结构体变量,也可以使用在定义函数时使用*struct
类型的参数来传递结构体:
/* 将struct作为整体传递给函数 */
void fun(struct person p)
{
......
}
/* 在定义函数时使用结构体指针作为参数 */
void fun(struct person *p)
{
......
}
6.2 结构体指针作为函数参数
当结构体的成员较多时,如果将整个结构体作为参数传递会浪费内存,这时我们可以使用结构体指针作为参数传递,从而提高程序的效率。
/* 定义函数请参考5.3小节的内容 */
/* 调用函数,传递的是结构体指针 */
fun(&p1);
7. 结构体的大小
在C语言中,结构体的大小是由它所有成员中最大的类型大小决定的。
下面是一个结构体大小的示例:
#include
struct test
{
int a;
char b;
short c;
};
int main()
{
printf("size of struct test is %d\n", sizeof(struct test));
}
上面的代码输出结果为:size of struct test is 8
,因为该结构体的两个成员变量都是占用4个字节的,而char
类型是占用1个字节的,而short
类型又是占用2个字节的,所以这个结构体的大小是8个字节。
8. 小结
结构体是一种自定义数据类型,在C语言中使用struct
关键字来定义,它可以由不同的数据类型的变量组成。我们可以将这些变量放到一个结构体中来描述一个实体。结构体的成员可以是标量、数组或结构体,也可以嵌套其他结构体。结构体的大小是由它所有成员中最大的类型大小决定的。我们可以使用结构体变量、结构体数组、结构体指针来访问和操作结构体中的成员变量,它们的使用方式和普通变量类似,只需要遵循一定的语法规则即可。