c语言----变量和预处理
c语言----变量和预处理
c语言----变量和预处理 全局变量 全局变量初始化 静态本地变量 *返回指针的函数 小贴士 编译预处理指令 宏 #define 没有值的宏 预定义宏 带参数的宏 带参数宏的原则 #include后面到底使用“”还是<>?声明
全局变量
-
定义在函数外边的变量是全局变量 -
全局变量具有全局的生存期和作用域 -
他们和任何函数都无关 -
在任何函数都可以使用它
全局变量初始化
-
没有做初始化的全局变量会得到0值 -
指针会得到NULL -
只能用编译时刻已知的值来初始化全局变量 -
它们的初始化在main主函数发生前完成
如果函数内部存在与全局变量同名的变量,则全局变量会被隐藏(优先使用局部变量)
静态本地变量
-
在本地变量定义时加上 static
修饰符就会变成静态本地变量 -
当函数离开的时候,静态本地变量会继续存在并保持其值 -
静态本地变量的初始化只会在第一次进入这个函数时做,,以后进入这个函数会保持上次离开的值
#include"stdio.h"
int f();
int i=0;
void main()
{
for(i=0;i<10;i++)
f();
}
int f()
{
static int a=0;
printf("%d次调用a的值%d\n",i,a);
a+=2;
return a;
}
结果:
如果a
不是静态变量(static int a=0
变为int a
)
结果:
实际上静态本地变量就是特殊的全局变量。但是作用域只能在定义它的函数内部
*返回指针的函数
-
返回本地变量是危险的。因为一旦子函数完成运算,其里面的本地变量的地址空间会被收回,然后分配给后续函数使用 -
返回全局变量或者静态本地变量的地址是安全的 -
返回在函数内的malloc的内存是安全的,但容易造成问题 -
最好的做法是返回传入的指针
## 小贴士
-
不要使用全局变量在函数间传递参数和结果 -
尽量避免使用全局变量
编译预处理指令
-
#开头的就是编译预处理指令 -
他们不是c语言的成分,但是c语言程序离不开他们
宏
#define
-
用法: #define <名字> <值>
-
注意:没有结尾的分号,因为不是c语句 -
名字必须是一个单词,值可以是各种东西 -
c语言在编译器编译之前,编译预处理程序会打程序中的名字全部换为值
什么叫做宏呢?
按照上面定义出来的东西叫做宏
-
如果一个宏的值中有其他宏的名字,也是会被替换的 -
如果一个宏的值超过一行,最后一行之前的行末尾加\ -
宏的值后面出现的注释不会当成宏的一部分
#include"stdio.h"
#define PI 3.141596
#define PI_1 2*PI //宏中带宏
#define PRT printf("PI=%f\n",PI);\ //定义多行宏
printf("2*PI=%f\n",PI_1);
void main()
{
PRT
}
结果:
没有值的宏
#define _DEBUG
这类宏是用来条件编译的,后面的其他预处理指令来检查这个宏是否已经被定义了
预定义宏
宏 | 描 述 |
---|---|
DATE | 源文件的编泽口期,用 “Mmm dd yyy”形式的字符串常量表示 |
FILE | 当前源文件的名称,用字符串常量表示 |
LINE | 当前源文件中的行号,用十进制整数常量表示,它可以随#line指令改变 |
TIME | 当前源文件的最新编译吋间,用“hh:mm:ss”形式的宁符串常量表示 |
STDC | 如果今前编泽器符合ISO标准,那么该宏的值为1,否则未定义 |
带参数的宏
#include"stdio.h"
#define cube(x) (x)*(x)*(x)//括号尽量不要少
void main()
{
printf("%d\n",cube(5+5)); //宏定义中的x用5+5代替
}
带参数宏的原则
一切要有括号:整个值要有括号,参数出现的每一个地方都要括号
#define cube(x) ((x)*3.14*3.14) //正确使用
#define cube(x) (x)*3.14*3.14 //错误使用
#define cube(x) (x*3.14*3.14) //错误使用
可以带有多个参数,也可以嵌套使用
#define min(a,b) ((a)>(b)?(a):(b))
注意:使用宏不能加分号,因为我们一般在定义宏时就加了分号
-
在大型程序的代码中使用普遍 -
可以非常复杂,如“产生”函数 -
部分宏会被 inline
函数代替
#include后面到底使用“”还是<>?
""要求编译器首先在当前目录(.c所在的目录)找寻这个文件,如果没有就在编译器指定的目录去找
<>让编译器只在指定目录下找
编译器自己知道自己的标准库的头文件在哪里
一般的做法就是任何.c都有和它同名的.h,把所有的对外公开的函数原型和全局变量的声明都放进去
声明
怎么声明一个全局变量,使其在各个.c文件被使用?
extern int a
//声明一个全局变量(不能初始化)
int a
//定义一个变量
怎么保证.h文件只被编译一次?
我们知道所有变量只能被编译一次的。当变量被定义在.h中,当多次调用这个.h文件。在编译时会多次编译
//标准头文件结构
#ifndef _MAX_H_ //如果没有定义_MAX_这个宏的话,就定义这个宏,如果存在直接跳到endif
#define _MAX_H_
#endif