1,结构体
#include<stdio.h>
#include<windows.h>
struct S //类型声明
{
char name[20]; //名字
int age; //年龄
};
struct S1
{
char name[20];
int age;
}s1 = { "李四", 25 }; //声明类型的同事定义变量s1
struct S2
{
char name[20];
int age;
struct S *node;
}s2 = {"王五",30,NULL}; //结构体嵌套的初始化
int main()
{
struct S s = { "张三", 18 }; //初始化
struct S2 s3 = { "周六", 40 };
printf("%s %d\n", s.name, s.age);
printf("%s %d\n", s1.name, s1.age);
printf("%s %d\n", s2.name, s2.age);
printf("%s %d\n", s3.name, s3.age);
system("pause");
return 0;
}
结果:
结构体内存对齐
结构体内存对齐是非常热门的考点。
那么为什么存在内存对齐?
1.平台原因
不是所有的硬件平台都能访问任意地址上的任意数据的。
2.性能原因
数据结构应该尽可能地在地在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要进行两次内存访问;而对其的内存访问仅需要一次访问。
内存对齐如何计算?
我们必须掌握结构体的对齐规则:
1.第一个成员在与结构体变量偏移量为0的地址处。
2.其他成员变量要对其到对齐数的整数倍的地址处。(对齐数=编译器默认的一个对齐数与该成员大小的较小值。vs中默认的值为8 Linux中的默认值为4)
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
举例子:
看代码:
#include<stdio.h>
#include<windows.h>
struct s1
{
char a;
int b;
char c;
};
struct s2
{
char a;
char b;
int c;
};
struct s3
{
double a;
char c;
int i;
};
struct s4
{
char a;
struct s3 b;
double c;
};
int main()
{
printf("%d\n", sizeof(struct s1));
printf("%d\n", sizeof(struct s2));
printf("%d\n", sizeof(struct s3));
printf("%d\n", sizeof(struct s4));
system("pause");
return 0;
}
结果:
解释:
2.位段
先来看一个位段类型代码:
#include<stdio.h>
#include<windows.h>
struct A
{
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
};
int main()
{
printf("%d\n", sizeof(struct A));
system("pause");
return 0;
}
输出的结果为8;
位段有属于自己的特点:
(1)位段的成员必须是int ,unsigned int,signed int。
(2)位段的成员名后边有一个冒号和一个数字。
那么位段的大小是如何计算的?
由于是int类型,所以给位段的内存分配时,先分配四个字节的大小,如果够用,就不会继续分配;如果不够用,比如struct A ,先分配的四个字节不够用,然后在分配四个字节,总共就8个字节的大小。
3.联合
联合也是一种特殊的自定义类型,这中类型定义的变量也包含一系列的成员,但是这些成员公用一块空间(联合体也叫共用体)。
看代码:
#include<stdio.h>
#include<windows.h>
union Un
{
char b;
int c;
};
int main()
{
union Un a;
printf("%d\n", sizeof(a));
system("pause");
return 0;
}
输出的结果为4;
联合的成员是公用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小。
联合可用于求此计算机的大小端存储。
看代码:
#include<stdio.h>
#include<windows.h>
int daxiaoduan()
{
union
{
int b;
int c;
}un;
un.b = 1;
return un.c;
}
int main()
{
int ret = daxiaoduan();;
if (ret = 1)
printf("大端\n");
if (ret = 0)
printf("小端\n");
system("pause");
return 0;
}
联合大小的计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
比如:
#include<stdio.h>
#include<windows.h>
union un1
{
char a[5];
int b;
};
union un2
{
short c[7];
int b;
};
int main()
{
printf("%d\n", sizeof(union un1));
printf("%d\n", sizeof(union un2));
system("pause");
return 0;
}
结果:
在un1中,最大成员大小(5)不是最大对齐数(4)的整数倍,所以对齐到第八个字节处。
在un2中,最大成员大小(14)不是最大对齐数(4)的整数倍,所以对齐到第十六字节处。