1我们知道,C标准不提供c++里的“//闭庋牡バ蟹绺褡⑹投惶峁?* *”这样的块注释功能,我们通常使用它写代码中说明性的注释文字(注释作用)以及在调试时关闭某段代码对编译器的可见性(屏蔽作用),当然,这里所谓的“注释作用”和“屏蔽作用”是我们从功能上下的主观定义,对预处理器而言,两者并无任何区别。对于前者,因为“注释”中不会再出现“注释”和“需要屏蔽的代码段”,所以不会有嵌套的需求,所以通常不会有问题;而对于后者,当我们在调试程序时需要“屏蔽”某段代码时,该段代码中可能包含着前述的“注释”和/或“已被屏蔽的代码段”,这时就产生了“/* */鼻短资褂玫男枨?但某人的C标准恰恰不允许我们这么干。当你试图使用嵌套的块注释功能时,会发现预处理器把最外层注释的开始和最内层注释的结尾这两者之间的内容处理成了注释,而其后一直到最外层注释结尾的内容被当作了“有效代码”——这显然会引起若干语法错误而导致编译中止。高手们开动脑筋想到了“#如果0…# endif”,它同样由预处理器进行处理,同样可以“屏蔽”一段代码,你想把说明文字写在里面也可以,这些和“/* *”都一样,但不一样的是:第一它允许嵌套(层数上限由预处理器决定),第二你随时可以把“#如果0”改成“#如果1”来取消对某段代码的“屏蔽”——很卓越的特性,快抛弃笨拙的“/* *”吧!它唯一的缺点就是在编辑器中没有“注释”该有的文本显示样式。
2,现在再来说说2楼提到的自动变量局部化的问题:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
通过谷歌,得知:
# if 0, code # endif
(1)代码中定义的是一些调试版本的代码,此代码时完全被编译器忽略。如果想让代码生效,只需把0 #如果改成#如果1,
(2) #如果0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#如果0是最好的,保证不会犯错误。(但是林锐的书上说千万不要把#如果0来当作块注释使用),
#如果1可以让其间的变量成为局部变量只
(3)这个结构表示你先前写好代码的,现在用不上了,又不想删除,就用这个方法,比注释方便只
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
通过我上面说的第一点,我们可以知道,对“#如果/# endif”的处理是预处理器完成的,而预处理器的唯一工作就是作“文字替换”的“预处理”工作,它并不负责常数符号表的生成,变量存储空间的分配,代码的重定位等工作,那么完全是给预处理器看的“#如果/# endif”怎么能控制变量的生存期,怎么能决定变量可以在哪里定义? ?
打开编辑器,写下如下代码:
===========================, volatile unsigned char ; unsigned int 主要(空白) { ,,,,,,,a =, 0;, # if 1, unsigned char * p =,,,, * p =, 255;, # endif return 0; },===========================
存成。c文件后用任何c编译器(不包括c++编译器)编译,都会在红字那一行报错,为什么呢?因为预处理器进行“预处理”的时候发现如果的条件表达式为“真”,所以它把那段代码块留下了,而只把代码块前后的“预处理指示符号(或者叫做预处理命令)”给清除掉了,这样,预处理后的结果交给编译器”翻译”的时候,它发现在一个函数(在这里为主要函数)内部的表达式语句(在这里是一个=0;)之后发现了变量声明/定义语句(在这里是声明并定义指针变量p的语句),按照编译器的规则,这是一个错误,所以它拒绝接受这样的输入,罢工并开始抱怨(中止编译,给出错误信息)。