1、预处理之宏定义
可以用#define命令将一个指定的标识符(即宏名)来代表一个字符串;
宏定义语法:#define 宏名 字符串
使用原则:
1、“原样替换”;
2、不能代替函数;
3、定义时后缀不要加分号。
带参数的宏定义
#include <stdio.h>
#define s(a,b) a*b //注意,此处不能加分号,否则就变成了s=(a*b;)
int main()
{
printf("矩形1的面积是:%d\n",s(2,4));
printf("矩形2的面积是:%f\n",s(1.2,1.2));
return 0;
}
关于原样替换,请体会下面程序用法的错误
/*
*copyright(c) 2018,HH
*All rights reserved.
*作 者:HH
*完成日期:2018年08月05日
*版本号:v1.0
*
*问题描述:单参数的宏定义,“原样替换”
*输入描述:;
*程序输出:;
*/
#include <stdio.h>
#define pi 3.1415926
#define s(r) r*r*pi
//#define s(r) (r)*(r)*pi//正确的写法
int main()
{
float a,b;
a=1;
b=2;
printf("r=%f,圆形1的面积=%f\n",a+b,s(a+b));//1+2*1+2*3.1415926=1+2+6.2831852=9.2831852
return 0;
}
2、预处理之“文件包含”
所谓“文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包含进来。
源文件与头文件的分离,一般头文件包含以下几类内容:
1、对自定义类型的声明;
2、被调用函数的声明;
3、宏定义:用#define定义的符号常量和宏;
4、全局变量的定义;
5、外部变量的声明,例如:extern int a;
6、根据需要包含的其它头文件。
文件包含的作用:
“文件包含”命令可以节省程序设计人员的重复劳动,是模块化程序设计的产物,便于多个程序员分别编程;将公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用;公用的声明只写一次,除节省时间,更可观的是减少出错。
GCC编译器中的头文件和库函数
头文件:路径codeblocks/MinGW/include中包含.h的头文件;
库函数:路径codeblocks/MinGW/lib下的为.a的库函数(.o目标文件的集合)。
3、预处理之条件编译
/*
*copyright(c) 2018,HH
*All rights reserved.
*作 者:HH
*完成日期:2018年8月9日
*版本号:v1.0
*
*问题描:条件编译
*输入描述:;
*程序输出:
*/
#include <stdio.h>
#define debug//条件编译,“#define 标识符”,该语句如果之前加//则函数中语句会被自动注释
int main()
{
int x=1,y=2;
#ifdef debug
printf("x=%d y=%d\n",x,y);
#endif // debug
printf("x*y=%d\n",x*y);
return 0;
}
1)条件编译的常用形式之一
当所指定的标识符已经被#define命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。#endif用来限定#ifdef命令的范围,其中#else部分也可以没有。
#ifdef 标识符
程序段1
# else
程序段2
#endif
//当不需要编译程序端2时,可以写成如下形式:
#ifdef 标识符
程序段1
#endif
当所指定的标识符没有被#define命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。
#ifndef 标识符
程序段1
#else
程序段2
#endif
2)条件编译的常用形式之二
如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。
4、条件编译:避免重复编译
条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译。了解:条件编译当然也可以用条件语句来实现。 但是用条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目标程序较短。如果条件选择的程序段很长,采用条件编译的方法是十分必要的。
#ifndef 标示1
#define 标示1
#endif
程序段1
该段代码意思是:如果标示1没有被定义,则重定义标示1,然后在执行程序段1、……;如果标示1已经被定义,则直接跳过,直接执行程序端1。
备注:#ifndef 和 #endif 要一起使用,如果丢失#endif,可能会报错。
千万不要忽略了头文件中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:
#ifndef <标识>
#define <标识>
......
......
#endif
<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前面加下划线,并把文件名中的“.”也变成下划线,如:stdio.h
在c语言中,对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作,即使不使用# ifndef宏定义,一个c文件多次包含同一个h文件也不会报错。
但是在c++语言中,#ifndef的作用域只是在单个文件中。所以如果h文件里定义了全局变量,即使采用#ifndef宏定义,一个c文件包含同一个h文件多次还是会出现全局变量重定义的错误。
使用#ifndef可以避免下面这种错误:如果在h文件中定义了全局变量,一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;如果加了#ifndef,则不会出现这种错误。
“ 条件编译”命令允许对程序中的内容选择性地编译,即可以根据一定的条件选择是否编译。