下载
加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 #ifndef教程

#ifndef教程.doc

#ifndef教程

那個夏末不的涐
2017-09-27 0人阅读 举报 0 0 暂无简介

简介:本文档为《#ifndef教程doc》,可适用于综合领域

#ifndef教程定义#ifndefx#definex#endif这是宏定义的一种它可以根据是否已经定义了一个变量来进行分支选择一般用于调试等等实际上确切的说这应该是预处理功能中三种(宏定义文件包含和条件编译)中的一种条件编译。C语言在对程序进行编译时会先根据预处理命令进行“预处理”。C语言编译系统包括预处理编译和链接等部分。#ifndefx先测试x是否被宏定义过#definex程序段如果x没有被宏定义过定义x并编译程序段#endif程序段如果x已经定义过了则编译程序段的语句“忽视”程序段。条件指示符#ifndef的最主要目的是防止头文件的重复包含和编译。了解:条件编译当然也可以用条件语句来实现。但是用条件语句将会对整个源程序进行编译生成的目标代码程序很长而采用条件编译则根据条件只编译其中的程序段或程序段生成的目标程序较短。如果条件选择的程序段很长采用条件编译的方法是十分必要的。编辑本段补充一些内容千万不要忽略了头文件中的#ifndef这是一个很关键的东西。比如你有两个C文件这两个C文件都include了同一个头文件。而编译时这两个C文件要一同编译成一个可运行文件于是问题来了大量的声明冲突。还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用你都要加上这个。一般格式是这样的:#ifndef<标识>#define<标识>#endif<标识>在理论上来说可以是自由命名的但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写前后加下划线并把文件名中的“”也变成下划线如:stdioh#ifndefSTDIOH#defineSTDIOH#endif编辑本段详细讨论#ifndef的作用在c语言中对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作即使不使用#ifndef宏定义多个c文件包含同一个h文件也不会报错。但是在c语言中#ifndef的作用域只是在单个文件中。所以如果h文件里定义了全局变量即使采用#ifndef宏定义多个c文件包含同一个h文件还是会出现全局变量重定义的错误。使用#ifndef可以避免下面这种错误:如果在h文件中定义了全局变量一个c文件包含同一个h文件多次如果不加#ifndef宏定义会出现变量重复定义的错误如果加了#ifndef则不会出现这种错误。编辑本段条件编译的命令的三种形式“条件编译”命令允许对程序中的内容选择性地编译。即可以根据一定的条件选择是否编译。条件编译的命令主要有以下几种形式#ifdef标识符程序段I#else程序段#endif它的作用是当“标识符”已经由#define定义过了。则编译“程序段”。否则编译“程序段”。其中如果不需要编译“程序段”。则上述形式可以变换为:#ifdef标识符程序段#endif形式#ifndef标识符程序段#else程序段#endif它的作用是当“标识符没有由#define定义过。则编译“程序段”。否则编译“程序段”。同样当无“程序段”时。则上述形式变换为:#ifndef标识符程序段#endif形式#if表达式程序段#elsee程序段#endif它的作用是当“表达式”值为真时。编译程序段。否则则编译程序段。同样当无程序段时则上述形式变换为:#表达式程序段#endif以上三种形式的条件编译预处理结构都可以嵌套使用。当#else后嵌套#if时可以使用预处理命令#elif它相当于#else#if。在程序中使用条件编译主要是为了方便程序的调试和移植。防止重复编译以testh为例:#ifndefTESTH#defineTESTH#endif一般是用来防止重复包含头文件第一次包含头文件时XXX没有被定义第二次再用时XXX已经被定义拉就不在包含这个头文件。条件指示符#ifndef检查预编译常量在前面是否已经被定义如果在前面没有被定义,则条件指示符的值为真,于是从#inndef到#endif之间的所有语句都被包含进来进行处理相反,如果#inndef指示符的值为假,则它与#endif指示符之间的行将被忽略条件指示符#ifndef的最主要目的是防止头文件的重复包含和编译。深入:条件编译预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。条件编译有三种形式下面分别介绍:第一种形式:#ifdef标识符程序段#else程序段#endif它的功能是如果标识符已被#define命令定义过则对程序段进行编译否则对程序段进行编译。如果没有程序段(它为空)本格式中的#else可以没有即可以写为:#ifdef标识符程序段#endif举例如下:#defineNUMokvoidmain(){structstu{intnumchar*namecharsexfloatscore}*psps=(structstu*)malloc(sizeof(structstu))ps>num=ps>name="Zhangping"ps>sex='M'ps>score=#ifdefNUMprintf("Number=dnScore=fn",ps>num,ps>score)#elseprintf("Name=snSex=cn",ps>name,ps>sex)#endiffree(ps)}由于在程序的第行插入了条件编译预处理命令因此要根据NUM是否被定义过来决定编译那一个printf语句。而在程序的第一行已对NUM作过宏定义因此应对第一个printf语句作编译故运行结果是输出了学号和成绩。在程序的第一行宏定义中定义NUM表示字符串OK其实也可以为任何字符串甚至不给出任何字符串写为:#defineNUM也具有同样的意义。只有取消程序的第一行才会去编译第二个printf语句。读者可上机试作。第二种形式:#ifndef标识符程序段#else程序段#endif与第一种形式的区别是将“ifdef”改为“ifndef”。它的功能是如果标识符未被#define命令定义过则对程序段进行编译否则对程序段进行编译。这与第一种形式的功能正相反。可以理解为ifnotdefine第三种形式:#if常量表达式程序段#else程序段#endif它的功能是如常量表达式的值为真(非)则对程序段进行编译否则对程序段进行编译。因此可以使程序在不同条件下完成不同的功能举例如下:#defineRvoidmain(){floatc,r,sprintf("inputanumber:")scanf("f",c)#ifRr=*c*cprintf("areaofroundis:fn",r)#elses=c*cprintf("areaofsquareis:fn",s)#endif}本例中采用了第三种形式的条件编译。在程序第一行宏定义中定义R为因此在条件编译时常量表达式的值为真故计算并输出圆面积。上面介绍的条件编译当然也可以用条件语句来实现。但是用条件语句将会对整个源程序进行编译生成的目标代码程序很长而采用条件编译则根据条件只编译其中的程序段或程序段生成的目标程序较短。如果条件选择的程序段很长采用条件编译的方法是十分必要的。一般情况下源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译也就是对一部分内容指定编译的条件这就是“条件编译”。有时希望当满足某条件时对一组语句进行编译而当条件不满足时则编译另一组语句。条件编译命令最常见的形式为:#ifdef标识符程序段#else程序段#endif它的作用是:当标识符已经被定义过(一般是用#define命令定义)则对程序段进行编译否则编译程序段。其中#else部分也可以没有即:#ifdef程序段#denif这里的“程序段”可以是语句组也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上系统上运行而不同的计算机又有一定的差异。例如我们有一个数据类型在Windows平台中应该使用long类型表示而在其他平台应该使用float表示这样往往需要对源程序作必要的修改这就降低了程序的通用性。可以用以下的条件编译:#ifdefWINDOWS#defineMYTYPElong#else#defineMYTYPEfloat#endif如果在Windows上编译程序则可以在程序的开始加上#defineWINDOWS这样则编译下面的命令行:#defineMYTYPElong如果在这组条件编译命令之前曾出现以下命令行:#defineWINDOW则预编译后程序中的MYTYPE都用float代替。这样源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况可以根据此思路设计出其它的条件编译。例如在调试程序时常常希望输出一些所需的信息而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:#ifdefDEBUGprint("deviceopen(p)n",file)#endif如果在它的前面有以下命令行:#defineDEBUG则在程序运行时输出file指针的值以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的即在调试时加一批printf语句调试后一一将printf语句删除去。的确这是可以的。但是当调试时加的printf语句比较多时修改的工作量是很大的。用条件编译则不必一一删改printf语句只需删除前面的一条“#defineDEBUG”命令即可这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用即起统一控制的作用如同一个“开关”一样。一般情况下源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译也就是对一部分内容指定编译的条件这就是“条件编译”。有时希望当满足某条件时对一组语句进行编译而当条件不满足时则编译另一组语句。条件编译命令最常见的形式为:#ifdef标识符程序段#else程序段#endif它的作用是:当标识符已经被定义过(一般是用#define命令定义)则对程序段进行编译否则编译程序段。其中#else部分也可以没有即:#ifdef程序段#denif这里的“程序段”可以是语句组也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上系统上运行而不同的计算机又有一定的差异。例如我们有一个数据类型在Windows平台中应该使用long类型表示而在其他平台应该使用float表示这样往往需要对源程序作必要的修改这就降低了程序的通用性。可以用以下的条件编译:#ifdefWINDOWS#defineMYTYPElong#else#defineMYTYPEfloat#endif如果在Windows上编译程序则可以在程序的开始加上#defineWINDOWS这样则编译下面的命令行:#defineMYTYPElong如果在这组条件编译命令之前曾出现以下命令行:#defineWINDOW则预编译后程序中的MYTYPE都用float代替。这样源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况可以根据此思路设计出其它的条件编译。例如在调试程序时常常希望输出一些所需的信息而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:#ifdefDEBUGprint("deviceopen(p)n",file)#endif如果在它的前面有以下命令行:#defineDEBUG则在程序运行时输出file指针的值以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的即在调试时加一批printf语句调试后一一将printf语句删除去。的确这是可以的。但是当调试时加的printf语句比较多时修改的工作量是很大的。用条件编译则不必一一删改printf语句只需删除前面的一条“#defineDEBUG”命令即可这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用即起统一控制的作用如同一个“开关”一样。有时也采用下面的形式:#ifndef标识符程序段#else程序段#endif只是第一行与第一种形式不同:将“ifdef”改为“ifndef”。它的作用是:若标识符未被定义则编译程序段否则编译程序段。这种形式与第一种形式的作用相反。以上两种形式用法差不多根据需要任选一种视方便而定。还有一种形式就是#if后面的是一个表达式而不是一个简单的标识符:#if表达式程序段#else程序段#endif它的作用是:当指定的表达式值为真(非零)时就编译程序段否则编译程序段。可以事先给定一定条件使程序在不同的条件下执行不同的功能。例如:输入一行字母字符根据需要设置条件编译使之能将字母全改为大写输出或全改为小写字母输出。#defineLETTERmain(){charstr="CLanguage",cinti=while((c=stri)!=''){i#ifLETTERif(c>='a'c<='z')c=c#elseif(c>='A'c<='Z')c=c#endifprintf("c",c)}}运行结果为:CLANGUAGE现在先定义LETTER为这样在预处理条件编译命令时由于LETTER为真(非零)则对第一个if语句进行编译运行时使小写字母变大写。如果将程序第一行改为:#defineLETTER则在预处理时对第二个if语句进行编译处理使大写字母变成小写字母(大写字母与相应的小写字母的ASCII代码差)。此时运行情况为:clanguage有人会问:不用条件编译命令而直接用if语句也能达到要求用条件编译命令有什么好处呢,的确此问题完全可以不用条件编译处理但那样做目标程序长(因为所有语句都编译)而采用条件编译可以减少被编译的语句从而减少目标的长度。当条件编译段比较多时目标程序长度可以大大减少。补充:头文件中的#ifndef(::)标签:学习公社千万不要忽略了头件的中的#ifndef这是一个很关键的东西。比如你有两个C文件这两个C文件都include了同一个头文件。而编译时这两个C文件要一同编译成一个可运行文件于是问题来了大量的声明冲突。还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用你都要加上这个。一般格式是这样的:#ifndef<标识>#define<标识>#endif<标识>在理论上来说可以是自由命名的但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写前后加下划线并把文件名中的“”也变成下划线如:stdioh#ifndefSTDIOH#defineSTDIOH#endif

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/13

#ifndef教程

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利