1.结构体
2.枚举
3.联合
结构体
结构体是由不同类型或相同类型的成员组成的结合,定义形式为:
struct Name
{
成员;
}
例:
struct Stu
{
char name[20];
int age;
float score;
char other[20];
}
struct stu为自定义结构体类型,s1为结构体变量,初始化与其他类型的变量相同,访问结构体成员使用.(成员访问运算符),方式为结构体变量.结构体成员。
#include<stdio.h>
struct stu
{
char name[20];
int age;
float score;
char other[20];
};
int main()
{
struct stu s1 = { "张三",22,95.5f,"无" };
printf("%s %d %f %s", s1.name, s1.age, s1.score, s1.other);
return 0;
}
运算结果如下:
结构体大小的计算:
如要计算结构体的大小,就先要了解结构体对齐。1.首先结构体的第一个成员永远都位于0偏移处;2.其次从第二个成员开始,以后的每个成员都要对齐到对齐数的整数倍(对齐数:成员自身大小和默认对齐数的极小值。如:vs环境下默认对齐数是8,gcc环境无默认对齐数,则为成员自身大小);3.当成员全部存放进去后,结构体的总大小必须是所有成员的对齐数中最大对齐数的整数倍,如果不够,则浪费空间对齐;4.如果结构体里嵌套了结构体,嵌套的结构体对齐到自己成员最大对齐数的整数倍,结构体整体大小就是所有最大对齐数(包括嵌套结构体的对齐数)的整数倍。
这里介绍一个函数offsetof(结构体类型,成员名),计算偏移量。#pragma pack(数字) 修改默认对齐数,还原可令数字为空。
struct S1
{
int a;
char c;
}s1;
struct S2
{
double d;
char c;
int i;
}s2;
struct S3
{
char c;
struct S2 s2;
double d;
}s3;
int main()
{
printf("%d\n%d\n", sizeof(s1), sizeof(s3));
return 0;
}
s1变量在内存中的存放如图解析:
s3变量在内存中的存放如图解析:
c 0 | 空 4 | s2 8 | s2 12 | s2 16 | s2 20 | d 24 | d 28 |
空 1 | 空 5 | s2 9 | s2 13 | s2 17 | s2 21 | d 25 | d 29 |
空 2 | 空 6 | s2 10 | s2 14 | s2 18 | s2 22 | d 26 | d 30 |
空 3 | 空 7 | s2 11 | s2 15 | s2 19 | s1 23 | d 27 | d 31 |
枚举
定义格式为:enum Name {枚举的可能取值},第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。
enum Sex
{
MALE,
FEMALE,
SECRET
}
enum Sex zhangsan=MALE;
联合
联合与结构体定义方式相同,但是其的每一个成员都共用一块空间,所以一旦修改任意一个成员就会改变其他成员。