C语言学习(十七)全局变量 宏定义

1.全局变量
①全局变量的定义与性质

定义在函数外面的变量是全局变量,全局变量具有全局的生存期和作用域,它们与任何函数都无关,在任何函数内部都可以使用它们。

例1:全局变量

#include<stdio.h>

int f(void);

int g=12;    //定义全局变量
int main(int argc, char const *argv[])
{
    printf("g=%d\n",g);
	f();      //函数调用
	printf("g=%d\n",g);
	return 0;
}

int f(void)
{
    g+=2;
	printf("g=%d\n",g);
	return g;
}

运行结果
在这里插入图片描述

②全局变量初始化
如果没有做初始化,全局变量会得到0值,这点与本地变量不同;
如果是指针的话会得到NULL值;
只能用编译时刻已知的值来初始化全局变量(int g1=12; int g2=g1; 这种定义是错误的);
它们的初始化发生在main函数之前。

③被隐藏的全局变量
如果在函数内部存在与全局变量同名的变量,全局变量会被隐藏。
也就是说在更小的范围内定义了一个同名的变量,则全局变量就会被隐藏。

④静态本地变量
在本地变量定义时加上static修饰符就成为静态本地变量;当函数离开的时候,静态本地变量会继续存在并保持其值;静态本地变量的初始化只会在第一次进入这个函数时做,以后进入函数时会保持上次离开时候的值。

静态本地变量实际上是特殊的全局变量,它们位于相同的内存区域。

静态本地变量具有全局的生存期,函数内的局部作用域,static在这里的意思是局部作用域(本地可访问)。

例2:静态本地变量

int f(void);

int main(int argc, char const *argv[])
{
	f();      
	f();
	f();
	return 0;
}

int f(void)
{
    int all = 1;
	printf("all=%d\n",all);
    all +=2;
	printf("agn all=%d\n",all);
	return all;
}

这里的all是一般的本地变量,程序运行结果为:
在这里插入图片描述
如果对上面程序进行修改,将all改成静态本地变量,语句如下:

static int all = 1;

程序运行结果为:
在这里插入图片描述

2. 编译预处理和宏

①编译预处理指令
#开头的是编译预处理指令,它们不是C语言的成分,但是C语言程序离不开它。
#define用来定义一个宏。

例3:宏

#include<stdio.h>
#define PI 3.14159

int main(int argc, char const *argv[])
{
	printf("%f\n",PI);
	return 0;
}

②宏定义
#define <名字> <值>
注意没有结尾的分号,因为它不是C语言的语句,名字必须是一个单词,值可以是各种东西。
在C语言的编译器开始编译之前,编译预处理程序会将程序中的名字换成值,是完全的文本替换。

③宏的性质
如果一个宏的值中有其他的宏的名字,也是会被替换的;
如果一个宏的值超过一行,最后一行之前的行末要加“\”;
宏的值后面出现的注释不会被当做宏的值的一部分。

   #define PI 3.14159
    #define PI2 2*PI  //2*PI
    #define PRT printf(”%f”,PI);\
               printf(“%f\n”,PI2)

上面的PI2中的PI会被替换,注释的内容不影响程序,但是如果直接用空格是不可以的。

④预定义的宏
LINE 表示源代码当前位置的行号
FILE 表示文件名
DATE 表示编译时候的日期
TIME 表示编译时候的时间
STDC

printf("%s:%d\n",FILE,LINE);
printf("%s:%d\n",DATE,TIME)

⑤带参数的宏
例4:像函数的宏

#include<stdio.h>
#define cube(x)((x)*(x)*(x))

int main(int argc, char const *argv[])
{
	int i=5;
	printf("%d\n",cube(i)); //((i)*(i)*(i))
	return 0;
}

错误定义的宏:

#define G1(x) (x*57.22)
#define G2(x) (x)*57.22

G1I(5+2)会变成5+257.22而不是(5+2)57.22
100/G2(1)会变成100/1
57.22而不是100/(1
57.22)

所以我们写带参数的宏的时候一定要记得加括号,最外面要加括号,参数也要加括号。

带参数的宏矿业带多个参数:

#define MIN(a,b)((a)>(b)?(b):(a))

另外,带参数的宏也可以嵌套使用。

猜你喜欢

转载自blog.csdn.net/qq_33523925/article/details/87885182
今日推荐