1.枚举
枚举是一种用户定义的数据类型,它用关键字enum以如下语法来表明:
enum 枚举类型名字{名字0,……,名字n};
枚举类型的名字通常并不使用,要用的是大括号里的名字,它们是常量符号,
他们的类型是int,值则依次从0到n。如:`enum colors{red,yellow,green};`
就是指创建了三个常量,red值为0,greed值为2。
2.枚举量
- 枚举量可以作为值
- 枚举类型可以跟上enum作为类型,但实际以整数计算和输入输出
- 声明枚举量的时候可以指定值:
- enum COLOR{RED=1,YELLOW,GREEN=5};
- red值为1,则yellow值为2,green值指定为5。
3.声明结构类型
struct date{
int month;
int year;
}; //这个分号最容易忘记
struct date today; //给这个结构取个名字
today.month = 05; //给结构中的某个变量赋值
printf("Today's month is %i.\n",today.month);
- 和本地变量一样,在函数内部声明的结构类型只能在函数内部使用,
- 所以通常在函数外部声明结构类型,以便可以被多个函数使用。
- 结构的初始化:
- struct data {int month; int day; int year};
- struct date today = {05,27,2020};
- 按顺序指定赋值
- struct date thismonth = {.month=5, .year=2020};
- 没有给day赋值,默认为0。
4.声明结构的形式
// 1.p1和2都是point,里面有x和y的值。
struct point{
int x;
int y;
};
struct point p1,p2;
// 2.p1和p2都是一种无名结构,里面有x和y。
struct {
int x;
int y;
} p1,p2;
// 3.p1和p2都是point,里面有x和y的值。 (最常见)
struct point{
int x;
int y;
} p1,p2;
// 对于第一和第三种形式,都声明了结构point。
// 但是第二种形式没有声明结构point,只定义了两个变量。
5.结构运算
- 要访问整个结构,直接用结构变量的名字。
- 可以对结构做:赋值、取地址、也可以传递给函数参数。
- 数组无法做以下这种运算,结构可以:
p1=(struct point){5,10};相当于p1.x=5; p2.y=10;p1 = p2;相当于p1.x=p2.x; p1.y=p2.y;
6.结构指针
和数组不同,结构变量的名字并不是结构变量的地址,所以必须
使用&运算符获取地址:`struct date *pDate = &today;`
7.结构作为函数参数
int numberOfDays(struct data d)
- 整个结构可以作为参数的值传入函数;
- 这时在函数内新建一个结构变量,并复制调用者的结构的值;
- 也可以返回一个结构,这些与数组完全不同。
8.输入输出结构
我们将一个结构传入了函数,然后在函数中操作,但是没有返回;
传入结构和传入数组是不同的,它传入的是外面那个结构的克隆体,而不是指针。
所以我们可以创建一个临时变量,然后把这个结构返回给调用者。
9.结构指针作为参数
struct data {
int month;
int day;
} myday;
struct data *p = &myday;
(*p).month = 12; //符号较多,简写为下一行
p->month = 12; //读作arrow,p所指的month
10.结构数组
可以自定义结构的类型。
struct time testTimes[3] = {{8,27,25},{11,0,0},{5,12,34}};
11.嵌套的结构
strcut rectangle {
struct point pt1;
struct point pt2;
};
如果定义这样一个变量:
struct rectangle r,*rp;
rp = &r;
则下面这四种形式是等价的:
r.pt1.x (r.pt1).x rp->pt1.x (rp->pt1).x
但是没有rp->pt1->x,(因为pt1不是指针)。
12.自定义数据类型(typedef)
C提供typedef的功能来声明一个已有的数据类型的新名字,
比如`typedef int Length`,使得Length成为int类型的别名。
这样,Length可以代替int出现在变量定义和参数声明啦。
`Length a,b,len;`,`Length numbers[10];`。
主要用于给复杂的struct定出名字。
typedef struct{
int day;
int year;
} data;
最后面的data是这个结构的名字。
13.联合(union)
- 存储
- 所有成员共享一个空间,
- 同一时间只有一个成员是有效的,
- union的大小是其最大的成员
- 初始化
- 对第一个成员做初始化
14.全局变量
- 与任何函数都无关,可以在任何函数内部使用。
printf("in fun %s name=%d\n",__func__,gWord);
这个字符串__func__表示当前函数的名字,即main。- 没有初始化会得到0值,指针会得到NULL值。
- 只能用编译时已知的值来初始化全局变量。
- 它们的初始化发生在main函数之前。
- 如果函数内部存在和全局变量同名的变量,全局变量会被隐藏。
15.静态本地变量
- 在本地变量定义时加上static修饰符即可。
- 当函数离开时,静态本地变量会继续存在并保持其值。
- 其初始化只会在第一次进入这个函数时做,以后会保持上次离开时的值。
- 静态本地变量实际上是特殊的全局变量,(它们位于同样的内存区域)。
- 具有全局的生存期,局部的作用域。
16.宏定义
- #开头的是编译预处理指令。
- 它们不是C语言成分,但是C语言程序离不开它们。
- #define用来定义一个宏。
17.#define
#define <名字> <值>- 注意没有结尾的分号,因为不是C的语句。
- 宏超过一行,最后需要加\。
- 名字必须是一个单词,值可以是各种东西。
- 在开始编译前,预处理会把程序中的名字换成值。
- 完全的文本替换。
- 使用参数:gcc --save-temps (将产生的临时文件保存下来)
18.没有值的宏
#define _DEBUG
这类宏用于条件编译,后面又其他的编译预处理指令来检
查这个宏是否已经被定义过了。
19.预定义的宏
__LINE__%d 所在行数__FILE__%s 所在文件的全路径__DATE__%s 日期__TIME__%s 时间__STDC__判断是否为标准C程序
20.带参数的宏
-
基本原则:一切都要括号
- 整个值要括号。
- 参数出现的每个地方都要括号。
- 前往不要加分号。
-
可以带多个参数、求出较小值:
- #define MIN(a,b) ((a)>(b) ? (b):(a))

1112

被折叠的 条评论
为什么被折叠?



