和结构体一同出现的一般还会有共用体和枚举类型,这三者的语法格式相同,不同的只是使用的情境不同。
共用体
共用体能够将不同类型的变量存放到同一段内存单元,这也就是 union 的由来。
语法
union unionname
{
datatype member1;
datatype member2;
datatype member3;
};
定义和初始化
先看下边的程序:
#include <stdio.h>
typedef union student1
{
short num;
char sex;
int score;
}USTU;
typedef struct student2
{
short num;
char sex;
int score;
}SSTU;
int main()
{
USTU stu1 = {10,'x',80};
SSTU stu2 = {20,'y',90};
printf("sizeof(USTU) = %d\n",sizeof(USTU));
printf("&stu1.num = %p,stu1.num = %d\n",&stu1.num,stu1.num);
printf("&stu1.sex = %p,stu1.sex = %c\n",&stu1.sex,stu1.sex);
printf("&stu1.score = %p,stu1.score = %d\n",&stu1.score,stu1.score);
printf("sizeof(SSTU) = %d\n",sizeof(SSTU));
printf("&stu2.num = %p,stu2.num = %d\n",&stu2.num,stu2.num);
printf("&stu2.sex = %p,stu2.sex = %c\n",&stu2.sex,stu2.sex);
printf("&stu2.score = %p,stu2.score = %d\n",&stu2.score,stu2.score);
return 0;
}
结果为:
sizeof(USTU) = 4
&stu1.num = 0x7fffec657b40,stu1.num = 10
&stu1.sex = 0x7fffec657b40,stu1.sex =
&stu1.score = 0x7fffec657b40,stu1.score = 10
sizeof(SSTU) = 8
&stu2.num = 0x7fffec657b50,stu2.num = 20
&stu2.sex = 0x7fffec657b52,stu2.sex = y
&stu2.score = 0x7fffec657b54,stu2.score = 90
从上面的结果来看:
- 共用体类型和结构体类型的构造方式相同
- 构造体类型变量的输出结果正常,成员指针也是线性排列的
- 共用体类型的字节长度是成员中字节长度最大的那个
- 共用体类型变量成员指针全部指向同一个地址,也就是该共用体变量的首地址
- 从共用体成员打印的结果来看,对共用体类型变量成员全部进行初始化是错误的
- 但是只对首个成员初始化是可以实现正确结果的
- 也可以想到,共用体类型变量最好先定义再赋值会比较好
- 共用体类型变量的成员赋值只与最新的一次赋值有关
大端模式和小端模式
- 大端模式:数据低位保存在内存高位地址中,数据高位保存在内存低位地址中
- 大端模式:数据低位保存在内存低位地址中,数据高位保存在内存高位地址中
利用共用体类型可以判断计算机的大小端:
#include <stdio.h>
typedef union student1
{
char top;
int num;
}USTU;
int main()
{
USTU stu;
stu.num = 0x41424344;
printf("stu.top = %c\n",stu.top);
printf("stu.num = %x\n",stu.num);
return 0;
}
结果为:
stu.top = D
stu.num = 41424344
由结果可知,数据低位存储在内存低位地址中,即为小端模式。
枚举
枚举类型可以定义一组整型常量,从而提高程序的可读性。枚举类型有时候用在 switch 中,作为一种标签使用。
语法
enum enumname
{
memberlist
};
定义和初始化
#include <stdio.h>
typedef enum week
{
MON,TUE,WED,THU,FRI,SAT,SUN
}DAY;
int main()
{
printf("%d,%d,%d,%d,%d,%d,%d\n",MON,TUE,WED,THU,FRI,SAT,SUN);
DAY day = MON;
printf("%d\n",day);
return 0;
}
结果为:
0,1,2,3,4,5,6
0
从上面的结果可以看出:
- 枚举类型是一个集合,集中中的元素都是一些自命名的变量,并且变量还都是整型的
- 构造枚举类型的时候,各个元素之间用逗号隔开
- 一定要注意枚举元素最后边没有分号
- 如果没有在构造枚举类型时给元素赋值,就默认为0,1,2,3...的有序数列
- 如果在构造枚举类型时给元素赋值,就认为是从赋值位置开始的递增数列
- 枚举类型可以看作是预处理指令 #define 的替代
- 上边定义的枚举类型变量,既可以赋值为整型值,也可以赋值为枚举元素