① 为什么在头文件里面用条件编译呢程序如下
防止重复编译。比如,第一次使用该头文件后,LCDHEARD被定义过,以后再使用该头文件,就不会重新编译了。
② #ifndef是什么
#ifndef是"if not defined"的简写,是宏定义的一种,它是可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等。
实际上确切的说这应该是预处理功能中三种(宏定义,文件包含和条件编译)中的第三种——条件编译。
作用:
条件指示符#ifndef的最主要目的是防止头文件的重复包含和编译。
条件编译当然也可以用条件语句来实现, 但是用条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目标程序较短。如果条件选择的程序段很长,采用条件编译的方法是十分必要的。
③ C语言中条件编译的作用
条件编译属于三种宏定义中的一种,条件指示符的最主要目的是防止头文件的重复包含和编译,例如:一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误
条件编译常用的有四个预处理命令:#if、#else、#elif、#endif。
#if指令的形式为:
#if常量表达式
代码块
#endif
#if后面的常量表达式为值,则编译它与#endif之间的代码,否则跳过这些代码。指令#endif标识一个#if块的结束。
#else被使用来标志#if的末尾和#else块的开始。这是必须的,因为任何#if仅有一个#endif与之关联。
#elif意指"else if",它形成一个if else if嵌套语句用于多种编译选择。#elif后面跟一个常量表达式,如果表达式是真,则编译其后的代码块,不对其他#elif表达式进行检测,否则顺序测试下一块。常见的形式如下:
形式1:
#ifdef标识符
/*程序段1*/
#else
/*程序段2*/
#endif
它的作用是当标识符已经由#define定义过了,则编译程序段1,否则编译程序段2,也可以使用简单形式
#ifdef标识符
/*程序段1*/
#endif
形式2:
#ifndef标识符
#define标识符
/*程序段1*/
#else
/*程序段2*/
#endif
它的作用是当标识符没有由#define定义过,则编译程序段1,否则编译程序段2 ,也可以使用简单形式
#ifndef标识符
#define标识符
/*程序段1*/
#endif
形式3:
#if表达式
/*程序段1*/
#else
*程序段2*/
#endif
它的作用是 当“表达式”值为真时编译程序段1。否则则编译程序段2,也可以使用简单形式
#if表达式
/*程序段1*/
#endif
形式4:
#if表达式1
/*程序段1*/
#elif表达式2
/*程序段2*/
............
#elif表达式n
/*程序段n*/
#endif
它的作用是当“表达式1”值为1时编译程序段1,表达式2的值为真是编译程序段2,否则依次顺序判断到表达式n。
最后,条件编译的条件是一个常量表达式,支持逻辑与&&和或||运算。以上四种形式的条件编译预处理结构都可以嵌套使用,
标识符: 在理论上来说可以是自由命名的,但每个头文件的这个标识符都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h。
#ifndef_STDIO_H_
#define_STDIO_H_
/*程序段*/
#endif
④ 请教高手关于头文件条件编译#ifndef的问题 下面的程序有哪位高手给解释一下啊 各个层次关系 小弟看不懂
最外层的#ifdef是这个样子:
#ifndef __MENU_H
#define __MENU_H
...
#endif /* __MENU_H */
这是为了确保menu.h只被包含一次。第二次包含时,由于__MENU_H已经被定义,整个文件的内容就被跳过了。
__cplusplus是个特殊的宏,只在C++程序中被定义。这样,在C代码中,看到的代码是这个样子的:
...
void Show_HomeScreen(void);
而在C++代码中,看到的则是这个样子:
extern "C" {
...
void Show_HomeScreen(void);
}
最主要的用处是函数被声明为extern "C",也就是在目标文件中用C的方式进行编码和查找。C的方式只有函数名,而C++的方式则把参数也编码了进去,这样才可能允许函数重载。比如,test(int)在C代码里的符号名就是test,而在C++中则不同。在MSVC(在不同编译器中不同)中是“?test@@YAXH@Z”。一个函数要同时在C和C++中使用,一般都回在头文件声明时放到一个extern "C"块里。
⑤ #ifndef的用法
#ifndef是宏定义里面的一种,用来防止防止头文件的重复包含和编译。
比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。
如果把头文件的内容都放在#ifndef和#endif中,不管你的头文件会不会被多个文件引用,你都要加上这个,就可以避免冲突的问题。
#ifndef可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说这应该是预处理功能中三种(宏定义,文件包含和条件编译)中的一种——条件编译。 C语言在对程序进行编译时,会先根据预处理命令进行“预处理”。C语言编译系统包括预处理,编译和链接等部分。
(5)对头文件用条件编译扩展阅读:
#ifndef一般格式是这样的:
#ifndef <标识>
#define <标识>
......
#endif
<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h
#ifndef _STDIO_H_
#define _STDIO_H_
......
#endif
⑥ C++中的条件编译是怎么一回事能举例解释一下吗
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
条件编译命令最常见的形式为:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。
其中#else部分也可以没有,即:
#ifdef
程序段1
#denif
这里的“程序段”可以是语句组,也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上运行,而不同的计算机又有一定的差异。例如,我们有一个数据类型,在Windows平台中,应该使用long类型表示,而在其他平台应该使用float表示,这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译:
#ifdef WINDOWS
#define MYTYPE long
#else
#define MYTYPE float
#endif
如果在Windows上编译程序,则可以在程序的开始加上
#define WINDOWS
这样则编译下面的命令行:
#define MYTYPE long
如果在这组条件编译命令之前曾出现以下命令行:
#define WINDOW
则预编译后程序中的MYTYPE都用float代替。这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况,可以根据此思路设计出其它的条件编译。
例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:
#ifdef DEBUG
print ("device_open(%p)\n", file);
#endif
如果在它的前面有以下命令行:
#define DEBUG
则在程序运行时输出file指针的值,以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的,即在调试时加一批printf语句,调试后一一将printf语句删除去。的确,这是可以的。但是,当调试时加的printf语句比较多时,修改的工作量是很大的。用条件编译,则不必一一删改printf语句,只需删除前面的一条“#define DEBUG”命令即可,这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用,即起统一控制的作用,如同一个“开关”一样。
有时也采用下面的形式:
#ifndef 标识符
程序段1
#else
程序段2
#endif
只是第一行与第一种形式不同:将“ifdef”改为“ifndef”。它的作用是:若标识符未被定义则编译程序段1,否则编译程序段2。这种形式与第一种形式的作用相反。
以上两种形式用法差不多,根据需要任选一种,视方便而定。
还有一种形式,就是#if后面的是一个表达式,而不是一个简单的标识符:
#if 表达式
程序段1
#else
程序段2
#endif
它的作用是:当指定的表达式值为真(非零)时就编译程序段1,否则编译程序段2。可以事先给定一定条件,使程序在不同的条件下执行不同的功能。
例如:输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。
#define LETTER 1
main()
{
char str[20]="C Language",c;
int i=0;
while((c=str[i])!='\0'){
i++;
#if LETTER
if(c>='a'&&c<='z') c=c-32;
#else
if(c>='A'&&c<='Z') c=c+32;
#endif
printf("%c",c);
}
}
运行结果为:C LANGUAGE
现在先定义LETTER为1,这样在预处理条件编译命令时,由于LETTER为真(非零),则对第一个if语句进行编译,运行时使小写字母变大写。如果将程序第一行改为:
#define LETTER 0
则在预处理时,对第二个if语句进行编译处理,使大写字母变成小写字母(大写字母与相应的小写字母的ASCII代码差32)。此时运行情况为:
c language
有人会问:不用条件编译命令而直接用if语句也能达到要求,用条件编译命令有什么好处呢?的确,此问题完全可以不用条件编译处理,但那样做目标程序长(因为所有语句都编译),而采用条件编译,可以减少被编译的语句,从而减少目标的长度。当条件编译段比较多时,目标程序长度可以大大减少。
补充:
头文件中的#ifndef
千万不要忽略了头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。
还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:
#ifndef <标识>
#define <标识>
......
......
#endif
<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h
#ifndef _STDIO_H_
#define _STDIO_H_
......
#endif
⑦ 头文件中的 ifndef/define/endif 干什么用
#ifndef、#define、#endif为C语言的3条预处理语句,主要用作条件编译。先介绍一下条件编译:
一般情况下,源代码文件中的所有行都参加编译,但有时需要指定一部分代码在某个拍缓条件下才被编译,这就叫做条件编译。
条件编译发生在预处理阶段,在C中,主要通过#if、#elif、#else、#ifdef、#ifndef、#endif来给一段代码附加上编译条件,然后预处理器收集满足条件的可以进行编译的代码,这样经过预处理,不满足条件的代码就不会被编译。
这3个预处理语袭芦模句的功能分别为:
#ifndefsymbol
语句块
#endif
如果没有定义符号symbol,那么就编译下面指定的语句块,用endif来表示条件编译语句的结尾。
#definesymbol
定义一个符号symbol。
这三个预处理语句用在一起可以解决头文件被重复引用的问题:一个.c源程序中可能引用了多个头文件,而被源程序引用的头哗蔽文件又有可能存在引用关系,比如a.h引用了b.h,然后在源程序中同时引用a.h和b.h,就会产生这个问题,这时编译器会产生符号重定义之类的错误。为了防止该问题,就需要在头文件中加入以下语句:
#ifndefsymbol
#definesymbol
头文件包含的内容
#endif
这样即可防止该头文件被重复引用。symbol一般采取以下方式命名:_头文件名_H,当然也可采取其他方式。
另外,对于有的编译器也可以在头文件中加入#pragma once来防止头文件被重复引用