枚举
枚举是一种用户定义的数据类型,使用关键字 enum
1)如果一个变量只有几种可能的值,则可以定义为”枚举类型“
2)用“枚举类型来表示 int 常量”
enum name{name1,....,namen};
通常并不直接使用枚举类型的类型名,而是大括号内的名字
其名字是常量符号,类型为 int ,值依次从 0 递增
enum color{red,blue,green};
该语句创建了三个 color 类型的常量
red=0,blue=1,green=2
当需要一些可以排列起来的常量值时,定义枚举的意义就是就是给了这些常量值名字
☆注意
1)枚举变量作为函数参数时
void a(enum color t);
要在自己定义的类型前加 enum 做修饰
2)枚举类型的量是以整数(int)来做内部计算和外部输出(%d)
enum color t=red;
scanf("%d",&t);
printf("%d",t);
使用小技巧
enum color {red,blue,green,NumColor};
因为枚举类型中的常量值一般是递增的
在定义枚举类型时,最后一位的值是前面常量的数量
可以在定义完需要的常量后,额外加一个计数的常量,通过该常量可以查询定义的常量数量
申明枚举量的时候也可以指定值
enum color {red=1,yellow,blue=6,green};
red=1,yellow=2,blue=6,green=7
枚举类型中的常量会按前一常量的值依次递增
枚举的实用意义
在c语言中,主要用来一次定义大量 const int 型常量
结构
struct date{
int year;
int month;
int day;
};
申明了一个名为 date 的结构变量
如何使用
申明了上列 date 结构后
struct date today;
定义了一个 struct date 类型的 today 变量
为其赋值时
today.year=2021;
today.month=4;
today.day=25;
另外两种定义的情况
1)
struct{
int x;
int y;
}p1,p2;
p1 和 p2 都是一种无名的结构,里面有 x 和 y
没有申明 point 结构,只是定义了两个变量
2)
struct point{
int x;
int y;
}p1,p2;
p1 和 p2 都是 point 类型的结构,里面含有 x 和 y
结构的初始化
struct date today={2021,4,25};
struct date month={.month=4,.day=25};
数组和结构
数组使用
[] 运算符和下标访问其单元
a[0]=0;
结构使用
. 运算符和成员名字访问其成员
today.day=25;
结构的运算
对于整个结构,可以赋值,取地址,也可以传递给函数做参数
p1=(struct point){1,2};//p1.x=1,p1.y=2;结构的赋值
p1=p2;//p1.x=p2.x,p1.y=p2.y(数组无法实现)
struct date *pDate=&today;//定义一个结构指针*pDate来取得today的地址
printf("%p",pDdate);//输出了today的地址,其中&运算符不可省略
函数和结构
int numberOfDate(struct date a)
整个结构可以作为参数的值传入函数
此时会在函数内新建一个结构变量,复制调用结构的值
函数也可以返回一个结构
输入结构
没有方法可以 scanf 一整个结构,只能一个成员一个成员的 scanf
输入方式1)
int getStruct(void);
main()
{
struct point a;
a=getStruct();//调用函数给结构a赋值,a会接收返回的p的值
}
int getStruct(void)
{
struct point p;//定义一个本地结构
scanf("%d",&p.x);//依次给成员赋值
scanf("%d",&p.y);
return p;//返回结构p
}
缺点:废空间(建立一个新结构p)废时间(p赋值给a)
输入方式2)
-> 运算符
struct point *p=&a;//p取得了结构a的地址
(*p).month=4;//两种方式等价
p->month=4;//该形式更简洁
->表示指针所指的结构变量中的成员
int getStruct(struct point *p);
main()
{
struct point a;
getStruct(&a);//调用函数给结构a赋值,a会接收返回的p的值
}
int getStruct(struct point *p)
{
scanf("%d",&p->x);//依次给成员赋值
scanf("%d",&P->y);
return p;//返回结构p
}
结构中的结构
1)数组结构
struct time{
int hour;
int minute;
int second;
};
int main()
{
struct time testTime[]={
{11,22,33},{44,55,66},{77,88,99},{12,13,14},{15,16,17}
};//定义了一个结构数组,一个struct time类型的数组
int i;
for(i=0;i<5;i++)
{
printf("%i:%i:%i",testTime.hour,testTime.minute,testTime.second);
//可以按数组的方式输出数组结构
}
}
2)结构结构——嵌套结构
struct point {
int x;
int y;
};
struct rectangle {
struct point pl1;
struct point pl2;
};
struct rectangle r;//定义了一个四边形(rectangle)
/*存在
r.pt1.x
r.pt1.y
r.pt2.x
r.pt2.y
四个量
*/
struct rectangle r,*rp;
rp=&r;
r.pt1.x == rp->pt1.x == (r.pt1).x == (rp->pt1).x //这四个都使等价的
//而 rp->pt1->x 这种形式是不存在的
☆注意
1)如果在一个函数内定义一些结构变量,则这个结构变量只能在该函数内使用,在函数外定义的话,则可以在任意的方使用
联合
自定义数据类型——typedef
用来申明一个已有数据类型的新名字
typedef int a;
之后 a 就可以代替 int 出现在变量定义和参数声明的地方
使用例
typedef long int64_bit;
typedef struct date{
int year;
int month;
int day;
} Date;//Date 于括号之间有空格隔开,便于 typedef 区分
int64_bit i=10000000000;//使定义的意思更加清晰
Date a={2021,4,25};//简化了复杂的名字,不必连带上结构体
改善了程序的可读性
联合关键字——union
union a{
int i;
char c;
} elt1,et2;//形式上类似于struct ,但其成员i和c公用一个内存空间,会相互影响
所有成员共享一个空间
同一时间只有一个成员是有效的
union 的大小是其最大成员的大小
使用例
typedef union {
int i;
char ch[sizeof(int)];//定义一个字符数组
} CHI;
int main()
{
CHU chi;
int b;
chi.i=1234;
for(b=0;b<sizeof(int);b++)//因为union的成员公用一个空间,所以可以输出ch数组内的内容
{printf("%02hhX/*输出16进制的数*/",chi.ch[i]);}
}