- 位端
- 什么是位端
- 位端的内存分配问题
- 位端的跨平台问题
- 总结
- 枚举
- 枚举的定义
- 枚举的优势
- 枚举的使用
- 联合体(共用体)
- 联合体的定义
- 联合体的特点
- 试题引导
- 联合体大小的计算
- 链接
位端 什么是位端
位端跟结构体相似,但有两个不同;
位端的成员变量必须是 int , unsigned int , signed int;
位端的成员后面有一个冒号和数字。
例如
//位端的演示
struct s
{
int a : 2;
int b : 2;
int c : 2;
int d : 4;
};
在这里 s 就是一个位端。
位端的内存分配问题
- 位端的结构体成员必须是 int , unsigned int , signed int ,或者是 char (整形家族)类型;
- 位端的空间开辟是按照 int 四个字节,char 一个字节;
- 关于位端有许多不确定的因素(标准被定义),是不支持跨平台的,可移植的程序要避免使用位端。
例题
struct s
{
char a : 2;
char b : 2;
char c : 8;
}s;
int main()
{
s.a = 1;
s.b = 4;
s.c = 6;
printf("%d\n", sizeof(s));
return 0;
}
结果演示
题目解析
这里我们看到结构体成员后面的数字代表 所占的bety位数;
a 为 char 类型先开辟一个空间以供使用,a 占两个比特位,放入数字01,我们假设从高地址处想低地址处存放(每个平台设置的都不一样),剩下6个比特位;
b 占2个比特位,还有六个可以继续使用, b=100但是只能放两个比特位,舍去最高位放入00,还剩4个比特位;
c 占8个比特位,剩余的四个不够,再次开辟一个空间,剩下的四个空间可能使用可能不使用(C语言标准并未定义),c=0110,放入0110,不够进行补位;
占2个字节。
总结
- int 在位端中被当作有符号数,还是无符号数都是不确定的;
- 位端中最大位的数目也是不确定的。(16位机器是16,64位机器是64,在16位机器中写成17会出问题)
- 位端中的成员是从左往后分配,还是从右往左分配是不确定的。
- 当结构体包含两个位端时,第二个位端所需要的空间大于所剩的空间时,
会开辟新的空间,但是所剩的空间是否使用不确定。
位端相较于结构体,会节省更多的空间,但是效率会下降。而结构体为了高效,会进行结构体对齐而浪费部分空间。
枚举
把可能的取值一一列举出来叫做列举。
列举的全程:enumeration
如:
星期: 星期一、星期二、星期三、星期四、星期五、星期六、星期日;
性别:男性、女性、保密;
月份: 一月、二月、三月、四月…十二月;
enum day
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum sex
{
male,
female,
secret
};
这里 enum day、enum sex都是枚举类型。
括号内的值叫做枚举常量。
我们发现枚举常量都是用逗号分隔开来,同时在定义完枚举类型后我们需要用分号来结束。
每个枚举常量都是有值的,默认都是从 0 开始,依次加一。
我们也可以修改这些值,只需要加上等号即可。
我们也可以只修改开头的值,设为5,它将从5开始,依次加一。
枚举的使用
- 增加代码的可读性和可维护性;
- 和 define 定义的标识性常量相比枚举有类型检查,更加严禁;
- 防止命名污染;
- 便于调试;
使用方便一次可定义多个常量。
//枚举的使用
enum menu
{
exit,
start,
suspend,
end
};
int main()
{
int input;
scanf("%d", &input);
switch (input)
{
case exit:
break;
case start:
break;
case suspend:
break;
case end:
break;
default:
break;
}
return 0;
}
这样我在书写某些程序时,就不需要 case 0、case 1…再面对这样晦涩难懂的语句了。同时我们通过一个枚举,同时定义了好多值(如 exit = 0),不用再一一定义了。
联合体(共用体)
联合体是一种特殊的自定义类型,联合体的变量也包括各种类型,但是他们公用同一块空间,一个值改变另一个指也会跟着改变。
联合体的定义//联合体的定义
union s
{
char a;
int b;
};
在这里我们定义了联合体。
联合体的特点 试题引导//联合体的特点
union s
{
char a;
int b;
}s;
int main()
{
s.a = 1;
printf("%d\n", s.a);
s.b = 2;
printf("%d\n", s.a);
printf("%p\n", &s.a);
printf("%p\n", &s.b);
return 0;
}
结果展示
我们发现当 b 改变时, a 也会跟着改变,我们还发现 a 和 b 的起始地址都是一样的。由此我们得出结论:联合体变量共用同一空间,一个值改变,另一个值也会受到影响。
- 联合体的大小为最大成员的大小;
- 当最大成员不是最大对齐数的整数倍时,要对齐到最大对齐数的整数倍处。
试题演示
//联合体的大小
union s
{
char a[19];
int b;
}s;
union j
{
int a[20];
char b;
}j;
int main()
{
printf("%d\n", sizeof(s));
printf("%d\n", sizeof(j));
return 0;
}
结果展示
解析
在s中a[19] 的对齐数是 1,b的对齐数是 4,a[19]大小为19个字节,但是不是最大对齐数的整数倍,所以空间为 20个字节。
在j中最大对齐数是 4,所占空间是 80个字节,刚好是 4 的整数倍。
位端、枚举、联合体的相关代码
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)