枚举 (Enumer)
枚举是一种用户定义基本数据类型,使用关键字enum声明,主要用于排比一系列有意义的名字
格式
enum 枚举名 {枚举元素1,枚举元素2,...}
枚举元素只能是int类型,可以作为常量符号使用
枚举可以让独立定义的连续常量更简洁化
例如
1 2 3 4
| const int zero = 0; const int one = 1; const int two = 2; const int three = 3;
|
可以使用枚举写成enum number{zero,one,two,three}
第一个枚举元素默认从0开始,你可以指定第一个从任意数字开始,后面依次排列
输入输出
枚举的元素可以作为值去使用,而枚举类型可以带上enum作为数据类型,犹如int、double这种数据类型一样,还可以以整数的方式做内部计算和外部的输入输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h>
enum number { one = 1, two, three }; void f(enum number x); int main() { enum number t = 0; scanf("%d" , &t); f(t); return 0; } void f(enum number x){ printf("%d", x); return; }
|
结构体 (Struct)
可以理解成可以存放不同数据类型的数组,一个结构中包含了多个成员的数据类型
⇩长代码警告!
结构类型
结构类型需要使用struct语句,定义变量时需要带上struct以及结构类型名称
格式
1 2 3 4 5 6
| struct 结构体类型名称 { 成员变量; };
struct 结构体类型名称 变量名;
|
也可以写成下面这样,它们的意思是一样的
1 2 3 4
| struct 结构体类型名称 { 成员变量; }变量名;
|
每个变量名都包含结构变量的所有内容,当你要对变量赋值时,需要对应结构体中的成员变量类型
结构运算
与数组一样,当需要访问结构成员时,使用变量名 .成员变量
的方式
要访问整个结构的时候直接用结构变量的名称就行
对于整个结构,可以做赋值,取地址的操作,还可以传递给函数参数
初始化
在定义变量的时候就初始化结构内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <stdio.h>
struct number { int one; int two; int three; } demo;
int main() { struct number demo = {10, 20, 30}; printf("one = %i,two = %i, three = %i", demo.one, demo.two, demo.three); return 0; }
|
还可以用另一种方式去初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <stdio.h>
struct number { int one; int two; int three; }demo;
int main() { demo = (struct number){10, 20, 30}; printf("one = %i,two = %i, three = %i", demo.one, demo.two, demo.three); return 0; }
|
甚至你还可以像数组一样对单个成员变量初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <stdio.h>
struct number { int one; int two; int three; }demo; int main() { demo = (struct number){.one = 10, .three = 30}; printf("one = %i,two = %i, three = %i" , demo.one, demo.two, demo.three); return 0; }
|
结构指针
与数组不同的是,结构变量的名称并不是结构变量的地址,所以在访问结构变量在内存中的的地址时,需要用到取地址符&
1 2
| struct number *p = &demo; printf("demo = %p", p);
|
需要用指针指向结构内容时,可以用到一个新的运算符->
意为将指针指向结构的成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <stdio.h>
struct number { int two; }demo;
int main() { demo = (struct number){ 20 }; printf("two = %i\n", demo.two); struct number *p = &demo; p -> two = 200; printf("two = %i", p->two);
return 0; }
|
学生表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <stdio.h> struct student { int studentID; char *name; char *sex; int age; }first;
int main() { first = (struct student) {1003,"张三","男",19}; printf("名字\t性别\t年龄\t学号\t\n%s\t%s\t%i\t%i" ,first.name, first.sex, first.age, first.studentID); return 0; }
|
结构函数
整个结构可以作为参数的值传入函数
当传递的是一个结构时,在函数中是新建了一个结构变量,并复制了调用者的结构的值
这个函数的返回类型可以是一个结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
#include <stdio.h> #include <stdbool.h>
struct date { int month; int day; int year; };
int numberofDays(struct date d);
bool isLeap(struct date d);
int main() { struct date today, tomorrow; printf("Enter today's date (mm-dd-yy):"); scanf("%i-%i-%i", &today.month, &today.day, &today.year); if (today.day != numberofDays(today)) { tomorrow.day = today.day + 1; tomorrow.month = today.month; tomorrow.year = today.year; } else if (today.month == 12) { tomorrow.day = 1; tomorrow.month = 1; tomorrow.year = today.year + 1; } else { tomorrow.day = 1; tomorrow.month = today.month + 1; tomorrow.year = today.year; } printf("Tomorrow'date is %i-%i-%i", tomorrow.month, tomorrow.day, tomorrow.year); return 0; }
int numberofDays(struct date d) { int days; const int dayspermonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (d.month == 2 && isLeap(d)) { days = 29; } else { days = dayspermonth[d.month - 1]; } return days; }
bool isLeap(struct date d) { bool leap = false; if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0) { leap = true; } return leap; }
|
结构数组
声明结构数组:struct 结构体类型名称 成员变量[数组元素个数]
例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <stdio.h>
struct time { int hour; int min; int seconds; }NowTime;
int main() { struct time NowTime[5] = { {11,59,59}, {12,0,0}, {1,59,29}, {23,59,59}, {19,50,29} }; return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include <stdio.h>
struct time { int hour; int min; int seconds; } NowTime;
struct time LaterTime(struct time now);
int main() { const int CURT = 5; struct time NowTime[CURT] = { {11, 59, 59}, {12, 0, 0}, {1, 59, 29}, {23, 59, 59}, {19, 50, 29} }; struct time *p = NowTime; for (int i = 0; i < CURT; i++) { *p = NowTime[i]; printf("Nowtime is %.2i:%.2i:%.2i", p->hour, p->min, p->seconds); *p = LaterTime(*p); printf("...One seconds later its %.2i:%.2i:%.2i\n", p->hour, p->min, p->seconds); } return 0; }
struct time LaterTime(struct time now) { ++now.seconds; if (now.seconds == 60) { now.seconds = 0; ++now.min; if (now.min == 60) { now.min = 0; ++now.hour; if (now.hour == 24) { now.hour = 0; } } } return now; }
|
嵌套结构(禁止套娃!)
既然结构内可以是不同类型的数据,那么也可以是结构类型的数据
1 2 3 4
| struct aAndb{ struct a dataa; struct b datab; };
|
空间想象力太差了,告辞
复用的时候看作文件夹与快捷键就行
![06-10_22:25](https://cdn.jsdelivr.net/gh/zhboat/cdn_pic@master/upic/2020/06-10_22:25.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <stdio.h>
struct point { int x; int y; };
struct rectangle { struct point p1; struct point p2; };
void printRect(struct rectangle r) { printf("<%d,%d> to <%d,%d>\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y); }
int main() { struct rectangle rects[] = {
{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}} }; for (int i = 0; i < 2; i++) { printRect(rects[i]); } return 0; }
|
TypeDef
使用typedef可以自定义数据类型的名称,让其变成新的别名
复杂的名字化繁为简,重载已有的类型名称,新名称的含义更清晰更具有移植性
还能够替代数据类型出现在变量定于和参数声明
使用typedef最后的单词就是该类型的新名称
1 2 3
| typedef int abc; abc a,b,c; abc number[5];
|
1 2 3 4 5 6 7
| typedef struct student { int studentID; char *name; char *sex; int age; }aaa; aaa zhangsan = {111,"zhangsan","nan",17};
|
union(联合)
联合是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型
可以定义一个带有多成员的联合体,但是任何时候只能有一个成员带有值,联合体提供了一种使用相同的内存位置的有效方式
它的语法和结构一样,但是每个成员是共享一个空间
而且同一时间只有一个成员是有效的,union整体的空间大小就是最大的那个成员
所以你不能同时输出联合体中的所有成员的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <stdio.h> #include <string.h>
union Data { int i; float f; char str[20]; };
int main() { union Data data;
data.i = 10; printf("data.i : %d\n", data.i);
data.f = 220.5; printf("data.f : %f\n", data.f);
strcpy(data.str, "Hello,World"); printf("data.str : %s\n", data.str);
return 0; }
|