第二章 语法陷阱

2.1 理解函数声明

(*(void(*)())0)();
任何C变量的声明都由两部分组成:类型以及一组类似表达式的声明符。
一旦我们知道了如何声明一个给定类型的变量,那么该类型的类型转换符只需要添加一个括号即可的到。
例如 float (*h)();表示h是一个指向返回值为浮点类型的函数的指针。
因此(float (*h)())表示一个"指向返回值为浮点类型的函数的指针"的类型转换符。

第一步假设fp是一个函数指针,那么通过(*fp)()调用fp所指向的函数,可以简写问fp()。
在表达式(*fp)()中,*fp两侧的括号非常重要,因为函数运算符()的优先级高于单目运算符*。
如果没有括号则*fp()效果等同于*((*fp)())的简写形式。
我们本意是(*0)();但是上式并不能生效,因为运算符*必须要一个指针来做操作数。而且这个指针还应该是一个函数指针。
因此在上式中必须对0作类型转换。

如果fp是一个指向返回值为void类型的函数的指针,那么(*fp)()的值为void,fp的声明如下:void (*fp)();
将常数0转型为“指向返回值为void的函数的指针”类型,可以这样写:(void (*)())0

2.2 运算符的优先级问题

优先级最高者其实并不是真正意义上的运算符,包括:数组下标、函数调用操作符各结构成员选择操作符。它们都是从左到右结合。
单目运算符的优先级仅次于前述运算符。单目运算符是从右到左。
接下来就是双目运算符。其中,算术运算符的优先级最高,移位运算符次之,关系运算符再次之,接着就是逻辑运算符、赋值运算符。
再下来就是三目运算符即条件运算符。

任何两个逻辑运算符都具有不同的优先级,每个与比每个或优先级高。
所有赋值运算符的优先级都是一样的从右到左。
在所有的运算符中,逗号运算符的优先级最低。

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

在if或者while语句之后需要紧跟一条语句时,如果此时多了一个分号,那么原来紧跟在if或者while子句之后的语句就是一条单独的语句,与条件判断部分没有了任何关系。
还有一种情形,当一个声明的结尾紧跟一个函数定义时,如果声明结尾的分号被省略,编译器可能会把声明的类型视作函数的返回值类型。
例如
struct log{
int date;
int time;
int code;
}
main()
{
  ...
}
上面代码实际的效果是声明函数main的返回值是结构log类型。

2.4 switch语句

C语言的switch语句的控制流程能够依次通过并执行各个case部分,要注意使用break语句及时把case中断。
我们可以在不添加break的部分添加一行注释  /*此处没有break语句*/

2.5 函数调用

f();是一个函数调用语句
f;这个语句计算函数f的地址,却并不调用该函数。

2.6 悬挂else引发的问题

else的原则是就近原则。

C语言允许初始化列表中出现多余的符号,例如
int das[]={31,28,31,};

C陷阱与缺陷(二)的更多相关文章

  1. C陷阱和缺陷学习笔记

    这段时间把<C陷阱和缺陷>看了,没时间自己写总结.就转一下别人的学习笔记吧http://bbs.chinaunix.net/thread-749888-1-1.html Chapter 1 ...

  2. 阅读《C陷阱与缺陷》的知识增量

    版权声明:本文为Focustc原创文章.转载请注明作者及出处. https://blog.csdn.net/caozhankui/article/details/35925939 看完<C陷阱与 ...

  3. 读书笔记--C陷阱与缺陷(一)

    要参与C语言项目,于是作者只好重拾C语言(之前都是C++,还是C++方便). 看到大家都推荐看看  C陷阱与缺陷(C traps and pitfalls),于是好奇的开始了这本书的读书之旅. 决定将 ...

  4. 读书笔记--C陷阱与缺陷(七)

    第七章 1.null指针并不指向任何对象,所以只用于赋值和比较运算,其他使用目的都是非法的. 误用null指针的后果是未定义的,根据编译器各异. 有的编译器对内存位置0只读,有的可读写. 书中给出了一 ...

  5. [C陷阱和缺陷] 第1章 词法“陷阱”

    有感自己的C语言在有些地方存在误区,所以重新仔细把"C陷阱和缺陷"翻出来看看,并写下这篇博客,用于读书总结以及日后方便自身复习. 第1章 词法"陷阱" 1.1 ...

  6. C语言学习书籍推荐《C陷阱与缺陷》下载

    下载地址:点我 凯尼格 (作者), 高巍 (译者) <C和C++经典著作:C陷阱与缺陷>适合有一定经验的C程序员阅读学习,即便你是C编程高手,<C和C++经典著作:C陷阱与缺陷> ...

  7. 《C陷阱与缺陷》整理二

    1.数组名作实參     在C语言中,我们没有办法将一个数组作为函数參数传递,假设我们使用数组名作为參数.这个时候数组名立马会被转换为指向该数组的第一个元素的指针.     关于这一点的理解能够向前深 ...

  8. 读书笔记--C陷阱与缺陷(二)

    第二章 1. 理解函数声明 书中分析了复杂的类型声明方式,也说明了使用typedef声明会更好理解,推荐大家使用typedef进行函数声明. 书中类型分析一层一层挖掘,让读者可以理解多层嵌套的类型含义 ...

  9. 程序员必知的Python陷阱与缺陷列表

    本文关注的主要是python陷阱,具体而言,是指CPython,而且除非特别说明,所有代码示例都是在python2.7运行的. 我个人对陷阱的定义是这样的:代码看起来可以工作,但不是以你“想当然“”的 ...

随机推荐

  1. sqlplus conn远程连接

    oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v11_2_0oracle.in ...

  2. [置顶] fmt日期格式化

    jstl中的日期格式化 <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> & ...

  3. 高效率JavaScript编写技巧

    最近在编写一个JavaScript框架,发现有很多细节注意得不够,担心长时间积累会导致框架实际应用的时候出现严重的效率问题.于是开始关注JavaScript提高效率的一些技巧,在这里分享给大家. 1. ...

  4. MySQL具体解释(19)----------海量数据分页查询优化

    分页的详细解说解说请看http://blog.csdn.net/u011225629/article/details/46775947 查看代码打印1 SELECT * FROM table ORDE ...

  5. HDU2546:饭卡(01背包)

    HDU2546:饭卡 http://acm.hdu.edu.cn/showproblem.php?pid=2546 当我们遇到问题选择物体的价值和顺序相关时就需要,排完序后对其01处理.这题因为当我们 ...

  6. C#获取时间的函数

    //获取日期+时间DateTime.Now.ToString();            // 2012-9-4 20:02:10DateTime.Now.ToLocalTime().ToString ...

  7. UltraISO做U盘启动盘教程

    用UltraISO做U盘启动盘教程 注意:制作前请先备份u盘内重要文件 vista.win7系统需要以管理员身份运行UltraISO,其他系统直接运行即可 1.打开UltraISO选择iso镜像文件 ...

  8. 表单验证插件 jquery.validata 使用方法

    参考资料:http://www.runoob.com/jquery/jquery-plugin-validate.html 下载地址 jquery.validate插件的文档地址http://docs ...

  9. IS-A 和 HAS-A

    IS-A关系 IS-A就是说:一个对象是另一个对象的一个分类. 下面是使用关键字extends实现继承. public class Animal{ } public class Mammal exte ...

  10. les nationalités et les pays

    masculin  féminin pays français  française  la France chinois  chinoise  la Chine   suisse  suisse  ...