结构体的概括
C语言提供给用户自定义的数据类型,用户可以根据需求自己构建存储数据的方式。结构体的作用就是整合类型不同,但是互相关联的数据。
比如:可以在里面同时定义int,float,char或者数组。
结构体的定义
struct 结构体名
{
数据类型1 成员名1;
数据类型2 成员名2;
……
数据类型n 成员名n;
}; //注意不要漏掉这里的;
比如:
struct RESULTS
{
char a;
int b;
float c;
int d[10];
};
小提示:
- struct是C语言声明结构体类型时所必须使用的关键字,不能省略。
- 大括弧内的每一个类型声明语句右面都要用分号“;”作为语句结束标记,大括弧外也必须有一个分号“;”作为结构体类型声明语句的结束标志。
- 结构体名通常用大写。
结构体变量
由于结构体定义好后,没有变量的名称,所以需要先定义一个变量名。有三种办法:
1)用结构体名去定义变量
struct RESULTS
{
char a;
int b;
float c;
int d[10];
};
struct RESULTS str; //定义结构体变量str
2)定义结构体的同时定义变量
struct RESULTS
{
char a;
int b;
float c;
int d[10];
}str; //定义结构体的同时定义结构体变量str
3)直接定义结构体的变量(这种方法将类型定义和变量的定义合二为一,没有结构体名,以后无法再使用这种结构体定义其他的变量)。也就是说,之后的操作只能使用这个变量名,无法在使用这个结构体定义其他的变量名称(不建议使用)。
struct
{
char a;
int b;
float c;
int d[10];
}str;
结构体数据写入
使用结构体变量依次输入数据,但某些地方比较麻烦;直接在定义的同时赋予初始值,会根据结构体中成员的位置依次赋值,但是赋值的时候要注意成员的数据类型。
struct RESULTS
{
char a[10]; //定义一个字符串数组
int b;
float c;
}str; //定义结构体的同时定义结构体变量str
int main()
{
strcpy(str.a,"wind"); //字符串赋值只能采用这个方式
str.b = 100; //使用变量str引用结构体的成员b,并赋值给他
str.c = 235;
//定义的同时赋予初始值,会根据结构体中成员的位置依次赋值
//赋值的时候要注意成员的类型
struct RESULTS str1 = {"wifi",2,8};
return 0;
}
结构体数据输出
printf("%s\n",str.a);
printf("%d\n",str.b);
printf("%s\n",str1.a);
printf("%.f\n",str1.c);
上述的结果:
结构体与数组
结构体与数组的区别:
1.数组只能存储同一种数据类型的数据,结构体可以存在多种数据类型。
2.结构体定义的是变量,变量可以相互赋值,数组不能相互赋值。
结构体数组
//定义结构体数组,并赋予初值
struct RESULTS th[3] = {{"qiu",7,12},
{"cai",8,75},
{"shui",1,24}};
printf("%s\n",th[0].a);
printf("%d\n",th[2].b);
结构体数组的结果:
结构体与指针
之前学习指针与数组的结合,不过加了一点小细节。
//定义结构体数组
struct RESULTS th[3] = {{"qiu",7,12},
{"cai",8,75},
{"shui",1,24}};
//定义结构体指针,并让指针指向数组首地址
struct RESULTS *pa = th;
//结构体指针访问成员
printf("%s\n",(*pa).a);
//如果是地址访问,可使用指向符
printf("%s\n",pa->a);
结构体的内存大小
参见《sizeof(结构体)和内存对齐.doc》和《pragma预编译指令》,求结构体sizeof的三个原则:
1. 结构体变量的首地址是其最宽基本类型成员的整数倍
2. 结构体每个成员相对于结构体首地址的偏移量, 都是该成员大小的整数倍
3. 结构体的总大小是其最宽基本类型成员的整数倍
例如:
三个数据类型中,最大基本数据类型是4个字节,b+c就有了8个字节的内存,char a[10]按理来说应该占10个字节,但是10不是4的整数倍,所以它应该占12个字节。最后结果就为12+8=20个字节,输出结果就是20。