3.1 枚举
3.2 结构
3.3 类型定义
3.1 枚举
枚举是一种用户定义的数据类型,它用关键字enum以如下语法来表明:
enum 枚举类型名字{名字0,...,名字n};
枚举类型名字通常并不真的使用,要用的是在大括号里的名字,因为它们就是常量符号,它们的类型是int,值则依次从0到n。如:
enum colors{red, yellow, green};
就创建了三个常量,red的值是0,yellow的值是1,而green的值是2
当需要一些可以排列起来的常量值时,定义枚举的意义就是给了这些常量值的名字
套路:自动计数的枚举
这样需要遍历所有的枚举量或者需要建立一个用枚举量做下标的数组的时候就很方便了
1 #define _CRT_SECURE_NO_WARNINGS
2
3 #include
4
5 enumcolors6 {7 red, yellow, green, numcolors//枚举的套路,最后一个放颜色的数量
8 };9
10 main()11 {12 int color = -1;13 char *colorsnames[numcolors] = { "red","yellow","green"};14 char *colorname =NULL;15
16 printf("输入你喜欢的颜色的代码:");17 scanf("%d", &color);18
19 if (color >= 0 && color
24 {25 colorname = "unknown";26 }27
28 printf("你喜欢的颜色是%s", colorname);29
30 system("pause");31 }
枚举量
声明枚举量的时候可以指定值
1 enumcolors2 {3 red = 1, yellow, green = 5
4 };
枚举只是int
即使给枚举类型的变量赋不存在的整数值也没有任何warning或error
虽然枚举类型可以当作类型使用,但是实际上很(bu)少(hao)用
如果有意义上排比的名字,用枚举比const int方便
枚举比宏(macro)好,因为枚举有int类型
3.2 结构
和本地变量一样,在函数内部声明的结构类型只能在函数内部使用
所以通常在函数外部声明结构类型,这样就可以被多个函数所使用了
类似数组,初始化的时候没有全部赋值,没有赋值的元素是0
1 structdate2 {3 intmonth;4 intday;5 intyear;6 };7
8 struct date today = { 07,31};9
10 printf("%d,%d,%d", today.month, today.day, today.year);
结构运算
要访问整个结构,直接用结构变量的名字
对于整个结构,可以做赋值、取地址,也可以传递给函数参数
1 structpoint2 {3 intx;4 inty;5 };6
7 structpoint p1, p2;8
9
10 p1 = (struct point) { 5, 10 };//相当于p1.x = 5;p1.y = 10;
11
12 p2 = p1;//相当于p1.x = p2.x;p1.y = p2;y;
数组无法做以上两种运算
结构指针
和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符
struct date *pDate = &today;
结构作为函数参数
int numberofdays(struct date d);
整个结构可以作为参数的值传入函数
这时候是在函数内新建一个结果变量,并复制调用者的结构的值
也可以返回一个结构
这与数组完全不同
输入结构
没有直接的方式可以一次scanf一个结构
结构指针作为参数
K & R说过(p.131)
"if a large structure is to be passed to a function, it is generally more efficient to pass a pointer than to copy the whole structure"
指向结构的指针
1 structdate2 {3 intmonth;4 intday;5 intyear;6 };7
8 structdate today;9 struct date *p = &today;10
11 (*p).month = 12;12
13 p->month = 12;
用->表示指针所指的结构变量中的成员
结构数组
struct date dates[100];
struct date dates[]=
{
{4,5,2005},
{2,4,2005}
};
结构中的结构
struct dateAndTime
{
struct date sdate;
struct time stime;
};
嵌套的结构
struct point
{
int x;
int y;
};
struct rectangle
{
struct point pt1;
struct point pt2;
};
如果有变量
struct rectangle r;
就可以有:
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(因为pt1不是指针)
3.3 类型定义
自定义数据类型typedef
C语言提供了一个叫做typedef的功能来声明一个已有的数据类型的新名字。比如:
typedef int Length;
使得Length成为int类型的别名
这样,Length这个名字就可以代替int出现在变量定义和参数声明的地方了
Length a, b, len;
Length numbers[10];
typedef
声明新的类型的名字
新的名字是某种类型的别名
改善了程序的可读性
1 typedef long int64_t;//重载已有的类型名字,新名字的含义更清晰,具有可移植性
2
3 typedef structADate4 {5 intmonth;6 intday;7 intyear;8 }Date;//简化了复杂的名字
9
10 int64_t i = 100;11
12 Date d = { 9,1,2005 };
typedef struct
{
int month;
int day;
int year;
}Date;
typedef最后一个单词就是名字
联合
sizeof(union...)=sizeof(每个成员)的最大值
存储
所有的成员共享一个空间
同一时间只有一个成员是有效的
union的大小是其最大的成员
初始化
对第一个成员做初始化