结构体大小
我们可以用sizeof测结构体的大小,这里牵扯到了对齐的特性,编译器会按照结构体成员数据类型最大者来分配空间,这样牺牲了空间但是节省了时间
比如一个结构体中有int char float类型的成员,那么编译器会用4个字节来分配空间
#include<stdio.h>
#include<string.h>
typedef struct stu
{
int id;
char name[20];
char name1[15];
float score;
}STU;
int main()
{
printf("%d\n", sizeof(struct stu));//所有成员的大小
return 0;
}
这里按照4个来分配内存,给int 分配4个然后给长度为20的字符数组分配24个,给长度为15的分配20个,他还能余下5个大小,刚好可以分配给后面的float型,所以最后分配了44个字节
我们也可以用#pragma pack(n),这个n代表用几个字节为单位来分配空间,这个n的取值为(1,2,4,8,16),在预处理的时候,编译器就会知道用你想用多少字节来分配内存
比如我给上面的程序加一个
#pragma pack(1)
那么程序就按1个字节来分配内存
最后结果是按照1个字节分配内存,4 + 20 + 15 +4 = 43
联合体
联合是一种数据类型,它能在同一个内存空间中存储不同的数据类型,他的典型用法是,设计一种表以储存既无规律、事先也不知道顺序的混合类型。
他们公用一个内存空间,这个空间是最大的数据类型的空间,例如联合体内有char int double 那么内存空间分配的就是8个字节
我们可以用联合体来求大小端序
#include<stdio.h>
typedef union data
{
int i;
char ch;
}DATA;
int main()
{
DATA temp;
temp.i = 0x12345678;
if(temp.ch == 0x12)
{
printf("大端序\n");
}
else
{
printf("小端序\n");
}
return 0;
}
联合体分配了以4个字节的大小为单位分配空间,给int的i一个0x12345678就分配了12个字节的空间,但是当要调用char ch的时候,它只有4个字节,所以它只有前4个数据,0x12,这样就可以判断是什么端序,最后测出我的电脑是小端序
联合体还有一个用法是,在结构体中存储与其他成员有从属关系的信息,例如,假设用以一个结构表示一辆汽车,如果汽车属于驾驶者,就要用一个结构成员来描述这个所有者,如果汽车被租赁,那么需要一个成员来描述其租赁公司
这个关系可以用下面的代码来完成
struct owner
{
char socsecurity[12];
...
};
struct leasecompany
{
char name[40];
char headquarters[40];
...
};
union data
{
struct owner owncar;
struct leasecompany leasecar;
};
struct car_data
{
char make[12];
int status;
union data owner;
...
};
枚举
枚举就是将一堆有意义的单词赋值,这样可以增加代码的可阅读性,和#define用法类似,如果需要改变的单词多了,就可以使用枚举
#include<stdio.h>
#include<string.h>
enum EDG
{
flandr, jiejie, scout, viper, meiko
};
int main()
{
enum EDG person;
// person = UZI;
// printf("%d\n", person);
// person = clearlove;
// printf("%d\n", person);
person = jiejie;
printf("%d\n", person);
person = scout;
printf("%d\n", person);
}
当我们定义了5个枚举类型的成员时,给第一个赋初值且只能在定义的时候赋初值,后面的成员依次加1
位段
我们把位段作为一种更紧凑存储数据的方式,例如,假设在屏幕上表示一个方框的属性,为简化问题,我们假设方框具有以下属性
- 方框是透明的还是不透明的
- 方框的颜色选自以下调色板:黑色、红色、绿色、黄色、蓝色、紫色、青色、白色
- 边框可见或隐藏
- 边框的颜色与填充色使用相同的调色板
- 边框可以使用实现、点线、或虚线样式
可以使用单独的变量或全长的结构成员来表示每个属性,但是这样做有些浪费位,例如只需要1位即可代表方框是透明的还是不透明的;只需要一位就可以表示边框时显示还是隐藏。8种颜色可以用3位单元的8个可能的值来表示,而3种边框样式也只需要2位单元即可表示,总共10位就足够表示方框的5个属性设置
这就要用到位段来节省资源
#include<stdio.h>
#include<string.h>
typedef struct reg
{
int a:2;
int b:4;
int c:6;
int d:4;
}REG;
int main()
{
REG registe;
registe.a = 3;
registe.b = 10;
registe.c = 20;
registe.d = 9;
printf("%d, %d, %d, %d\n",registe.a, registe.b, registe.c, registe.d);
printf("%d", sizeof(registe));
return 0;
}
我们定义一个2位的a,4位的b,6位的c,4位的d,因为这些都是有符号的,这个a赋3换算二进制就是011取反加一位101,就是-1后面的以此类推会出现 -6, 20, 7,当然如果位数够就会输出本来的值