重读C陷阱与缺陷

来源:互联网 发布:生意参谋数据怎么导出 编辑:程序博客网 时间:2024/05/29 14:23
C陷阱与缺陷是一本很薄,很易读,很有内容的小书,译者高巍翻译得不错,书的纸张封皮我都很喜欢。今天花了几个小时又粗粗翻了一遍,记点笔记。

1. 词法分析中的贪心法

    C中有一个很简单的规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是,从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个符号,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理策略有时候被称为“贪心法”,或者“大嘴法”。
    比如:a---b,与表达式a-- - b的含义相同。
    如果/*紧挨这一起,无论上下文如何,都被当做一段注释的开始。比如y = x/*p;应该写为 y = x / *p;或更清楚一些y = x / (*p);

2. 整形常量

    在C中10和010的含义截然不同,C编译器会把第一个字符为0的整数当做八进制数。

3. 理解函数声明

    (*(void(*)())0)();表示什么?
    构造这类表达式有一条简单的规则:按照使用的方式来声明。
    任何C变量的声明都是由两部分组成:类型以及一组类似表达式的声明符。声明符从表面上看与表达式有点类似,对它求值应该返回一个声明中给定类型的结果。比如float f;对f求值返回一个float;void (*fp)();   (*fp)()的值为void;(*fp)是一个函数; fp是一个函数指针。那么要得到fp的类型,把变量名去掉,就得到void (*)();(void (*)())0表示把0转换为函数指针;上面的式子就表示对转换后的函数指针的调用。
    当然可以用更清楚的方式表示上面的式子:
    typedef void (*funcptr)();
    (*(funcptr)0)();

4. main函数的标准形式

    在最新的 C99 标准中,只有以下两种定义方式是正确的:
        int main( void )--无参数形式
        {
         ...
        return 0;
        }
       
        int main( int argc, char *argv[] )--带参数形式
        {
         ...
        return 0;
        }
    main函数返回0表示正确执行,返回非0表示执行失败。
    带参数的main,参数类型是指定的,名称可以自己定,通常argc表示参数个数,argv是命令行参数,argv[0]是程序本身的名字。
原创粉丝点击