第一章 C 穿越时空的迷雾

  1. 每次编写新函数时,都应该使用函数原型。(可以放在头文件中)

  2. const关键字限定的变量,表示该变量只读。最有用的地方是用来限定函数的形参,防止函数内部修改实参指针所指的数据。const并不表示该变量是常量。

  3. 尽量不使用unsigned 无符号类型,只在使用位段和二进制掩码时使用无符号类型。

  4. 进行比较的时候,使操作数均为有符号数或者无符号数。

    下面的代码int 在比较的时候会升级为unsigned int, 从-1转换后得到的结果是非常大的正整数,从而if语句不会进入。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int solution() {
    int array[] = { 23, 34,12,17,204,99,16};
    int d = -1, x;
    if (d <= (int) (sizeof(array) / sizeof(array[0])) - 2){ // 不加int 不会进入if语句
    cout << d << endl;
    x = array[d+1];
    cout << x << endl;cout << d << endl;
    }
    cout << d << endl;
    return 0;
    }

    第二章 不是BUG,而是语言特性

  5. switch 语句默认是fall through,即case语句不加break的话,会依次执行下去。break跳出的是这个switch语句

  6. 在ANSI C标准中相邻的字符串常量会被自动合并,如果字符串数组在初始化的时候漏掉一个逗号,则会使两个元素自动合并而不报错。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void stringMerge() {
    char *resource[] = {
    "monitor",
    "disk",
    "mouse"
    "keybord",
    "pen",
    };
    cout << resource[2] << endl;
    }

    输出为mousekeybord,这样使数组元素少了一个,造成越界错误。

  7. static修饰的变量只初始化一次,可以用来使同一段代码,第一次执行(对static变量初始化)和后面执行(不进行初始化)结果不同。

  8. C中的函数默认是全局可见的,相当于默认加了extern 关键字,限制对这个函数的访问需要使用static。一个符号要么是全局可见要么是其他都看不见。

  9. static关键字:

    1. 在函数内部,表示该变量值在各个调用期间保持延续性,不会被销毁
    2. 修饰函数,表示函数只对本文件可见
  10. extern 关键字

    1. 修饰函数,表示函数全局可见。冗余操作
    2. 修饰变量,表示在其他地方可见。(跨文件使用全局变量)
  11. 表达式中包含布尔操作,算数运算,位操作等混合计算,适当的地方加上括号,有些优先顺序可能与自己想的不一样,所以使用括号来明确表达。

  12. 结合性

    1. 赋值运算符为右结合性,从右向左执行。a=b=c c先赋值给b,b再赋值给a
    2. 位操作符&,|位左结合性,从左向右执行。
  13. 使用fgets() 替代gets(),后者不会检查读入的限制,会有漏洞,前者只接受有限数量的字符。