小言_互联网的博客

一行注释也能影响代码运行?别不信!

310人阅读  评论(0)

​来源:公众号【编程珠玑】

作者:守望先生

ID:shouwangxiansheng

 

没想到吧,一行注释也能影响运行结果

也许你在某个段子里听说过,某行注释删掉后,程序竟然不能预期执行?真的会这样么?你还别不信。

见证“奇迹”


  
  1. 1 //来源:公众号【编程珠玑】
  2. 2 //作者:守望先生
  3. 3 #include <stdio.h>
  4. 4 #include <math.h>
  5. 5 int main(void)
  6. 6{
  7. 7     int a = ( int) sqrt( 30);
  8. 8     //is sqrt(30) + 1 > 5 ??/
  9. 9     //故意让a++,你别管为什么
  10. 10    a++;
  11. 11     if(a >  5)
  12. 12         printf( "sqrt(30) +1 > 5 \n");
  13. 13     else
  14. 14    {
  15. 15         printf( "sqrt(30) +1 <= 5 \n");
  16. 16    }
  17. 17     return  0;
  18. 18}

编译运行:


  
  1. 1$ gcc -o main main.c -trigraphs
  2. 2$ ./main
  3. 3sqrt( 30) + 1 >  5 

作为受过九年义务教育的我们,一看就知道结果是对的,毕竟 5 * 5 < 30 < 6 * 6。

但是删掉第九行,再运行:


  
  1. 1$ ./main
  2. 2sqrt( 30) + 1 <=  5 

结果竟然变了!!
 

看到这里,细心的读者可能已经发现了其中的端倪,我也就不卖关子了。接下来就说说我们本次要提到的主角-三字符组(trigraph sequences)。

三字符组

我们都知道C语言里面有很多转义符号,例如:


  
  1. 1\n 换行符(LF)
  2. 2\r 回车符(CR)
  3. 3\t 水平制表符(HT)
  4. 4\b 退格符(BS)
  5. 5\’ 单引号
  6. 6\” 双引号
  7. 7\\ 反斜杠
  8. 8......

当然还有很多,我就不一一列举了。这些符号在代码中都有特别的作用,或者无法直接输入,因此用转移符+其他字符组合来代替。

同样的,早期的一些键盘可能没法输入一些特殊的符号,如:

1# $ @ [ \ ] ^ ` { | } ~ 

于是,为了解决这个问题C语言标准规定预处理器(C preprocessor)在扫描处理C语言源文件时,替换下述的3字符出现为1个字符:

三字符组 替换为
??= #
??/ \
??' ^
??( [
??) ]
??! |
??< {
??> }
??- ~

也就是说,??/会被替换为\,如果删掉原先的第九行,就变成了:


  
  1. 1     //is sqrt(30) + 1 > 5 \
  2. 2    a++;

我们都知道,\的存在(通常一行代码太长,可以通过该符号来换行),使得上面看似两行,实则是一行。即变成了:

1    //is sqrt(30) + 1 > 5 a++;

也就是说,a++根本不会执行了,当然会导致最终结果不符合预期。

当然了,很多现代编译器可能并不会做这样的替换,所以这样的问题也基本无需担心,老实用原本的符号即可。
实际上,细心的读者可能观察到了,我在前面例子代码中加了编译选项-trigraphs,否则的话,编译是有警告的:


  
  1. 1$ gcc -o main main.c
  2. 2main.c:  In  function ‘main’:
  3. 3main.c: 6: 27: warning: trigraph ??/ ignored, use -trigraphs  to enable [-Wtrigraphs]
  4. 4      //is sqrt(30) + 1 > 5 ??/

双字符组

除了三字符组,还有双字符组。

双字符组 替换为
<: [
:> ]
<% {
%> }
%: #

总结

今天的你不知道很难踩坑,知道了也没啥用的内容就介绍到这里了。

但是留个问题:

为什么例子中我们使用了sqrt函数,但在编译时却不需要链接math库?答案在这里一个奇怪的链接问题

 

关注公众号【编程珠玑】,获取更多Linux/C/C++/数据结构与算法/计算机基础/工具等原创技术文章。后台免费获取经典电子书和视频资源


转载:https://blog.csdn.net/hyb612/article/details/105464199
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场