现在的位置: 首页 > 综合 > 正文

C陷阱与缺陷书摘 —词法与语法“陷阱”

2013年08月06日 ⁄ 综合 ⁄ 共 1169字 ⁄ 字号 评论关闭

符号token:程序中的一个基本信息单元。词法分析:把程序分解成一个一个符号。

 

1. 词法分析中的贪心规则

 

如果(编译器)输入流截止某个字符之前都已经被分解为一个个符号,则下一个符号将包括从该输入符之后可能组成一个符号的最长字符串。(K&R)

 

例:

                      y = x/*p ;         /* p指向除数 */

 

      根据注释,上述语句似乎是用x除以p所指向的值,把所得商赋给x;而实际上, /*被编译器理解为一段注释的开始,它将不断读入字符,直到*/出现为止。上述语句直接将x赋值给y,不顾及后面的p。

 

2. 整形常量

 

第一个字符是数字0的整形常量将被视为八进制数。10 不同于 010。有时候为了格式对齐的需要,可能会无意中10进制写成8进制。

 

3. 字符与字符串

 

用单引号(‘’)包住的一个字符代表一个整数,其值对应于该字符在编译器采用的字符集中的序列值。例:‘a’与0141(八进制)或97(十进制)严格一致,对采用ascii字符集的编译器而言。

 

用双引号(“”)包住的字符串,代表的是一个指向无名数组骑士字符的指针,该数组被双引号之间的字符以及一个额外的二进制值为零的字符‘/0’初始化。

 

因为两者类型不同,如果混用,编译器的类型检查功能将会检测到这样的错误。例: char *slash = '/'; 。而在某些不对函数参数进行类型检查的编译器中,则会在程序运行时产生难以预料的错误,而不会给出编译器诊断信息。

 

4. 函数声明

 

C变量的声明包含两部分:1)类型;2)一组类似表达式的声明符(declarator)。

 

可以在声明中任意使用括号(由于声明符与表达式相似):float ((f))

 

float *g(), (*h)();

表示*g()和(*h)()都是浮点表达式。()的结合优先级高于*, *g() 也就是*(g()):g是一个函数,其返回值类型是指向浮点数的指针;同理,可以看出h是一个函数指针,h所指向的函数的返回值为浮点类型。

 

根据一个给定类型的变量声明,得到该类型的类型转换符:只需把声明中的变量名和声明末尾的分号去掉,在将剩余部分用一个括号“封装”起来即可。

如 float (*h)();  --->  (float (*)())
  : 表示一个“指向返回值为浮点类型的函数的指针”的类型装换符。

 

如何根据函数指针fp调用fp所指向的函数: (*fp)();

     fp是一个函数指针,那*fp就是该指针所指向的函数,所以(*fp)()就是调用该函数的方法。ansi c允许将上式简写为 fp()。

 

5. 注意语句结束标志的分号和switch语句中的break

 

6. 函数调用

 

在函数调用时即使不带参数,也应包括参数列表。例:f是一个函数,f(); 是一个函数调用;而f; 却是一个什么都不做的语句:计算f的地址,并不调用该函数。

 

 

 

 

抱歉!评论已关闭.