C语言中的空格,你用对了嘛?

        许多人会告诉你空格在 C语言中没有什么意义,只要你喜欢,随便多输入儿个或者少输入几个都没有关系。但事实并非如此!这里有几个例子,空格从根本上改变了程序的意思或程序的有效性。

  • “\”字符可用于对一些字符进行“转义”,包括newline (这里指回车键)。被转义的newline 在逻辑上把下一行当作当前行的延续,它可用于连接长字符串。如果在“”和回车键之间不小心留上一两个空格就会出现问题,\ newline\newline 就不一样。这个错误很难被发现,因为你是在寻找某种无形的东西(在应该是 newline 的地方出现了一个空格,注意newline 并不是一个有形的字符,所以“”后面有没有空格在实际代码中根本看不出来)。newline 在典型情况下用于转义连续多行的宏定义。如果你的编译器不具备出类拔萃的错误处理能力,最好还是放弃这种用法。转义newline 的另一种用处是延续一个字符串常量,如下
char a[] ="Hi! How are you? I am quite a \
long string, folded onto 2 lines";


这种多行字符串常量的问题被 ANSI C 通过引入相邻字符常量白动连接的约定解决。但正如我在本章的其他地方所指出的那样,这个方法在解决一个问题的同时又引入了一个新问题。

  • 如果将所有的空格都弃之不用,也会陷入麻烦。例如,你明白下面的代码是什么意思吗?
z = y+++x;

        程序员的意图可能是z=y+++x,但也可能是z=y+++x。ANSIC规定了一种渐为人所熟知的“maximal munch strategy(最大一口策略)”。这种策略表示如果下一个标记有超过一种的解释方案,编译器将选取能组成最长字符序列的方案。以上面这个例子为例,它将被解析为z=y+++x。但这还是有可能陷入麻烦,比如下面的代码

Z = Y+++++X;


按照前面的策略将被解析为 z=y++ ++ +x,这将引起一个编译错误,错误信息是“++操作符迷失于空格间”。即使编译器能够推断(从理论上说惟一有效的编排方式是z=y+++++x,它还是会出现编译错误。

  • 第三个跟空格有关的问题出现在当程序员有两个指向mt的指针并想对两个 int数据执行除法运算时,代码如下:
ratio = *x/*y;


        但编译器会给出一条销误信息,抱怨出现了语法错误。问题出在除法运算符“/”与“*”操作符之间缺少空格。当它们紧贴在一起时被编译器理解成注释的开始部分,并把它与下一个“*”之间的所有代码都变成注释的内容。
        跟错误地编写了一个注释符号相关的情况是:打算结束注释时却由于意外未能结束。有种ANSI C 编译器的某个发行版本有一个有趣的 Bug。符号表由一个散列函数访问,该函数计算一个进行一系列搜索的大致起始位置。计算过程用注释的形式在代码中出现,注释内容非常详尽,甚至提到了提供算法的书。不幸的是,该程序员忘了结束注释,导致整个散列初始值计算过程也成了注释的一部分,结果就成了下面的代码。你应该马上能发现问题所在并知道这样会发生什么。

int hashval=0;
/* PW hash function from "Compilers: Principles,Techniques,and Tools'
    * by Aho, Sethi,and ullman,  Second Edition.
while(cp < bound)
{
    unsigned long overflow;
    hashval = (hashval << 4) + *cp++;
    if((overflow = hashal & (((unsigned long) 0xF) << 28)) != 0)
        hashval ~= overflow l (overflow >>24);
}
hashval %= ST HASHS::ZE    /*选择起始桶*/
/* 搜索每个表,这次搜索名字。如果失败,保存该字符串,
 *进入字符串的指针,然后返回它.
*/
for(hp = &st_ihash; ;hp = hp->st hnext) {
    int probeval = hashval;    /*下--个探测值 */

        初始散列值的整个计算过程被省略掉了,这样当程序对符号表进行搜索时,每次总是从第零个元素开始进行!结果符号表搜索(编译器中极为常见的操作)比它预期的要慢得多。这个问题在测试过程中从未被发现过,因为它只影响搜索的速度而不影响结果。这就是有些编译器在注释字符串中间发现“/*”会发出警告信息的原因。这个错误最终在寻找另一个 Bug的过程中被发现,在适当位置插入“*/”后,立刻使编译速度提高了15%!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值