积土成山
结构体
1.结构体的声明
1)普通声明
声明一个学生类型,结构体是不同类型变量的集合。
struct student
{
char name[20];
int age;
};//分号不能丢
结构体变量的创建
2)特殊声明
去掉student这样的标识
struct
{
char name[20];
int age;
};
1.结构体变量的创建
struct
{
int a;
char b;
float c;
}x;
int main()
{
struct m;
x.a=5;
m.a = 5;//这里会报错(m无法未定义的标识符)
printf("%d", m.a);
printf("%d", x.a);
return 0;
}
我们发现在这种情况下不能创建局部变量,只可以创建全局变量。
2. 多个特殊声明时
我们尝试把两个struct下的一个变量x的地址赋给,另一个struct下的p。
struct
{
int a;
char b;
int c;
}a[20], * p;
struct
{
int a;
char b;
float c;
}x;
int main()
{
p = &x;//这里会报错“从“*”到“*”的类型不兼容。”
return 0;
}
这样表示编译器会把他们当成是两个不同的结构体;
2.结构体的自引用
1. 错误的形式
我们尝试在结构体中创建结构体,下面这样可行吗?
struct Node
{
int data;
struct Node next;//这里会报错(未定义的struct “Node”)
};
int main()
{
int sum = sizeof(struct Node);
printf("%d", sum);
return 0;
}
无法打印sum,那我们自己思考一下结构体的内存大小是多少。
假设struct Node的大小为x
2.正确的形式
struct Node
{
int data;
struct Node *next;//通过指针的形式找到下一个结构体
};
int main()
{
struct Node p;
struct Node m;
p.next = &m;
p.next->data = 10;
printf("%d", m.data);
int sum = sizeof(struct Node);
printf("%d", sum);
return 0;
}
这里的结构体大小sum明显是个定值,一个int类型加上一个指针变量。
3.结构体的内存大小
1.结构体内存大小的计算
struct s1
{
char c1;
int i;
char c2;
};
struct s2
{
char c1;
char c2;
int i;
};
int main()
{
printf("%d\n", sizeof(struct s1));
printf("%d\n", sizeof(struct s2));
return 0;
}
结构体储存的变量相同,但是内存大小却不一样,这是为什么呢?
结构体的内存对齐规则 |
-
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8 -
结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
-
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
画图演示一下
这里我们再讲一个特例:一个结构体内储存结构体变量的情况 |
struct S3
{
double d;
char c;
int i;
};
struct S4
{
char c1;
struct S3 s3;
double d;
};
int main()
{
printf("%d", sizeof(struct S4));
return 0;
}
那么我们来思考一下s4的内存大小是多少?
打印的结果是32。这是怎么计算的?
2. 设置默认对齐数
在c语言中我们是可以自己设置默认对齐数的
#pragma pack(8)//设置默认对齐数为8
struct S1
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
修改默认对齐数后计算结构体的内存大小的规则不变。
谢谢大家的阅读与支持!