1.全局变量
定义在函数外部的变量叫做全局变量
全局变量具有全局的生存周期,作用域从声明他开始到末尾
没有初始化的全局变量会得到0值,指针会得到NULL值(本地变量不会给初值,保存的是内存中原有的值)
全局变量的初始化只能用编译时已知的值来初始化(只有常数,和常量const(不建议) 可以用来给它赋值)
如果函数内部存在和全局变量同名的本地变量,全局变量会被隐藏
2.静态本地变量 static 关键字
用static修饰的本地变量是静态本地变量(也可以修饰全局变量,但是加不加没卵用)
当函数执行结束离开时,函数内部的静态本地变量会继续保持其值
静态本地变量的初始化只会在第一次进入这个函数的时候做,以后进入这个函数的时候会保持上次离开的值
void fun(){
static int x=10; //只做一次
x++; //每次调用都执行,因此调用n次之后x值时10+n而不是11
}
静态本地变量的本质是全局变量,它和全局变量保存在相同的内存区域中,static关键字实质只是限制这个全局变量的范围为这个函数内
3.返回指针的函数
返回本地变量的指针是危险的,因为一旦函数结束,这块地址就相当于回收了,这个地址可能之后会被分配给其他变量
返回全局、静态本地变量、malloc的地址是安全的,最好的做法是返回传入的指针
4.使用全局变量tips
不要使用全局变量来在函数间传递参数或者作为返回结果
尽量避免使用全局变量
全局变量和静态本地变量对于多线程的环境是不安全的
5.编译预处理指令和宏
#开头的是编译预处理指令,他们不是C语言的部分,但是C语言离不开他们
#define 用来定义一个宏(c99以前没有const,只能用define来定义常量)
例:#define PI 3.1415 在编译器预处理的时候,会把程序中所有的PI换成3.1415
编译预处理
.c->.i->.s->.o->可执行文件
其中.c是源文件,.i是编译预处理后的文件,.s是汇编程序,.o是目标文件
可以用宏来定义宏
例如:#define PI2 2*PI
一行宏的定义没结束可以在末尾加一个反斜杠\
除了可以定义有值的宏,还可以定义没有值的宏,这类宏是用于条件编译的
预定义宏:
_LINE_ 源代码当前的行号
_FILE_ 源代码文件的文件名
_DATE_ 编译时候的日期
_TIME_ 编译时候的时间
6.带参数的宏
像函数一样的宏
例如 #define cube(x) x*x*x
之后在程序中 cube(5) 会表示5*5*5
错误定义的宏
#define RADTODEG(x) (x*57.29578) //printf("%f\n",RADTODEG(5+2))表示printf("%f\n",(5+2*57.29578) //从而导致2先乘以57.29578
#define RADTODEG(x) (x)*57.29578 //printf("%f\n",180/RADTODEG(1))表示printf("%f\n",180/(1)*57.29578) //导致180先/1
带参数宏的原则:一切都要有括号
a.整个值要有括号
b.参数出现的每个地方都要有括号
#define RADTODEG(x) ((x)*57.29578) //正确
宏可以带多个参数
#define MIN(a,b) ((a)>(b)?(b):(a))
宏可以嵌套组合使用其他宏
宏后面不要加分号
带参数的宏在大型程序代码中使用非常普遍,可以非常复杂,例如产生函数
7.大程序结构
原文:https://www.cnblogs.com/foodie-nils/p/13611397.html