最近阅读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;
}