本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
一行注释也能影响运行结果?
奔跑的男人 · 470浏览 · 发布于2020-04-01 +关注

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

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

字符

见证“奇迹”

#include <stdio.h> #include <math.h> int main(void) {     int a = (int)sqrt(30);     //is sqrt(30) + 1 > 5 ??/     //故意让a++,你别管为什么    a++;    if(a > 5)        printf("sqrt(30) +1 > 5 \n");    else    {        printf("sqrt(30) +1 <= 5 \n");    }    return 0;

编译运行:

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

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

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

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

结果竟然变了!!

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

三字符组

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

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

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

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

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

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

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

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

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

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

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

当然了,很多现代编译器可能并不会做这样的替换,所以这样的问题也基本无需担心,老实用原本的符号即可。

实际上,细心的读者可能观察到了,我在前面例子代码中加了编译选项-trigraphs,否则的话,编译是有警告的:

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

双字符组

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

总结

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


相关推荐

PHP实现部分字符隐藏

沙雕mars · 1321浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 906浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 966浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 960浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1084浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页