无题
全局变量
- 定义在函数外面的变量就是全局变量
- 全局变量具有全局的生存期和作用域
- 它们与任何函数都没有关系,但是在任何函数的内部都可以使用它们
- 全局变量默认初始化值是0,指针变量会得到NULL值
- 只能用已知的值去初始化全局变量,因为它们的初始化在Main函数之前
- 如果函数内部存在与全局变量同名的变量,那么全局变量会被覆盖
静态本地变量
- 在本地变量定义时加上static修饰符就能成为静态本地变量
- 当函数离开的时候,静态本地变量会继续存在并保持其值
- 静态本地变量的初始化只会在第一次进入这个函数的时候做,以后进入函数时会保持上次离开时候的值
- static是特殊的全局变量,与全局变量在内存的同一块地址,具有全局生存期,但只有局部作用域
宏
以#开头的是编译预处理指令,不是C语言自带的东西
使用
#define
定义宏,#define <名称> <值>
在编译前通过完整的文本替换方式将名称替换对应的值
宏可以嵌套使用,超过一行的值需要在行末加上\
在值中写注释不会被当作值的一部分
还有一些预定义的宏
宏 | 描述 |
---|---|
_LINE_ | 这会包含当前行号,一个十进制常量。 |
_FILE_ | 这会包含当前文件名,一个字符串常量。 |
_TIME_ | 当前时间,一个以 “HH:MM:SS” 格式表示的字符常量。 |
_DATE_ | 当前日期,一个以 “MMM DD YYYY” 格式表示的字符常量。 |
_STDC_ | 当编译器以 ANSI 标准编译时,则定义为 1。 |
1 |
|
带参数的宏
可以像函数一样使用,将未来的参数传递到预处理指令中
格式
#define <名称(参数)> <值>
在其他函数中调用#define的名称加()时传递的值会回到#define中
使用参数的时候,整个值需要加上括号,每个使用参数的地方也需要加上括号
可以嵌套组合使用,也可以带上多个参数
#define MIN(a,b) ((a)>(b)?(b):(a))
判断两个数中最小的值,如果a大于b,则最小数就是b,否则就是a
1 |
|
#&##
字符串常量化运算符(#)
在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。在宏中使用的该运算符有一个特定的参数或参数列表
标记粘贴运算符(##)
宏定义内的标记粘贴运算符(##)会合并两个参数。它允许在宏定义中两个独立的标记被合并为一个标记
头文件
头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。
把函数原型放到一个头文件(以.h结尾)中,在需要调用这个函数的源代码文件(.c)中#include这个头文件,就能让编译器在编译的时候知道函数的原型
#include
与宏一样,#include也是一个编译预处理指令,在编译之前就处理好了
它的作用是把头文件中的全部文本原封不动得插入到#include所在的位置
#include ""
要求编译器首先在当前目录寻找头文件,如果没有就去其他地方寻找,#include <>
用于引用系统头文件,在系统目录的标准列表中搜索在使用和定义函数的地方都应该有
#include 头文件
,任何源文件除了main函数都应该有对应的同名头文件,把所有对外公开的函数的原型和全局变量的声明都放进去
不对外公开的函数
- 在函数前面加上static就能让他成为只能在所在的源代码中才能被使用的函数
声明
对于变量的声明,格式:
extern 变量类型 变量名
函数原型
变量声明
结构声明
宏声明
枚举声明
类型声明
…等,这些声明都是不产生代码,只有在定义的时候才产生代码
重复声明
如果头文件中有结构的声明,那么很可能会在同一个源代码中被#include很多次,为了避免这种情况的发生,需要用到标准头文件结构
标准的做法是把文件的整个内容放在条件编译语句中
1
2
3
4
5
声明
...1
2
3
4
5
6
7
struct point {
int x;
int y;
};