C语言系列-预定义符号&#define定义宏&#define定义宏

 个人主页: 会编辑的果子君

个人格言:“成为自己未来的主人~”  

目录

预定义符号

#define定义常量

#define定义宏


预定义符号

C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。

__FILE__   //进行编译的源文件
	__LINE__   //文件当前的行号
	__DATE__   //文件被编译的日期
	__TIME__   //文件被编译的时间
	__STDC__   //如果编译器遵循ANSIC,其值为1,否则未定义

举个例子:

 

#include
int main()
{
	//__FILE__   //进行编译的源文件
	//__LINE__   //文件当前的行号
	//__DATE__   //文件被编译的日期
	//__TIME__   //文件被编译的时间
	//__STDC__   //如果编译器遵循ANSIC,其值为1,否则未定义

	printf("%d,%s", __LINE__, __DATE__);
	return 0;
}

#define定义常量

基本语法:

#define name stuff

举个例子:

 

#define name stuff
#define MAX 100
#define reg register
#define forever for(;;)
#define case break;case
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
		 date:%s\ttime:%s\n" ,\
		 __FILE__,__LINE__ 

 思考:在define定义标识符的时候,要不要在最后加上;?

例如:

#define MAX 100;
#define MAX 100

建议不要加上;,这样容易导致问题

比如下面的场景:

if (condition)
max = MAX;
else
max = 0;

如果是加了分号的情况,等替换后,if 和 else之间就是2条语句,而没有大括号的时候,if后边只能有一条语句,这里会出现语法错误

#define定义宏

#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)

下面是宏的申明方式:

#define name( parament-list) stuff

其中的parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中

注意:

参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分

举例:

#define SQUARE(x) x*x

这个宏接收一个参数x,如果在上述声明之后,你把SQUARE(5); 置于程序中,预处理器就会用下面这个表达式替换上面的表达式:5*5

警告:

这个宏存在一个问题:

观察下面的代码段:

#define SQUARE(x) x*x
#include
int main()
{
	int a = 5;
	printf("%d\n", SQUARE(a + 1));


	return 0;
}

乍一看,你可能觉得这段代码将打印36,事实上它将打印11,为什么呢?

替换文本时,参数x被替换成a+1,所以这条语句实际上变成了:

printf("%d\n", a + 1 * a + 1);

这样就比较清晰了,由替换产生的表达式并没有按照预想的次序来求值

在宏定义上加上两个括号,这个问题便轻松的解决了:

#define SQUARE(x) (x)*(x)

这样预处理之后就产生了预期的结果:

printf("%d\n", (a + 1)* (a + 1));

这里还有一个宏定义:

#define SQUARE(x) (x)+(x)

定义中我们使用了括号,想避免之前的问题,但是这个宏可能会出现新的问题

#define SQUARE(x) (x)+(x)
#include
int main()
{
	int a = 5;
	printf("%d\n", 10 * SQUARE(5));

	return 0;
}

这将打印什么呢,看上去,好像打印100,但是事实上打印的是55,

我们发现替换之后:

printf("%d\n", 10 * (5) + (5));

乘法运算先于宏定义的加法,所以出现了55

这个问题的解决办法是在宏定义表达式两边加上一对括号就可以了。

#define SQUARE(x) ((x)+(x))

提示:

所有用于对数值表达式进行求值的宏定义都应该用这种方式加上括号, 避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(c语言,开发语言)