预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
示例
#include<stdio.h>
int main()
{
int i=0;
for(i=0;i<10;i++)
{
printf("name:%s file:%s line:%d data:%s time:%s i=%d\n",__func__ ,__FILE__,__LINE__,__DATE__,__TIME__,i);
}
}
这些预定义符号都是语言内置的。
#define 定义宏
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义
宏(define macro)。
下面是宏的申明方式:
#define name( parament-list ) stuff
其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。
注意:
参数列表的左括号必须与name紧邻。
如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。
以下是一个定义宏的简单应用
#include<stdio.h>
#define MAX(x,y) (x>y?x:y)
int main()
{
int a =10;
int b=20;
int c=MAX(a,b);
printf("%d\n",c);
return 0;
}
#的作用
#可以把一个宏参数变成对应的字符串。在下面所示的代码中,#N将传入的N变成了对应的字符串,再根据字符串会自动拼接的特性,我们就可以得到下面的结果
#include<stdio.h>
#define print(N,format) printf("the value of "#N" is " format "\n",N)
int main()
{
int a=20;
double pai=3.14;
print(pai,"%lf");
return 0;
}
## 的作用
##可以把位于它两边的符号合成一个符号。在下面的代码中,我们所定义的宏会将传入的name和num分别拼接起来,形成一个完整的元素,所以在printf语句中,CAT(class,105)将class和105拼接了起来,形成class105,而class105的值恰好为105,所以输出的结果为105
#include<stdio.h>
#define CAT(name,num) name##num
int main()
{
int class105=105;
printf("%d\n",CAT(class,105));
return 0;
}
条件编译
条件编译是指我们有选择性地去编译我们的代码,即当满足某个条件时,才编译部分代码。
在下面所示的代码中,#ifdef和#endif之间的部分是我们条件编译的部分。
此代码中条件编译的条件为__DEBUG__已经完成了定义,就编译#ifdef和#endif之间的代码
#include <stdio.h>
#define __DEBUG__
nt main()
{
int i = 0;
int arr[10] = {0};
for(i=0; i<10; i++)
{
arr[i] = i;
#ifdef __DEBUG__
printf("%d\n", arr[i]);//为了观察数组是否赋值成功。
#endif //__DEBUG__
}
return 0;
}
这种语法形式常常被用于头文件的引用中
在一个大型项目中,为了避免不重复使用头文件来造成代码冗余的问题,我们通常会用上述语句来判断此文件是否引用过相同的头文件,如果引用过,就不再引用。
上述代码也可以使用#pragma once来替换达到相同的效果