词法分析:
编译器将程序分解成符号的方法是 从左到右一个一个字符的读入,如果该字符可能组成一个符号,再读入下一个字符
而c语言里的符号 / * =只有一个字符长, 是单字符的, /* == 一些事双字符符号。
故因此有以下陷阱
a---b 等价 a-- -b
y= x/*p /*被编译器理解成一段注释的开始
因此应该写成y = x / *p 或者 y = x/(*p)
整型常量 :
如果一个整形常量的第一个字符是数字0 那么该常量将被视作八进制,有时候在上下文中为了格式的对齐的需要,可能无意将十进制写成了
八进制。
字符和字符串:
单引号的一个字符实际上代表一个整数,对应该编译器采用的字符集中的序列值,ASCII字符集最常见。
双引号引起的字符串,代表的是一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及额外的二进制位0
的字符'\0'初始化
嵌套注释:被双引号括起的字符串中,注释符/*属于字符串的一部分,而在注释中出现的双引号又属于注释的一部分
语法陷阱:
函数声明:
运算符的优先级:
!=高于 &
操作符高于单目运算符 *p++ 等价 *(p++)
接下来是双目运算符 其中算数运算符优先级最高 移位次之,关系运算符再次之
接着是逻辑运算符 赋值运算符 最后是条件运算符
三目运算符的优先级是最低的
注意循环语句中的;分号
函数调用:
C语言要求在函数调用即使函数不带参数也应该包括参数列表
数组:
C语言中只有一维数组 C99VLA
NULL指针 不能被解除引用就是访问使用该指针指向的内存中存储的内容
连接器:
通常把目标模块堪称一组外部对象external object组成
每个外部对象代表机器内存的某个部分,并通过一个外部名称来识别
因此程序中的每个函数和每个外部变量如果没有被声明为static 就都是一个外部对象 某些C
编译器会对静态函数和静态变量的名称做一定改变 将他们也作为外部对象 由于经过了名称修饰 所以他们不会和其他源程序中的同名函数或
变量发生命名冲突
定义和声明:
extern int a;说明a是一个外部整形变量 但是因为它包括了extern关键字 这就显示说明了a的存储空间是在程序的其他地方分配的
从连接器的角度看 这是个对外部变量a的引用 不是对a 的定义
extern int a 和定义int a也可以在同一个源文件中