前要:本笔记为初学者上b站翁恺C语言P99-P102所得笔记。包括枚举和结构的内容。
注意:笔记中绝大多数内容都与翁恺C语言P99之前的数组、函数、指针等内容有连接,所以没学过那里的可能看不懂。
目录
11.1.1枚举
一.引:
常量符号化:用符号而非具体的数字来表示程序中的常量,便于人理解。而若我有很多常量要符号化(或言const int过多)时,太麻烦了?
二.def(意为definiton 定义,下沿用):一种用户定义的数据类型,用关键字enum(enumeration 枚举的缩写)来声明.(也就是说这个过程叫声明类型)
eg. enum 枚举类型名字{名字0,.…名字n};
注:
1.这些常量类型均是int,值自动被赋依次从0—n.(注意是从0开始,这里的n也并非项数,而是项数-1)
eg. enum colors{red,yellow,green};
此时即创建了三个常量,red值自动被赋0,yellow自动被赋1,green自动被赋2
2.然而,声明变量时也可以指定值
eg. enum colors{red=1,yellow,green=5};
这里的yellow就会顺着1变2,那此时3,4就会被跳过,green是5。
3.枚举类型名字本身通常并不真正使用,要用的是{}里的名字,因为它们就是常量符号。
4.用处:当需要一些可以排列起来的常量值时,定义枚举的就是给这些常量名字,方便人理解,也比暴力const int 简洁。
同时, 这相当于人造一种类型,这是先前没有的。
5.枚举量可以作值,从本质上,是以整数来用的。
三.一个技巧
自动计数的枚举:
在赋值不被干扰的情况下(也即是从0-n),最后一项的值正好等于其前面枚举量的数目,这样需要遍历所有枚举量或需建立一个用枚举量做下标的数组时就很方便了。(也就是说在最后加一个量,就可以方便遍历了)
#include<stdio.h>
enum COLOR {RED,YELLOW,GREEN,NUMCOLORS};
int main()
{
int color =-1;
char *ColorNames[NUMCOLORS]={
"red","yellow","green",};
char*colorName=NULL;
printf("输入你喜欢的颜色的代码:");
scanf("%d",&color);
if (color>=0&&color <NUMCOLORS){
colorName =ColorNames[color];
}else {
colorName ="unkown";
}
printf("你喜欢的颜色是%s\n",colorName);
}
这里的NUMCOLORS(计数君)前面是<而非<=
四.一些额外的话
1.枚举类型虽可以作为类型使用,但实际上很(bu)少(hao)使用.(了解)
2.枚举比宏(macro)好,因为枚举有int 类型。
总结可得,枚举常用于多常量定义,而非作类型。
11.2.1结构类型
一.声明结构类型:(也是人为定义一个类型)
struct date{
int month;
int day;
int year;
};
强调初学者激起容易漏掉这个最后的 ; ,这个是一个语句,而并非函数。
注:此声明放在哪里:若放在函数内,那就和本地变量一样,只能在内部使用。
所以通常在函数外部声明,这样可以被多个函数所使用。(明确,这个并非函数,变量在对应情况有意义。)
二.声明结构的三种形式
a.
struct point {
int x;
int y;
};
struct point p1,p2;
这里p1,p2都是point 里面有x,y的值;
b.
struct {
int x;
int y;
}point p1,p2;
p1,p2都是无名结构,里面有x,y的值;
c.
struct point {
int x;
int y;
} p1,p2;
p1,p2都是point ,里面有x,y
那么如何选择呢?
第一第三均可,第三更简洁,第二无名不太好。
三.初始化
struct date today={07,31,2014};
struct date this month={.month=7,.year=2014};;
初始化类似数组,不给值自动填0;
注意:结构变量类型(int,double…)不一定相等,而数组一定相等。
想必大家也注意到了结构类型和枚举类型的相似,区分一会再讲。(( ͡° ͜ʖ ͡°)✧)
四.结构成员
结构成员就是指里面的成员
其中数组用 [] 运算符和下标来访问其成员 如a[0]=10;
而结构用 . 运算符和名字来访问 如today.day 或student.firstname
五.结构计算
欲访问整个结构,可作赋值、取地址(注意是取,不是当),也可以传递给函数参数。
p1={5,10};//此意为pl.x=5;pl.y=10;
而与数组不同的是,结构之间可以互相直接赋值。
p1=p2;//p1.x=p2.x;p1.y=p2.y;
六.结构指针
和数组不同,结构变量名字并非结构变量的地址,必须用&运算符。
eg.
struct date *ptoday=&today//这里指针名字不限制,但用原来所指方便理解。
七.关于枚举类型和结构类型的异同
同:两者均为一种类型
异:
1.枚举的类型均int,而结构则不一定。
2.初始化时枚举自动从0到n,结构不初始化则全0;
3.结构的成员需要结构类型名字加 . 加名字 来调用 而,枚举直接用名字就行。
11.2.2结构和函数
一.结构传入时
在函数中,不同于数组作为一个指针的是,结构作为参数时,整个结构虽然可以作为参数值传入函数,但它是函数中新建一个结构变量,并复制调用其传入结构的值。本质上和传一个普通变量的效果类似,相当于传了个克隆体进去。
eg.int numberofdays(struct date d)
二.函数返回时
同时,函数也可以返回一个结构。
eg.struct date numberofdays(struct date d)
那么,如何在函数中输入一个结构呢?
我们是没有办法直接一次性scanf一整个结构的,那用以下两个办法是可以的:
1.内部设了结构再输出(意思就是里面设一个结构接受值再去输出它 比较麻烦不推荐)
2.结构指针作为参数
eg.
当struct date *p=&today;
(*p).month=12; 等价于 p->month=12;
这里用->(一个减号一个大于号)表示指针所指结构变量的成员,
也就是说(*p)效果等同于p->
11.3结构中的结构
一.嵌套的结构
eg.
以下四者等价(注意看.的位置)
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
解释:
结构可以套结构。
又因为 . 是从左往右计算,所以有无括号结果一样。
二,结构中的数组
eg.
struct date dates[100];
struct date dates[]={{4,5,2005},{2,4,2005}};
逐层拆括号理解即可,外圈为结构,结构里面是数组。
三.结构中的结构中的数组
eg.struct rectangle rects[]={{{1,2},{3,4},{5,6},{7,8}}};
同上,逐层分析即可。