一、宏定义:
不带参的宏定义:
#define 宏名 宏体
在该语句以下的内容,宏名将被宏体所替换。
#define HELLO “hello world!\n”
int main(void)
{
printf(HELLO);
return 0;
}
打印的结果是:hello world!
因为printf中的HELLO 被”hello world!\n”所替换。
不带参数的宏定义的4个特点:
1 若宏名出现在某个字符串中,则宏名不被宏体所替换,如:
#define HELLO “hello world!\n”
Int main(void)
{
printf(“HELLO\n”);
return 0;
}
打印结果是:HELLO
2 若宏体需要换行,可以在本行末尾使用反斜杠“\”表示续行。
3 若宏被定义在函数外部,则其作用域从被定义处开始到文件末尾。
4 可以使用#undef结束宏的作用域。
带参数的宏定义:
#define 宏名(参数列表) 宏体
与函数的使用相似,给宏名实参后,实参将替换宏体中相应的形参。
例如:
#define ADD(a,b) ((a)+(b))
Int main(void)
{
printf(“3+4 = %d\n”, ADD(3,4));
return 0;
}
打印结果是:3+4 = 7
带参数的宏定义的注意事项:
1 给宏体中的每个形参带上括号,防止出错:
#define ADD(a,b) a*b
Int main(void)
{
printf(“3 * (3+4) = %d\n”,ADD(3 , 3+4));
return 0;
}
打印的结果是:3 * (3+4) = 13
因为宏展开后是:3*3+4;而不是想要的3*(3+4)。
2 给宏体也带上括号,原因如上。
3 宏名和参数列表之间不能有空格。
二、include
作用包含另一个文件。
<>和””的区别:
使用<>包含文件,编译器会先到c库函数头文件所在目录查找被包含的文件。
使用””包含文件,编译器会先到用户当前目录下查找被包含的文件。
三、条件编译
#if 表达式
……
#else
…….
#endif
若#if后面的表达式为真,则编译#if至#else之间的代码;若为假,则编译#else至#endif之间的代码;
#include<stdio.h>
#definei 70
intmain(void)
{
#if i> 50
printf("i> 50");
#else
#if i ==50
printf("i ==50");
#else
printf("i< 50");
#endif
#endif
return 0;
}
打印结果是: i > 50
1 #if 和if语句的区别在于if语句无论if后面的表达式是真是假,if后面的代码和else后面的代码都会被编译;而#if在表达式真的时候只编译#if到#else之间的代码,假的时候只编译#else到#endif之间的代码。
2 #if必须有#endif与他搭配,而且#endif总是和他最近的没有#endif搭配的#if搭配。
3 #if后面的表达式不能有局部变量,条件编译是在编译时期做判断的,编译时期局部变量没有值。
4 #if后面的表达式可以包含全局变量,但要注意全局变量在编译时期值为0,是故有:
#include<stdio.h>
int a =70; //定义全局变量
intmain(void)
{
#if a ==0
printf("a ==0"); //此处被打印
printf(“,a = %d\n”,a);
#else
#if a == 70
printf(a == 70");
#else
printf("a !=70 && a != 0\n");
#endif
#endif
return 0;
}
打印结果是: a == 0, a = 70
#ifdef 宏名
…….
#endif
若宏名已经被定义,则编译#ifdef到#endif之间的代码
#ifndef 宏名
……..
#endif
若宏名没有被定义,则编译#ifndef到#endif之间的代码