1. 枚举
2. 结构
3. 联合
枚举
- 枚举是⼀种⽤户定义的数据类型,它⽤关键字 enum 以如下语 法来声明:enum 枚举类型名字 {名字0, …, 名字n} ;
- 枚举类型名字通常并不真的使⽤,要⽤的是在⼤括号⾥的名字, 因为它们就是就是常量符号,它们的类型是int,值则依次从0 到n。如:enum colors { red, yellow, green } ;
- 就创建了三个常量,red的值是0,yellow是1,⽽green是2。
- 当需要⼀些可以排列起来的常量值时,定义枚举的意义就是给 了这些常量值名字。
1. 常量符号化
#include <stdio.h> const int red = 0; const int yellow = 1; const int green = 2; // enum COLOR {RED, YELLOW, GREEN}; int main() { int color = -1; char *colorName = NULL; printf("请输入你喜欢的颜色的代码:"); scanf("%d",&color); switch(color){ case red: colorName = "red"; break; case yellow: colorName = "yellow"; break; case green: colorName = "green"; break; default: colorName = "unknow"; break; } printf("你喜欢的颜色是%s\n",colorName); return 0; }
会报错
⽤符号⽽不是具体的数字来表⽰程序中的数字
#include <stdio.h> // const int red = 0; // const int yellow = 1; // const int green = 2; enum COLOR {RED, YELLOW, GREEN}; int main() { int color = -1; char *colorName = NULL; printf("请输入你喜欢的颜色的代码:"); scanf("%d",&color); switch(color){ case RED: colorName = "red"; break; case YELLOW: colorName = "yellow"; break; case GREEN: colorName = "green"; break; default: colorName = "unknow"; break; } printf("你喜欢的颜色是%s\n",colorName); return 0; }
输入0,1,2来检测输出的结果
⽤枚举⽽不是定义独⽴的const int变量
2.案例
- 枚举量可以作为值
- 枚举类型可以跟上enum作为类型
- 但是实际上是以整数来做内部计算 和外部输⼊输出的
套路:⾃动计数的枚举
#include <stdio.h> enum COLOR {RED, YELLOW, GREEN, NumCOLORS}; int main() { int color = -1; char *ColorNames[NumCOLORS] = { "red","yellow","green", }; char *colorNames = NULL; printf("请输入你喜欢的颜色代码:"); scanf("%d",&color); if(color>=0 && color<NumCOLORS){ colorNames = ColorNames[color]; }else{ colorNames="unknown"; } printf("你喜欢的颜色是%s\n",colorNames); return 0; }
4. 枚举量
声明枚举量的时候可以指定值
enum COLOR { RED=1, YELLOW, GREEN = 5};
5. 枚举只是int
即使给枚举类型的变量赋不存在的整数值也没有任何 warning或error
6.枚举
- 虽然枚举类型可以当作类型使⽤,但是实际上 很(bu)少(hao)⽤
- 如果有意义上排⽐的名字,⽤枚举⽐const int⽅ 便
- 枚举⽐宏(macro)好,因为枚举有int类型
结构
1. 声明结构类型
#include <stdio.h> #include <time.h> #include <stdlib.h> int main() { struct date{ int month; int day; int year; }; struct date today; today.month = 07; today.day =31; today.year = 2014; printf("Today's date is%i-%i-%i.\n",today.year,today.month,today.day); return 0; }
2. 在函数内/外?
- 和本地变量⼀样,在函数内部声明 的结构类型只能在函数内部使⽤
- 所以通常在函数外部声明结构类型, 这样就可以被多个函数所使⽤了
#include <stdio.h> #include <time.h> #include <stdlib.h> struct date{ int month; int day; int year; }; int main() { struct date today; today.month = 07; today.day =31; today.year = 2014; printf("Today's date is%i-%i-%i.\n",today.year,today.month,today.day); return 0; }
3. 声明结构的形式
4.结构变量
struct date today;
today.month=06;
today.day=19;
today.year=2005;
5. 结构的初始化
#include <stdio.h> #include <time.h> #include <stdlib.h> struct date{ int month; int day; int year; }; int main() { struct date today = {07,31,2014}; // struct date thismonth = {.month=7,.year=2014,.day=31}; printf("Today's date is %i-%i-%i.\n",today.year, today.month , today.day); // printf("Today's date is%i-%i.\n",thismonth.year,thismonth.month,thismonth.day); return 0; }
6. 结构成员
- 结构和数组有点像
- 数组⽤[]运算符和下标访问其成员
- a[0] = 10;
- 结构⽤.运算符和名字访问其成员
- today.day
- student.firstName
- p1.x
- p1.y
7. 结构运算
- 要访问整个结构,直接⽤结构变量的名字
- 对于整个结构,可以做赋值、取地址,也可以 传递给函数参数
- p1 = (struct point){5, 10}; // 相当于p1.x = 5;
- p1.y = 10;
- p1 = p2; // 相当于p1.x = p2.x; p1.y = p2.y;
8. 复合字⾯量
- today = (struct date) {9,25,2004};
- today = (struct date) {.month=9, .day=25, year=2004};
9.结构指针
- 和数组不同,结构变量的名字并不是 结构变量的地址,必须使⽤&运算符
- struct date *pDate = &today;
10. 结构与函数
结构作为函数参数
int numberOfDays(struct date d);
11.输⼊结构
- 没有直接的⽅式可以⼀次scanf⼀ 个结构
- 如果我们打算写⼀个函数来读⼊ 结构 : —>
- 但是读⼊的结构如何送回来呢?
- 记住C在函数调⽤时是传值的
- 所以函数中的p与main中的y是不 同的
- 在函数读⼊了p的数值之后,没 有任何东⻄回到main,所以y还 是 {0, 0}
12. 解决的⽅案
- 之前的⽅案,把⼀个结构传⼊了函数,然后在函数中操 作,但是没有返回回去
- 问题在于传⼊函数的是外⾯那个结构的克隆体,⽽不是指 针
- 传⼊结构和传⼊数组是不同的
- 在这个输⼊函数中,完全可以创建⼀个临时的结构变量, 然后把这个结构返回给调⽤者
13. 结构指针作为参数
14. 指向结构的指针
15.结构指针参数
16. 结构数组
struct date dates[100];
struct date dates[] = { {4,5,2005},{2,4,2005}};
17.结构中的结构
struct dateAndTime { struct date sdate; struct time stime; };
18.嵌套的结构
19. 结构中的结构的数组
联合
1.⾃定义数据类型
- C语⾔提供了⼀个叫做 typedef 的功能来声明⼀个已有的数据类型的 新名字。⽐如:typedef int Length; 使得 Length 成为 int 类型的别名。
- 这样, Length 这个名字就可以代替int出现在变量定义和参数声明的 地⽅了: Length a, b, len ; Length numbers[10] ;
2.Typedef
声明新的类型的名字
新的名字是某种类型的别名
改善了程序的可读性
3. typedef
typedef struct {
int month;
int day;
int year;
} Date;
4. 联合
- 存储
- 所有的成员共享⼀个空间
- 同⼀时间只有⼀个成员是有效的
- union的⼤⼩是其最⼤的成员
- 初始化
- 对第⼀个成员做初始化
结构指针参数