1 结构体
描述一个复杂的数据类型,该类型需要若干个不同的数据类型的变量组成。
例如:学生
姓名,学号,年龄,性别这些内容都是不同数据类型的。我们无法使用数组或其他基本数据类型来描述,因此我们需要一个复合如下要求的变量
①变量能够存储多个数值
②数值的数据类型不同
③这些数值共同组成了一个整体用于描述同一种事物
C语言提供了一种复合数据类型来保存这种数据—结构体类型,用户可以自行定义其中的内容用来描述一个全新的类型
1.1 语法格式
①声明:
struct 结构体类型名
{
数据类型 变量名;(结构体成员)
……
};
② 声明结构体变量//不占内存
struct 结构体类型名 结构体变量名;
③ 初始化结构体变量
struct 结构体类型名 结构体变量名={值1,值2,。。。值n};
④ 结构体变量成员的使用
结构体变量名.成员名
1.2 结构体的嵌套
结构体变量可以嵌套定义
struct A
{
成员;
};
struct B
{
struct A 变量;
};
2 结构体变量的大小
概念:一个结构体变量的大小是由以下两个条件共同决定的
①结构体内部的成员变量的大小
②字节对齐规则
计算:以结构体内部最大元素的所占内存的大小作为内存的基本分配单元,一个结构体的大小是这个结构体中最大元素的内存单元的整数倍;结构体变量的存储是有条件的“连续存储”。因为每次分配的内存大小都是最大成员变量内存大小的整数倍所以在其中是有“空洞”空间的。
3 指针和结构体
3.1 指针变量指向结构体
需要创建一个基类型是结构体类型的指针变量。
结构体的地址就是结构体中第一个成员的首字节地址
利用指针变量访问结构体变量中的成员
语法:指针变量名->结构体成员名
利用指针变量加*来当做变量本身,需要将*和指针变量利用括号括起来,否则,指针变量首先会和.运算先结合。
(*指针变量名).成员
取结构体变量中的成员的地址
&结构体变量名.成员
&结构体指针变量->成员
3.2 结构体内有指针变量作为成员
struct Num
{
int x;
int* p;
};
int main()
{
/*
int m = 999;
struct Num obj = { 0, &m };
printf("%d %p\n", obj.x,obj.p);
printf("%d\n", *(obj.p));
*/
int arr[] = { 5, 10, 15, 20 };
struct Num obj = { 4, arr };
/*
int i;
for (i = 0; i < obj.x; i++)
{
//printf("%d\t", *(obj.p + i));
printf("%d\t", obj.p[i]);
}
putchar('\n');
*/
struct Num* pObj = &obj;
int i;
for (i = 0; i < pObj->x;i++)
{
printf("%d\t", *(pObj->p + i));
}
putchar('\n');
return 0;
}
3.3 结构体变量充当函数参数
概念:形式参数是结构体变量名,意味着参数在传递时,由实际参数(结构体变量)传递给形式参数(结构体变量)。实际上适合普通变量的参数传递一样的
返回值类型 函数名(struct 结构体类型名 变量名)
{
}
3.4 结构体指针充当函数参数
概念:形式参数是指向结构体变量的指针,意味着在参数传递时,由实际参数(结构体变量地址)传递给形式参数(结构体指针变量)。本质上就是地址传递过程
4 结构体数组
概念:数组的每一个元素都是结构体变量
语法:
①声明
struct 结构体类型名 数组名[长度];
②初始化