C语言第19天,标识符作用域和预处理指令

一、标识符作用域

1.代码块作用域

{//代码块A

xxxxxxxxxxx

xxxxxxxxxxx

xxxxxxxxxxx}

{//代码块B

xxxxxxxxxx

xxxxxxxxxx

xxxxxxxxxx}

源代码中,被花括号包括的代码,形成一个代码块

 

例题: #include<stdio.h>

void func()

{int n;

n=100;

printf("n in func%d\n",n);}

int main()

{int n=0;

printf("n in main%d\n",n);

func();//在这个代码块中没有定义

printf("n in main%d\n",n);

return 0;}

结果为n in func=100

n in main=0

n in main=0

 

2.平级代码块

互不干扰


3.上下级代码块

b在a'的作用域中,使用a的参数

 

但如果下级b中有定义n,那b的作用域将覆盖a,在b中使用b的参数,b外使用a的参数

 

4.带括号的块作用域

 void func(int p)

{

printf("p=%d\n",p);

}

int p定义在函数括号内,使用函数的花括号范围内都有p的定义

除了函数可以形成带括号的块作用域,if、while、for也可以形成带括号的块作用域

 

5.文件作用域

 

 若在花括号外声明,那么声明后的所有花括号内都有其定义

 
二、预处理指令
1.符号常量
符号常量在变量与常量那一节中,我们学习过一个叫做符号常量的知识点。
使用#define指令,将一个值使用一个符号替代。
定义符号常量的公式:# define 符号常量 值
例题:#include<stdio.h>
#define PRICE 3//商品的价格为3元
int main()
{int num;
int total=0;
//买一件
num=1;
total=num*PRICE;
printf("num:%d total:%d\n",num,total);
//买两件
num=2;
total=num*PRICE;
printf("num:%d total:%d\n",num,total);
//买三件
num=3;
total=num*PRICE;
printf("num:%d total:%d\n",num,total);
return 0;
若商品涨价为4元每件,仅需要修改符号常量PRICE为4,整个程序中所有用到的PRICE均变为4了。
 
2.预处理指令
源代码中,以井号#开头的并不是C语言中的语句。它们属于预处理指令。
预处理指令#define的用法其实非常丰富,前面我们仅使用它定义了一些符号常量。现在,我们来了解它的完整的使用公式。
#define宏替换体一旦预处理在程序中找到宏后,就会用替换体替换该宏。
 
3.带参数的#define
在#define中使用参数可以创建外形和作用与函数类似的宏函数。
宏函数的使用公式如下:#define  宏(参数1,参数2,...,参数n)  替换体
例题:用于求a,b两个数的平均值
#define MEAN(a,b) (a+b)/2
在程序中,可以这样使用它。
int result;
result=MEAN(2,4);
经过预处理后,宏被替换为如下的形式:
int result;result=(2+4)/2
虽然由带参数的#define定义的宏函数,在使用方法上很像函数。但是,请再次注意,它的本质依然是将宏替换为对应的替换体。
由此,如果简单地将其当做函数使用,会出现一些问题。
比如宏函数会遵循运算法则,不会像函数一样运算完之后,再将结果代入式子,导致宏函数中的数值先于宏函数外的数值运算。
例如:#define add(a,b) a+b
int result;
int a=6;
int b=5
result=5×add(a,b)×9
结果为5×6+5×9=75,不是我们想象中函数的5×11×9=495,所以运用时注意括号的添加#define add(a,b) (a+b)
 

4.宏函数内两个有用运算符
①井号#
会使得替换体内的number被双引号包括,成为了一个字符串。
#include<stdio.h>
#define FMT(varname)  "The value of" #varname "is %d\n"
int main()
{int number=123;
printf(FMT(number),number);
return 0;}
 
结果为The value of number is 123
//首先varname为一个变量,它会进行变化,如果没有#,那么结果中缺少双引号的number会被认作为一个变量,不符合printf第一个参数需要字符串的写法。无法编译通过
然后,在C语言中,相邻的字符串会被自动连接成一个完整的字符串。"The value of" "number" "is%d\n"等价于"The value of number is %d\n"
 
②双井号##
双井号可以将替换体中的两个记号组合成一个记号。
#define VARNAME(group,name) group##name
VARNAME(group1,Apple)展开为group1Apple。
VARNAME(group1,Orange)展开为group1Orange。
VARNAME(group2,Apple)展开为group2Apple。
VARNAME(group2,Orange)展开为group2Orange。
意义与#类似
 
5.取消宏定义
可以使用预处理指令#undef,取消这个宏的定义,再重新定义它。
#include<stdio.h>
#define NUM 100//取消宏定义NUM
#undef NUM//重新定义宏NUM为101
#define NUM 101
int main()
{printf("%d\n",NUM);
return 0;}
 
posted @ 2022-09-28 18:40  纯爱暴打ntr  阅读(167)  评论(0)    收藏  举报