《C陷阱与缺陷》2章:语法陷阱

2.1 理解函数声明

       这一部分是这章的难点,也是容易迷惑的地方。

       声明变量float f,g;float ((f)); 其含义是((f))的类型是浮点类型,()不影响类型,所以f也是浮点类型。float *pf; 这个声明的含义是*pf是一个浮点数,所以pf是一个指向浮点数的指针。float *g(), (*h)(); g是一个函数,该函数的返回值类型为指向浮点数的指针。h是一个函数指针,h所指向函数的返回值为浮点类型。

       一旦知道了如何声明一个给定类型的变量,类型的类型转换符就容易得到:只需要把声明中的变量名和声明末尾的分号去掉,再将剩余部分用一个括号封装起来即可。如:float (*h)(); 表示h是一个指向返回值为浮点类型的函数指针,(float (*)())表示一个“指向返回值为浮点类型的函数的指针”的类型转换符。

       所以,开头那个(*(void(*)())0)()就好理解了。中间的(void(*)())为类型转换符,将常数0转型为“指向返回值为void的函数的指针”类型。之后(*fp)()就是函数调用,其中fp为(void(*)())0。

       对于后面的signal库函数声明的讲解,我觉得该书翻译的前后不一样。比如前面还说signal返回值类型为void,后面又说该函数返回值为函数指针,这点极易让读者迷惑。经过网上查阅我是这样理解的。首先,写出该函数的声明:void ( *signal( int, void (*)( int ))) ( int ); 从里往外讲,void (*)( int )为用户定义的函数指针类型,其为signal的函数的第二个参数,所以signal( int, void (*)( int ))为signal函数的函数调用,且返回类型为函数指针,指向的函数接受一个整型参数 且没有返回值,其实就是指向它第二个参数函数的指针。因为我们声明函数指针是void (*sfp)(int);,所以signal函数的声明就是void ( *signal( int, void (*)( int ))) ( int );

2.2 运算符的优先级问题

       优先级规则:

       优先级最高的包括:数组下标、函数调用操作符各结构成员选择操作符。结合规则是自左于右结合。例如a.b.c含义是(a.b).c而不是a.(b.c)。

       单目运算符的优先级仅次于上面。而且结合规则是自右至左结合。比如*p++就是*(p++)。

       接下来是双目运算符。其中,算术运算符的优先级最高,移位运算符次之,关系运算符再次之,接着逻辑运算符,赋值运算符,最后条件运算符。

       最重要两点:

       1.任何一个逻辑运算符的优先级低于任何一个关系运算符。

       2.移位运算符的优先级比算术运算符要低,但是比关系运算符要高。

       关系运算符中==和!=优先级低于其他的关系运算符的优先级。

       我认为最重要的是赋值运算符在常用运算符中是最低的,这个容易引起错误。

2.3 注意作为语句结束标志的分号

       结束标志的分号有时候会引起不可预料的问题。书上我觉得比较有用的是

              struct logrec{

              }

              main(){  

              }

       第一个}后面的;号丢了则会跟main联系起来,要求main函数的返回值是结构logrec类型。

2.4 switch语句

       C语言的case只是一个标号,需要在每个case后面加上break;来结束整个switch过程。这样做有自己的优点。比如:一个编译器在查找符号时跳过程序中的空白字符。

              case ‘\n':

                     linecount++;

                     /*  此处没有break语句  */

              case '\t':

              case ' ':

2.5 函数调用

       f();是一个函数调用语句。而f;是一个什么也不做的语句。

2.6 “悬挂”else引发的问题

       C语言中else始终与同一个对括号内最近的未匹配的if结合。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值