位段

1什么是位段

位段的声明和结构是类似的,有两个不同

1位段的成员必须是int、unsigned int 或signed int 。

2位段的成员名后边有一个冒号和一个数字。

1
2
3
4
5
6
7
8
9
10
11
比如
struct A
{
int_a:2;
int_b:5;
int_c:10;
int_d:30;
};
A就是一个位段类型
那位段A的大小是多少?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
//位段 位是二进制位
struct S
{
//后面的:是所对应变零需要的比特位
int a:2;
int b:5;
int c:10;
int d:30;
//一共47个比特位——6个字节就够了*8=48bit
};
int main(void)
{
struct S s
printf("%d\n",sizeof(s));//占8个字节
}

2位段的内存分配

1位段成员可以是int unsigned int signed int 或者是char(属于整型家族)类型。

2位段的空间上是按照需要以4个字节或者1个字节(char)的方式开辟的。

3位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

在定义位段的变量中,最后一个不能大于32

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
struct S
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main(void)
{
struct S s = {0};
s.a = 10;
s.b = 20;
s.c = 3;
s.d = 4;
return 0;
}

3位段的跨平台问题

1int位段被当成有符号数还是无符号数是不确定的。

2位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题)

3位段中的成员在内存中从左向右 分配,还是从右向左分配标准尚未定义。

4当一个结构包含两个位段,第二个成员比较大,无法容纳第一个剩余的位段时,是舍弃剩余的位还是利用,这是不确定的。

总结:

​ 和结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

枚举

枚举故名思义就是一一列举

把可能的取值一一列举

1定义

1
2
3
4
5
6
7
enum Day//星期
{
//枚举的可能取值
Mon,
Tus,
...
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum Sex//星期
{
//枚举的可能取值—— 常量
MALE,//0
FEMALE,//1 可以在后面加入 = 给他一个初始值
//如果前面的赋值了,后面的没有赋值,就按顺序往下延。

SECRET//2

};
int main(void)
{
//规定好了它的取值
//enum是类型
enum Sex s = MALE;
//S
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enum Color
{
red,//0
green,//1
blue//2
}
int main(void)
{
//在上面定义的枚举常量中green所对应的值就是2,那么我们在这可不可以直接给s赋值为2呢?
//可以看到编译器并没有报错,说明编译器的语法检测不严格。
//2在这里是整型
//Color是枚举类型,两侧的类型是有差异的
//在c++中会报错,c++语法检测更为严格
enum Color s =;
//
return 0;
}

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
#define red 0
#define green 1
#define blue 2
int main(void)
{
int color = red;
return 0;
}
//枚举的写法比这个要更加好一些

2枚举的优点

为什么使用枚举?

我们可以使用#define来定义常量,使用枚举的优点是什么呢。

1增加代码的可读性和可维护性。

2和#define定义的标识符比较枚举有类型检查,更加严谨。

3防止命名污染(命名冲突)(封装)。

封装就是把数据和函数打包到一个类里面

4便于调试。

5使用方便,一次可以定义多个常量。


程序的执行过程

c语言的源代码–预编译-链接-可执行程序

这里的预编译就是在处理#define之类的东西

预编译会把所有的注释都删除


enum的大小怎么算呢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#incldue<stdio.h>
enum sex
{
male,
female,
secret

}
int main(void)
{
enum sex s male;
printf("%d\n",sizeof(s));
return 0;
}

联合(共用体)

1联合类型的定义

联合是一种特殊的自定义类型,这种自定义类型的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
union sb
{
char c;//一个字节
int a;//四个字节
};
//4个字节
int main(void)
{
union sb s;
printf("%p\n", &s);
printf("%p\n", &(s.c));//注意是句号
printf("%p\n", &(s.a));
//三个地址相同

return 0;
}

2特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合有能力 保存最大的那个成员)。

联合体内的成员不能同时使用


结构体、枚举、联合体的关键字不一样,性质也不一样


3联合大小的计算

联合的大小至少是最大成员的大小。

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

相关推荐视频——https://www.bilibili.com/video/BV1oi4y1g7CF?p=63&spm_id_from=pageDriver