C 语言的注释可以出现在C 语言代码的任何地方。这句话对不对?这是我当学生时我老师问的一个问题。我当时回答是不对。好,那我们就看看下面的例子:
A)
int/*...*/i;
B)
char* s="abcdefgh //hijklmn";
C)
//Is it a \
valid comment?
D)
in/*…*/t i;
我们知道C 语言里可以有两种注释方式:/* */ 和//。那上面3 条注释对不对呢?建议你亲自在编译器中测试一下。上述前3条注释都是正确的,最后一条不正确。
A),有人认为编译器剔除掉注释后代码会被解析成inti,所以不正确。编译器的确会将注释剔除,但不是简单的剔除,而是用空格代替原来的注释。再看一个例子:
/*这是*/#/*一条*/define/*合法的*/ID/*预处理*/replacement/*指*/list/*令*/
你可以用编译器试试。
B),我们知道双引号引起来的都是字符串常量,那双斜杠也不例外。
C),这是一条合法的注释,因为/是一个接续符。关于接续符,下面还有更多讨论。
D), 前面说过注释会被空格替换,那这条注释不正确就很好理解了。
现在你可以回答前面的问题了吧?但注意:/*…*/这种形式的注释不能嵌套,如:
/*这是/*非法的*/*/
因为/*总是与离它最近的*/匹配。
y = x/*p,这是表示x 除以p 指向的内存里的值,把结果赋值为y?我们可以在编译器上测试一下,编译器提示出错。
实际上,编译器把/*当作是一段注释的开始,把/*后面的内容都当作注释内容,直到出现*/为止。这个表达式其实只是表示把x 的值赋给y,/*后面的内容都当作注释。但是,由于没有找到*/,所以提示出错。
我们可以把上面的表达式修改一下:
y = x/ *p
或者
y = x/(*p)
这样的话,表达式的意思就是x 除以p 指向的内存里的值,把结果赋值为y 了。
也就是说只要斜杠(/)和星号(*)之间没有空格,都会被当作注释的开始。这一点一定要注意。
注释写得出色非常不容易,但是写得糟糕却是人人可为之。糟糕的注释只会帮倒忙。
1、安息吧,路德维希.凡.贝多芬
在《Code Complete》这本书中,作者记录了这样一个故事:有位负责维护的程序员半夜被叫起来,去修复一个出了问题的程序。但是程序的原作者已经离职,没有办法联系上他。这个程序员从未接触过这个程序。在仔细检查所有的说明后,他只发现了一条注释,如下:
MOV AX 723h ;R.I.P.L.V.B.
这个维护程序员通宵研究这个程序,还是对注释百思不得其解。虽然最后他还是把程序的问题成功排除了,但这个神秘的注释让他耿耿于怀。说明一点:汇编程序的注释是以分号开头。
几个月后,这名程序员在一个会议上遇到了注释的原作者。经过请教后,才明白这条注释的意思:安息吧,路德维希.凡.贝多芬(Rest in peace, Ludwig Van Neethoven)。贝多芬于1827 年逝世,而1827 的十六进制正是723。这真是让人哭笑不得!
2、windows 大师们用注释讨论天气问题
还有个例子:前些日子windows 的源代码曾经泄漏过一部分。人们在看这部分大师的经典作品时,却发现很多与代码毫无关系的注释!有的注释在讨论天气,有的在讨论明天吃什么,还有的在骂公司和老板。这些注释虽然与代码无关,但总比上面那个让贝多芬安息的注释要强些的。至少不会让你抓狂。不过这种事情只有大师们才可以做,你可千万别用注释
讨论天气。
3、出色注释的基本要求
关于函数的注释在函数那章有更详细的讨论。