枚举类型的定义
#include <stdio.h>
enum color
{ //枚举的可能取值
blue, // ,号分隔
red,
yellow
};
enum S
{
a =17,
b=20,
c=16
};
int main()
{
printf("%zd\n", sizeof(color)); //4
printf("%zd\n", sizeof(blue)); //4,枚举类型的大小为整形大小
printf("%d %d %d\n", blue,red,yellow); //初始值按顺序排默认为blue--0 red--1 yellow--2
//enum S a = 12; //error--"int" 类型的值不能用于初始化 "S" 类型的实体,不能再内部定义
printf("%d %d %d\n",a,b,c); //初始值可以在前面自定义
return 0;
}
可以使用define,为什么还要用enum
枚举的优点
1.增强代码的可读性和可维护性
2.和define定义标识符相比,枚举有类型检查,更加严谨、
3.防止了命名污染(封装)
4.便于调试
5.使用方便,一次可以定义多个常量
联合(联合体,共用体)
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间
联合体的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍联合类型的声明
#include <stdio.h>
union S
{
char c;
int a;
};
union M
{
int a; //a的最大对齐数是4
char n[5];//n[5]的最大对齐数是1,相当于定义五个char
}; //M的最大对齐数是4,而4字节放不下n,需要再开辟4个字节空间
int main()
{
union S m;
union M x;
printf("%p\n", &m);
printf("%p\n", &(m.c));
printf("%p\n", &(m.a)); //三个的地址相同,c和a共用了同一块空间,都从起始位置往后放
printf("%zd\n", sizeof(S)); //--4
printf("%zd\n", sizeof(m)); //--4
printf("%zd\n", sizeof(x)); //8
return 0;
}
位段--二进制位
位断的声明和结构是类似的,有两个不同
1.位段的成员必须是相同类型的(int,unsigned int或signed int)
2.位段的成员名后边有一个冒号和一个数字
3.设置可移植程序时尽量别用位段,不同编译器不一样
#include <stdio.h>
struct A
{
int a : 2; //a占2个比特位
int b : 5; //b占5个比特位
int c : 10; //10个
int d : 30; //30个 共47bite
}; //int类型 先开辟4个字节(32bite)空间 不够后又加4字节空间
//节省空间的同时允许浪费空间
int main()
{
int a = 100;
struct A m;
printf("%zd\n", sizeof(A));
printf("%zd\n", sizeof(m)); //8个字节
return 0;
}
位段的跨平台问题
int 当成有符号数还是无符号数不能确定
位段中最大位数的数目不能确定
位段中的成员在内存中的分配从左向右还是从右向左不能确定
.........
#include <stdio.h>
struct s
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
struct s n = {0};
n.a = 10;
n.b = 20;
n.c = 3;
n.d = 4;
return 0;
}
struct S
{
char a; //1字节
char b:1;
char c : 2;
char d : 3;
}*p;//共两个字节
#include <stdio.h>
#include <string.h>
int main()
{
char arr[4];
memset(arr, 0, 4);//把arr的四个字节设置为0
//arr 00000000 00000000 00000000 00000000
// a d c b 第一个字节给a 第二个字节最后的bit给b,依次类推
p=(struct S*)arr; //将数组arr强制转化为(struct S*)类型赋给p
//p 00000000 00000000 00000000
p->a = 2;
p->b = 3;//11 而b只花一个比特存储,于是只存1
p->c = 4;//100 两个比特位 放00
p->d = 5;//101 三个比特位 放101
//p 00000010 00101001 00000000
printf("%02x %02x %02x %02x\n",arr[0],arr[1],arr[2],arr[3]);
return 0;
}