我在网上找到了这个C程序:
#include <stdio.h>
int main(){
printf("C%d\n",(int)(90-(-4.5//**/
-4.5)));
return 0;
}
这个程序有趣的地方在于,当以C89模式编译和运行时,它会打印C89
,而当以C99模式编译和运行时,则会打印C99
。但我无法弄清楚这个程序是如何工作的。
你能解释一下上述程序中 printf
的第二个参数是如何工作的吗?
C99允许//
风格的注释,C89则不行。因此,要进行翻译:
C99:
printf("C%d\n",(int)(90-(-4.5 /*Some comment stuff*/
-4.5)));
// Outputs: 99
C89:
printf("C%d\n",(int)(90-(-4.5/
-4.5)));
/* so we get 90-1 or 89 */
自C99起,引入了行注释//
。因此,你的代码相当于在C89中:
#include <stdio.h>
int main(){
printf("C%d\n",(int)(90-(-4.5/
-4.5)));
return 0;
}
/* 90 - (-4.5 / -4.5) = 89 */
在C99中也等同于此
#include <stdio.h>
int main(){
printf("C%d\n",(int)(90-(-4.5
-4.5)));
return 0;
}
/* 90 - (-4.5 - 4.5) = 99*/
由于//
注释仅存在于C99及更高版本的标准中,因此该代码等效于以下内容:
#include <stdio.h>
int main (void)
{
int vers;
#if __STDC_VERSION__ >= 201112L
vers = 99; // oops
#elif __STDC_VERSION__ >= 199901L
vers = 99;
#else
vers = 90;
#endif
printf("C%d", vers);
return 0;
}
正确的代码应该是:
#include <stdio.h>
int main (void)
{
int vers;
#if __STDC_VERSION__ >= 201112L
vers = 11;
#elif __STDC_VERSION__ >= 199901L
vers = 99;
#else
vers = 90;
#endif
printf("C%d", vers);
return 0;
}
//
注释。 - Paul Rgcc
中会失败。如果没有使用std=c99
选项,你将会收到一个警告,即使你忽略了它,gcc
仍然会将//
解释为注释的开头(啊 - 你还需要使用-pedantic
选项。我默认已经开启了它)。 - Jongwarestd=c89
选项得到了符合C89标准的编译结果。 - ikh#if __STDC_VERSION__ >= 199901L
的方式,而不是使用//
注释技巧。 =) - Arkku