目录
枚举
1.定义
1.枚举类型定义一般形式
emum 枚举名 {枚举表列};
2.枚举变量定义
emum 枚举名 {枚举表列}枚举变量;
例如:enum WEEKDAY是枚举类型,WEEKDAY是枚举名,sun,mon,……sat是枚举常量,week是枚举变量。
#include<stdio.h>
enum WEEKDAY
{
sun,mon,tue=4,wed,thu,fir,sat
}week;
enum WEEKDAY week1;
2.枚举元素
枚举元素没有初始化时,默认从0开始为各个元素赋值。但当枚举中的某个成员赋值后,其后的成员按依次加1的规则确定其值。
#include<stdio.h>
enum WEEKDAY
{
sun,mon,tue=4,wed,thu,fir,sat
};
int main()
{
printf("%d\n", sun);//0
printf("%d\n", mon);//1
printf("%d\n", tue);//4
printf("%d\n", wed);//5
return 0;
}
3.枚举值是常量值,不可以在程序中使用赋值语句重新赋值
enum WEEKDAY
{
sun,mon,tue=4,wed,thu,fir,sat
//tue 初始化
};
int main()
{
sun = 2;//错误,枚举常量不可以重新赋值
return 0;
}
3.枚举的使用
枚举和define的区别:
#define 标识符 常量
#define sun 0
#define mon 1
enum WEEKDAY
{
sun,mon,tue=4,wed,thu,fir,sat
//tue 初始化
};
1.枚举可以一次列举出来多个元素,而define只可以一次定义一个元素
2.枚举常量是在编译的时候确定了值,而宏在预编译时期进行简单替换
3.一般编译器可以调试枚举常量,不能调试宏常量。
4.#define可以定义任意类型的常量,而枚举只能是定义整型常量。
#include<stdio.h>
void menu()
{
printf("***********************\n");
printf("****1.加法*************\n");
printf("****2.减法*************\n");
printf("****3.乘法*************\n");
printf("****4.除法*************\n");
printf("****0.退出*************\n");
printf("***********************\n");
}
int main()
{
menu();
int input;
do
{
printf("输入选择\n");
scanf("%d", &input);
switch (input)
{
case 1:printf("加法"); break;
case 2:printf("加法"); break;
case 3:printf("乘法"); break;
case 4:printf("除法"); break;
case 0:printf("退出"); break;
default:printf("重新输入\n"); break;
}
} while (input);
return 0;
}
#include<stdio.h>
enum option
{
EXIT,ADD,SUB,MUL,DIV
};
void menu()
{
printf("***********************\n");
printf("****1.加法*************\n");
printf("****2.减法*************\n");
printf("****3.乘法*************\n");
printf("****4.除法*************\n");
printf("****0.退出*************\n");
printf("***********************\n");
}
int main()
{
menu();
int input;
do
{
printf("输入选择\n");
scanf("%d", &input);
switch (input)
{
case ADD:printf("加法"); break;
case SUB:printf("加法"); break;
case MUL:printf("乘法"); break;
case DIV:printf("除法"); break;
case EXIT:printf("退出"); break;
default:printf("重新输入\n"); break;
}
} while (input);
return 0;
}
4.枚举类型变量大小
枚举类型的声明不占据内存,枚举类型的变量占据内存,c语言枚举类型变量大小4
在C++标准文档中是这样说明的:“枚举类型的尺寸是以能够容纳最大枚举子的值的整数的尺寸”,同时标准中也说了:“枚举类型中的枚举子的值必须要能够用一个int类型表述”。其实可以说一个枚举类型所占空间的大小即为一个常数所占内存空间的大小,即一个int型所占内存空间的大小。
联合体
1.概念
在计算机语言中,使几种不同类型的变量存放到同一内存单元中。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作共用体,也叫联合体。
2.共用体的定义
定义一个联合类型的一般形式为:
union 共用体名
{
成员表
};
union s
{
int a;
char name;
};
定义了一个共用体类型,s是共用体名,它有两个变量,int类型的a,char类型的name
3.共用体变量的定义
1.先定义共用体类型,后定义共用体变量
#include <stdio.h>
union s
{
int a;
char name;
};
union s m;
int main()
{
union s k;
return 0;
}
2.定义共用体的同时创建变量
union s
{
int a;
char name;
}m;
3.省略共用体名,直接定义共用体变量
union
{
int a;
char name;
}m;
4.初始化共用体
由于共用体同时占据一块内存空间,所以初始化时只可以对一个成员进行初始化。
#include<stdio.h>
union book
{
int a;
int b;
}m = { 2};
int main()
{
//union book b = { 1 ,2};//错误
union book b = { 1 };
}
5.引用共用体变量
使用成员访问运算符(.)
#include<stdio.h>
union book
{
int a;
int b;
}m = { 2 };
int main()
{
union book b = { 1 };
printf("%d\n", b.a);//1
printf("%d\n", b.b);//1
}
共用体中起作用的是最后一次被赋值的成员,在成员被赋值后,原来的成员值就会被覆盖。
#include<stdio.h>
union book
{
int a;
int b;
char s;
}A;
int main()
{
A.a = 65;
A.b = 66;
A.s = 48;
printf("%d\n", A.a);//48
printf("%d\n", A.b);//48
printf("%d\n", A.s);//48
printf("%c\n", A.a);//0
printf("%c\n", A.b);//0
printf("%c\n", A.s);//0
}
6.共用体和结构体的区别
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
#include<stdio.h>
union book
{
char name[20];
int price;
}s;
int main()
{
printf("%p\n", &s);
printf("%p\n", &s.name);
printf("%p\n", &s.price);
return 0;
}
打印的三个地址相同
7.共用体的大小
- 共用体的大小至少是最大成员的大小
- 当最大成员的大小不是最大对齐整数倍的时候,就要对齐到最大对齐数的整数倍处
例一:
#include<stdio.h>
union s
{
char a[5];
int i;
}a;
int main()
{
printf("%d", sizeof(a));
}
例2:
#include<stdio.h>
union s
{
short a[7];
int i;
}a;
int main()
{
printf("%d", sizeof(a));
}
例3:
#include<stdio.h>
struct s
{
char a;
int b;
}s;
union S
{
char a[3];
short i;
struct s m;
}a;
int main()
{
printf("%d", sizeof(a));
return 0;
}
例题5:
#include<stdio.h>
#pragma pack (2)
struct a
{
int i;
union u
{
char buff[13];
int i;
}u;
enum {red,green}colour;
}m;
int main()
{
printf("%d", sizeof(m));
return 0;
}
结果:22
8.共用体应用
1.判断系统的大小端
系统大小端:1:0x 00 00 00 01
小端:0x 01 00 00 00
大端:0x 00 00 00 01
思路:取出第一个字节来判断
#include<stdio.h>
int main()
{
int a = 1;
char* p = (char*)(&a);
if (*p == 1)
printf("小端");
else
printf("大端");
return 0;
}
#include<stdio.h>
union check
{
int a;
int b;
}s;
int main()
{
s.a = 1;
if (s.b == 1)
printf("小端");
else
printf("大端");
return 0;
}
2.处理信息
现有一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、职业、教学科目。请看下面的表格:
Name | Num | Sex | Profession | Score / Course |
---|---|---|---|---|
HanXiaoXiao | 501 | f | s | 89.5 |
YanWeiMin | 1011 | m | t | math |
LiuZhenTao | 109 | f | t | English |
ZhaoFeiYan | 982 | m | s | 95.0 |
对于学生,最后一项是成绩,对于老师,最后一项是科目。根据身份的不同,最后一栏的种类不同,且只对应一种种类,可以使用共用体。
#include<stdio.h>
struct
{
char name[20];
int num;
char sex;
char profession;
union
{
char course[20];
float score;
}u;
}s[4];
int main()
{
for (int i = 0; i < 4; i++)
{
printf("输入信息\t\tName\tNum\tSex\tProfession\n");
scanf("%s %d %c %c", s[i].name, &s[i].num, &s[i].sex, &s[i].profession);
if (s[i].profession == 's')
{
printf("请输入成绩\n");
scanf("%f", &s[i].u.score);
}
else
{
printf("请输入科目\n");
scanf("%s",s[i].u.course);
}
}
printf("Name\t\tNum \tSex \tProfession \tScore / Course\t");
for (int i = 0; i < 4; i++)
{
printf("\n%s\t%d\t%c\t%c\t", s[i].name, s[i].num, s[i].sex, s[i].profession);
if (s[i].profession == 's')
printf("\t%.1f", s[i].u.score);
else
printf("\t%s", s[i].u.course);
}
return 0;
}