全局变量和宏
先说全局变量:
全局变量是定义在函数外部的变量,与任何函数没有任何关系。在所有的函数都可以访问全局变量,它的作用于是整个程序。这里需要注意一个区别:本地变量在未初始化的时候它的值是随机的,但是全局变量会得到一个0值,指针的话会得到一个NULL。同时全局变量在被赋值的时候不可以被赋一个变量,哪怕是之前的全局变量。比如:
include <stdio.h> int n=12; int m=n; //系统就会报错 int main() { .....
但是如果我们把这个变量声明为const呢?就会发现可以通过了。但注意,必须是按照如下的顺序:
include <stdio.h> const int n=12; int m=n; //right int main() { ....... include <stdio.h> int m=n; //wrong const int n=12; int main() { ......
其实在C语言中还有一种和全局变量很类似的东西叫做静态局部变量:关键字static。
它的特性是在函数结束后会继续存在并保留其值,也就是生命周期和全局变量相同,它的初始化只能在最开始第一次进入函数的过程中进行。但是静态局部变量有一个地方和全局变量不同就是它只能在局部函数的作用域内访问,不能在其它函数访问。
综上在一个函数中我们返回的如果是一个全局变量或者静态局部变量的地址是安全的。但是在多线程条件使用全局变量和静态局部变量是很不安全的。
接下来再来看看宏:
#define N 某些值
C语言中其实是把源代码中N这个符号文本替换为数值(注意只是文本替换,所以不会进行编译检查)。这里的值不只是数值可以是表达式甚至是注释,更有甚者可以是多行的宏。
#define PI 3.14 \ E 2.79
C语言中还有一些预定义的宏比如:_LINE_(代表源代码行号),_FILE_(代表文件名)等等。
当然宏还可以定义为函数的形式,也就是宏可以被定义为带参数。
#include <stdio.h> #define cube(x) ((x)*(x)*(x)) int main() { printf("%d",cube(5)); return 0; }
然后我们就可以得到125.但是我们需要小心的是这种带参数的宏一定都要加括号。整个值要加括号,各个参数也要加括号,因为宏替换只是一种文本替换。所以为了避免错误,一定要在各个参数加括号。
再来一个例子(带多个参数的宏):
#define MAX(a,b) ((a)>(b)?(a):(b)) //选出最大值
当然宏还可以是嵌套的。
宏的使用主要是因为可以节省时间的开销,省去了调用函数的时间。但是因为它不会进行类型检查所以C以及C++语言中后来会用inline函数来代替部分宏。
最后可以看下这个例子:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define TOUPPER(c) ('a'<=(c)&&(c)<='z'?(c)-'a'+'A':(c)) int main() { char s[100]; strcpy(s, "abcd"); int i = 0; putchar(TOUPPER(s[++i])); }
输出的是:D.