问:编译器是完全移除注释还是用空格替换注释呢?
答:一些早期的编译器会删除每条注释中的所有字符,使得语句
a/**/b = 0;
可能被编译器理解成
ab = 0;
然而,依据C标准,编译器必须用一个空格字符替换每条注释语句,因此上面提到的技巧并不可行。我们实际上会得到下面的语句:
a b = 0;
问:如何发现程序中未终止的注释?
答:如果运气好的话,程序将无法通过编译,因为这样的注释会导致程序非法。如果程序可以通过编译,也有几种方法可以用。通过用调试器逐行地执行程序,就会发现是否有些行被跳过了。某些集成开发环境会使用特别的颜色把注释和其他代码区分开来。如果你使用的是这样的开发环境,就很容易发现未终止的注释,因为误把程序文本包含到注释中会导致颜色不同。此外,诸如lint(➤1.2节)之类的程序也可以提供帮助。
问:在一个注释中嵌套另一个注释是否合法?
答:传统风格的注释(/*...*/)不允许嵌套。例如,下面的代码就是不合法的:
/* /*** WRONG ***/ */
第2行的符号*/会和第一行的/*相匹配,所以编译器会把第3行的*/标记为一个错误。
C语言禁止注释嵌套有些时候也是个问题。假设我们编写了一个很长的程序,其中包含了许多短小的注释。为了临时屏蔽程序的某些部分(比如在测试过程中),我们首先会想到用/*和*/“注释掉”相应的程序行。但是,如果这些代码行中包含有传统风格的注释,这种方法就行不通了。
不过,C99注释(以//开始的注释)可以嵌套在传统风格的注释中,这是这类注释的另一个优势。后面我们将看到,可以用一种更好的方法来屏蔽部分程序(➤14.4节)。
问:float类型的名字由何而来?(p.13)
答:float是floating-point的缩写形式,它是一种存储数的方法,而这些数中的小数点是“浮动的”。float类型的值通常分成两部分存储:小数部分(或者称为尾数部分)和指数部分。例如,12.0这个数可以以
的形式存储,其中1.5是小数部分,而3是指数部分。有些编程语言把这种类型称为real类型而不是float类型。问:为什么浮点常量需要以字母f结尾?(p.14)
答:完整的解释见第7章。这里只简单回答一下:包含小数点但不以f结尾的常量是double(double precision的缩写)型的。double型的值比float型的值存储得更精确,并且可以比float型的值大,因此在给float型变量赋值时需要加上字母f。如果不加f,编译器可能会生成一条警告消息,告诉你存储到float型变量中的数可能超出了该变量的取值范围。
* 问:对标识符的长度真的没有限制吗?(p.20)
答:是,又不是。C89标准声称标识符可以是任意长,但只要求编译器记住前31个字符(
C99中是63个字符)。因此,如果两个名字的前31个字符都相同,编译器可能会无法区分它们。更复杂的情况是,C标准对于具有外部链接(➤18.2节)的标识符有特殊的规定,而大多数函数名属于这类标识符。因为链接器必须能识别这些名字,而一些早期的链接器又只能处理短名字,所以在C89中标识符只有前6个字符才是有效的。此外,C89还不区分字母的大小写。因此ABCDEFG和abcdefg可能会被作为相同的名字处理。(