C Traps and Pitfalls

Chap 01 词法陷阱

1.=是赋值运算符,==表示相等判断。

2.&、|是位运算符号,&&、||是逻辑运算符。

3.词法分析的贪心发:每一个符号应该包含尽可能多的字符。所以:a---b《=》a-- -b。但是/*会理解为注释,例如:b=a/*p会被解析为b=a。

4.整型常量:以0开头的整型是八进制整数。

5.单引号引用的字符表示一整数,双引号引起的字符表示一个无名字符数组。

Chap 02 语法陷阱

1.理解函数声明:按照使用的方式来声明。

理解指针数组、指向数组的指针和函数、函数指针的关键在于()、[]的优先级别大于*。所以指向数组的指针int (*a)[3]需要加括号,函数指针int (*f)()需要加括号。

float* g(): float (*h)();其中g是一个函数,返回float *;h是指向函数的指针,返回float,参数为void。*h表示该函数,使用指向函数指针的方法为:(*h)()。

(*((void (*)())0))():首先将地址0转换为指向函数的指针(通过“void(*)()”,表示返回值是void的函数指针),然后通过(*f)()调用处于地址0处的函数。

PS1:关于typedef的使用:

|-定义一种类型的别名:typedef char* String; String c = null;

|-为复杂声明定义一个简单的别名:对于void(*b[10])(void(*)())其含义为:b[10]是函数指针数组,其指向的函数接受的参数为返回值为void类型的函数指针。使用typedef简化如下:

第一步:使用别名简化右边括号中(在*后面添加别名)

typedef void (*pFunParam)();

第二步:使用别名简化左边括号中的(在*后面添加别名)

typedef void (*pFun)(pFunParam)

使用如下:pFun b[10];

PS2:指针数组和指向数组的指针。

|-指针数组:int* a[3]:数组a中的元素是int类型的指针。

|-指向数组的指针:int (*a)[3]:a是指向长度为3,里面类型为int的指针。

2.优先级问题:r=hi<<4+low。+的优先级别高于<<。*p++《=》*(p++)。最好使用()。

3.注意语句结束的分号:if(a>b);《=》if(a>b){}。声明结构体、类时需要加上分号的原因是:如果不加分号,会认为是该结构定义类型之后的一个返回值。如:

Struct

{

int a;

}

main()

{

return 0

}

//不加分号导致结构体是为main函数的返回值。

4.switch后面的case如果不break会接着执行。

5.函数调用:f(),f表示该函数的地址。

6.else悬挂问题:else总是与最近的if结对,当然完整使用{}会解决else悬挂问题。

If(x==0)

If(y==0)

Error();

Else

{

Dosth();

}

//else不是跟x==0结合,而是跟y==0结合。

Chap 03 语义陷阱

1.数组的访问:

Int a[3];int *p = a;p、a、&a[0]都是指向数组a[3]首地址的指针。p++指向数组中的下一个位置。

2.字符串是包含字符串和结束符(\0)的数组,strlen输出字符长度,不包括结束符。sizeof用于计算数组长度,计算sizeof(字符串)时要包含’\0’。

3.C语言中将作为函数参数的数组声明转换为相应的指针声明,因此char s[]等价于char *s。

4.指针的赋值仅仅是指针指向的修改,不会产生新对象。

5.空指针#define NULL 0中空指针0或者NULL经常用作指针是否为空的比较,需要注意的是空指针绝对不能解引用dereference。

6.不对称边界:C语言中遵循左闭右开[x,y)的原则。

7.函数调用f(x,y)参数中的分隔符不是逗号运算符,因此不保证运算的先后(x,y执行顺序不一定)。但是f((x,y))中是逗号运算符,运算顺序确定。此外||和&&具有短路特性,也保证了运算的顺序从左到右。诸如如下语句也需要注意执行顺序的问题:

i=0;

while (i<n>{

y[i++] = x[i];

}

8.&/|/~是位运算符,||/&&是逻辑运算符,使用时最好使用括号。

9.判断int整数a+b的结果是否溢出:

If((unsigned)a+(unsigned)b>INT_MAX){}

INT_MAX定义在limit.h中。

10.记得为main函数返回值,0表示成功非,负数表示失败。

Chap 04 连接

1.连接器的作用:连接器的输入是c编译器生成的目标模块和库文件,输出是生成的载入模块。生成载入模块时需要对每个目标模块中的对象进行检查是否已经存在:不存在就载入,存在就进行冲突处理。

2.Int a;如果位于函数体外,就是外部对象a的定义,会分配存储空间,并可能会为其分配初始值0。Int a=7;定义并初始化。

extern int a;声明a为全局变量,并未分配空间。用于说明a是在其他地方定义并分配的。全局声明甚至可以出现在函数的内部,因为对于连接器而言,声明的变量是对变量的显示引用。有了外部声明就一定有一个地方对a进行定义:int a;

3.static int;static修饰符用于减少命名冲突,限定修饰对象的作用域在本文件内。Static同样可以修饰函数。

4.函数使用之前必须声明。声明函数可以不写参数而直接写类型。

5.使用extern进行声明是,类型要一致。Extern char* pc;和char pc[]=”abc”;是不同的声明类型。

6.extern声明的一般用法:.h头文件中生命对象,.c源文件中定义该对象。

Chap 05 库函数

1.getchar函数返回的是整数,因此注意接受时不要使用char。

2.fread、fwrite用于读、写文件。如果以读打开文件,然后在不关闭文件的情况下需要写,必须调用fseek改变文件的读写状态。

3.Setbuf用于设置缓冲区大小。但是为了防止程序结束时缓冲去数据丢失,可以设置缓存为静态数组或者动态申请数据但是不释放。调用fflush强制输出缓冲区内容。

4.可以使用errno确定库函数具体的出错原因。但是应该先检查函数返回值,然后使用errno判断具体的错误。因为库函数并不要求函数执行成功一定设置errno为0。

5.可以使用signal函数捕获异步事件。

Chap 06 预处理器

1.使用宏时注意多余的空格。#define f (x) abc或许不是我们想要的定义。

2.宏不是函数。使用时注意加括号。

3.宏不是语句。__FILE__和__LINE__是内置宏,表示文件名和代码行号。

4.宏不是类型定义。

Chap 07 可移植限制

1.标识符名称的限制:标识符如函数名可能会被截断,只保证固定的长度,因此print_int和print_double或许会冲突。

2.注意整数的大小,机器是多少位的。

3.注意字符、整数的符号,是不是unsigned。

4.注意移位运算符的补位。

5.注意内存位置0,某些机器禁止读取该位置。

6.注意出发运算发生的截断。

7.注意随机数大小。

8.注意大小写转换。

9.注意内存申请函数。

C陷阱和缺陷(C Traps and Pitfalls)-读书笔记相关推荐

  1. C陷阱与缺陷(C Traps and Pitfalls)学习笔记

    文章目录 3.3 作为参数的数组声明 3.4 避免举隅法 3.5 空指针并非空字符串 3.6 边界计算与不对称边界 3.7 求值顺序 3.8 运算符&&,|| 和 ! 3.9 整数溢出 ...

  2. 57、读C陷阱和缺陷(C Traps and Pitfalls)(三)

    5.预处理器 使用预处理器大致有两个方向的原因: (1)需要将某个变量在程序中所有实现的实例全部修改. 这一条在C++中已用const定义变量替代了. (2)宏处理,来替代一个简单的函数,如putch ...

  3. 《C Traps and Pitfalls》 笔记

    这本书短短的100多页,很象是一篇文章.但是指出的很多问题的确容易出现在笔试的改错题中 -------------------------------------------------------- ...

  4. 《C陷阱与缺陷》第三章阅读笔记

    语义"陷阱" 3.1 指针与数组 C语言中数组值得注意的地方有以下两点: 1.C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来.然而,C语言中数组的元素可以是 ...

  5. Java Pitfalls读书笔记1(语法)

    一  父类中的静态方法     1  Super s = new child();        数据类型是Super,但是依旧是child实力,相当于被强制转换成Super类型的实例.     2  ...

  6. java pitfalls读书笔记

    以前做的笔记,供需要的朋友参考 刚从图书馆借了几本不错的java经典书籍,翻了翻,做了一些摘抄比较. ·实例方法被覆盖,静态方法被隐藏,即静态方法不能被覆盖 ·试图用子类的静态方法隐藏父类中同样标识的 ...

  7. c陷阱与缺陷第三章——Semantic Pitfalls

    c陷阱与缺陷第三章--Semantic Pitfalls 3.1 Pointers and array Array a[i] == i[a] Array subscripting Constrains ...

  8. 《C语言陷阱和缺陷》笔记

    原著:Andrew Koenig - AT&T Bell Laboratories Murray Hill, New Jersey 07094 翻译:lover_P 修订:CQBOY 来自:h ...

  9. 《C陷阱与缺陷》一导读

    前 言 C陷阱与缺陷 对于经验丰富的行家而言,得心应手的工具在初学时的困难程度往往要超过那些容易上手的工具.刚刚接触飞机驾驶的学员,初航时总是谨小慎微,只敢沿着海岸线来回飞行,等他们稍有经验就会明白这 ...

最新文章

  1. 深度学习--TensorFlow(5)BP神经网络(混淆矩阵、准确率、精确率、召回率、F值)
  2. procexp.exe中文版---Process Explorer 进程监视V11.21中文版
  3. 设计模式心得笔记--简单工厂
  4. angularjs 学期下拉列表指令
  5. ASP.NET中常用到的27个函数集
  6. 遗传算法与直接搜索工具箱学习笔记 -----从直接搜索算法开始
  7. 关于dell - R710的磁盘管理
  8. 云数据库MongoDB全面支持3.4版本,支持多存储引擎
  9. POJ 3207 Ikki's Story IV - Panda's Trick (POJ 六道2-SAT之一)
  10. Mysql UTF8 varchar与Oracle ZHS16GBK varchar2同长度下存汉字的差异
  11. 科学地花钱:基于端智能的在线红包分配方案 (CIKM2020)
  12. MVC架构设计——EF-Code First
  13. ACM MM2018 Best Paper 被华人包揽
  14. 最新版FFmpeg移植Android:编译so库(基于NDK r20和FFmpeg-4.1.0)
  15. 安卓编程 Sqlite的入门编程
  16. python词云词频分析_Python数据挖掘:WordCloud词云配置过程及词频分析
  17. 戴尔服务器u盘装系统看不见磁盘,戴尔电脑u盘装系统找不到硬盘怎么解决
  18. scrapy重试机制_Scrapy项目之User timeout caused connection failure(异常记录)
  19. 2022年茶艺师(初级)考试试卷及茶艺师(初级)模拟试题
  20. Pulsar Summit Asia 2020 | 场景案例论坛(上):多行业,多场景

热门文章

  1. 基于WebGL的球体纹理贴图实现全景展示
  2. 前端使用js实现新年(元旦)倒计时
  3. 2019牛客多校第八场
  4. Heritrix1.14.4安装配置和使用
  5. 解决报错ImportError: unique_cuda.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZN6caffe28T
  6. C语言(求圆柱体的体积)
  7. 数据结构基础篇-链表反转(非递归与递归)C++实现
  8. java多层map遍历_java中map的多层遍历
  9. ASP.NET印刷行业印务管理系统,源码免费分享
  10. nginx格式化工具