最近阅读C缺陷与陷阱,发现很多有意思的地方,在此作为记录.
No 1. 某些编译器允许嵌套注释。请写一个测试程序,要求:无论是对允许嵌套注释的编译器还是对不允许嵌套注释的编译器,改程序都能正常通过编译,但两种情况下程序执行的结果却不相同.
答案:
#include <stdio.h>
int main()
{
int i=/*/*/0*/**/1;
printf("%d\n",i);
}
这个解法主要利用了编译器作词法分析时的“贪心法”规则。如果编译器允许嵌套注释,则上式将被解释为:1
如果不允许嵌套注释,上面的表达式因此将被这样解释:0*1也就是0。
No.2 C 语言允许初始化列表中出现多余的逗号,例如:
int days[] = {31,28,31,30,31,30,31,31,30,31,30,31,};为什么这种特性是有用的?
答案:
就是为了能让自动化的代码工具生成代码 :-)
No.3 数组与指针
对二维数组的使用例子:
#include <stdio.h>
#include <stdlib.h>
int main()
{
/*二维数组的使用*/
int calendar[12][31] = {0};
for(int i = 0;i < 12;i++)
{
for(int j = 0;j < 31;j++)
{
calendar[i][j]= j + 1;
}
}
for(int i = 0;i < 12;i++)
{
for(int j = 0;j < 31;j++)
{
printf("%d ",*(calendar[i]+j));
}
printf("\n");
}
printf("\n");
for(int i = 0;i < 12;i++)
{
for(int j = 0;j < 31;j++)
{
printf("%d ",*(*(calendar+i) +j));
}
printf("\n");
}
printf("\n");
int (*monthp)[31];
for(monthp = calendar;monthp < &calendar[12];monthp++)
{
for(int days = 0;days < 31;days++)
{
printf("%d ",(*monthp)[days]);
}
printf("\n");
}
printf("\n");
for(monthp = calendar;monthp < &calendar[12];monthp++)
{
int *dayp;
for(dayp = *monthp;dayp < &(*monthp)[31];dayp++)
{
printf("%d ",*dayp);
}
printf("\n");
}
return 0;
}