看完《C陷阱与缺陷》,忍不住要重新翻一下,记录一下与自己的惯性思维不符合的地方。记录的是知识的增量,是这几天的流量,而不是存量。
这本书是在ASCI C/C89订制之前写的,有些地方有疏漏。

第一章 词法陷阱

  • 1.3 C语言中解析符号时使用贪心策略,如x+++++y将被解析为x++ ++ +y,并编译出错。
  • 1.5 单引号引起的一个字符代表一个对应的整数,对于采用ASCII字符集的编译器而言,'a'与0141、97含义一致。
  • 练习1.1 嵌套注释(如/*/**/*/)只在某些C编译器中允许,如gcc4.8.2编译时是不支持的。

第二章 语法陷阱

  • 2.6 else始终与同一个括号内最近的未匹配的if结合

第三章 语义陷阱

  • 3.1 int a[12][31]表示的是一个长度12的数组,每个元素是一个长度31的数组。
  • 3.1 在需要指针的地方如果使用数组名来替换,那么数组名就被视为其下标为0的元素的指针,p = &a的写法是非法的(gcc4.8.2只是警告)。
  • 3.2 如何连接两个给出的字符串s、t?细节很重要,书中给出的答案如下:
char *r,*malloc()//原文称不能直接声明一个s、t长度之和的数组,但c99可以声明变长数组,已经可以了
//记得要把长度加1
r = malloc(strlen(s) + strlen(t) +1);//必须判断内存是否分配成功
if(!r){complain();exit(1);
}strcpy(r,s);
strcat(r,t);......//完成之后一定要释放r
free(r);
  • 3.6 如何正确计算数组的边界?原则一,考虑最简单情况下的特例;原则二,仔细计算边界。
  • 3.6 以下一段代码为何引起死循环?这是因为在内存地址递减时,a[10]就是i。
    int i,a[10];
    for(i = 1; i<=10; i++)
    a[i] = 0;
  • 3.6 边界的编程技巧:用第一个入界点和第一个出界点表示数值范围,即[low,high)。这样的效果是
    • 取值范围的大小为两者之差。
    • 若取值范围为空,则上界等于下界。
  • 3.6 --n一般比n--执行速度更快。
  • 3.7 运算符&&和||保证两个操作数从左至右求值,其他运算符的操作数求值顺序未定义。比如y[i] = x[i++]结果是未定义的。
  • 3.9 如何检测a+b是否溢出?
    • if(a+b < 0)是不正确的,因为溢出时的行为是未定义的。正确的方法是将两者转换为unsigned型与INT_MAX比较
    • 更巧妙的方法:if(a > INT_MAX - b)

第四章 连接

  • 4.2 int a若出现在所有函数体之外,则完成了声明与定义(分配存储空间)。而extern int a;只是声明,说明a的存储空间是在其他地方分配的,不是定义;因此必须在别的某个地方定义,同一个或不同的源文件均可。
  • 4.3 static修饰符可以将一个函数或变量的作用域限制在一个源文件之内,不会与其他文件中的同名量发生冲突
  • 4.5 声明与定义必须严格相同,而数组和指针是不同的。
  • 4.6 如何避免声明与定义不符?遵守“每个外部对象只在一个地方声明”的规则即可。一般放在头文件中,所有用到此外部对象的源文件都要包括此头文件,定义此对象的文件也应该包括此头文件。

第五章 库函数

  • 5.1 getchar()返回整数,不能把返回值赋值给char型变量再与EOF比较,因为EOF定义为-1,应该赋值给int型变量。
  • 5.2 如果要对文件进行连续的read和write操作,则中间必须插入fseek函数调用。
  • 5.3 setbuf(stdout, buf);可以强制将buf指向的char数组设为缓冲区,改变输出缓存大小。
  • 5.3 书中使用缓冲区把stdin的内容复制到stdout的程序是错误的,因为缓冲区内容的写出直到缓冲区满或调用fflush才开始完成。可以把buf声明为静态的或者malloc在堆中,防止main函数结束后buf清空。
  • 5..1 一个程序异常终止时,程序输出的最后一部分常常丢失,可以使用setbuf指向一个空指针作为缓冲区
  • 5..2 putchar/getchar在stdio.h中使用宏实现,如果没有包括stdio.h,很大可能仍能运行,但是使用相应的函数代替,速度降低。

第六章 预处理器

  • 6 宏只是对文本处理,是一个表达式,不是函数或语句
  • 6.1 宏定义最好把每个参数和整个表达式使用括号括起来防止出错。
  • 6.2 如果一个操作数在两个地方用到,将被求值两次。解决方案:操作数应该没有副作用;将宏实现为函数。
  • 6.2 宏可能产生非常庞大的表达式。
  • 6.3 宏的分号的使用很麻烦,assert的一种正确实现:#define assert(e) ((void)((e)||_assert_error(__FILE__,__LINE__)))
  • 6.4 typedef struct foo FOOTYPE是类型定义语句,定义了一个新的类型。

第七章 可移植性缺陷

  • 7.4 编译器实现可能将字符当作有符号或无符号的。char转换为int时结果未定义,可以使用unsigned char避免。
  • 7.4 将字符变量转换为无符号整数时应该使用(unsigned char)c而不是(unsigned)c,后者将c转换为int再转换为unsigned int。
  • 7.5 除法运算速度大大慢于移位。
  • 7.7 整数除法运算时,仅规定商 x 除数 + 余数 == 被除数,大多数实现在负数的除法时,只保证余数与被除数正负号相同,商与被除数的符号无关。应尽量使n为无符号数。
  • 7.9 toupper/tolower函数均采用int型参数,实现时要检查输入是否符合要求,采用置位实现非常快速。
  • 7.11 要求一个按位输出long型数字。需要考虑:不能对-n求值,可能溢出(边界条件),应该把n转换为负的再处理;余数的符号未知,应做归一化处理。
  • 7..2 atoi函数把字符串转换为long型整数,应该按照负数来处理以避免溢出。

  

转载请注明作者:Focustc,博客地址为http://blog.csdn.net/caozhk,原文链接为点击打开

阅读《C陷阱与缺陷》的知识增量相关推荐

  1. 【知识点总结】-《C陷阱与缺陷》

    目录 第一章:词法的陷阱 1.1."="与"=="不同: 1.3词法分析的"贪心法": 1.4整型常量: 1.5字符与字符串: 第二章:语法 ...

  2. 《C陷阱与缺陷》学习笔记(2):作者有话说

    道阻且长,行则将至.埋头苦干,不鸣则已,一鸣惊人!加油,骚年! 1 参考资料 1.书本参考资料 <C陷阱与缺陷>前言: 2.网络参考资料 [维基百科]Andrew Koenig:https ...

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

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

  4. C语言三剑客之《C陷阱与缺陷》一书精华提炼

    点击上方"大鱼机器人",选择"置顶/星标公众号" 福利干货,第一时间送达! 1.C陷阱与缺陷概述 C语言像一把雕刻刀,锋利,并且在技师手中非常有用.和任何锋利的 ...

  5. c语言局限性,C语言陷阱与缺陷.pdf

    C 语言陷阱和缺陷[1] winxos 11-01-28 winxos 11-01-28 原著:Andrew Koenig - AT&T Bell Laboratories Murray Hi ...

  6. 写给大数据从业者:数据科学的5个陷阱与缺陷

    来源 | AI 前线 作者 | 陈炬,责编 | Carol 出品 | CSDN云计算(ID:CSDNcloud) 导读: 这篇分享主要总结了数据从业人员在实践中可能遇到的陷阱与缺陷.跟其他新起的行业一 ...

  7. 《C陷阱与缺陷》一第1章 词法“陷阱”1.1 =不同于==

    本节书摘来自异步社区<C陷阱与缺陷>一书中的第1章,第1.1节,作者 [美]Andrew Koenig,更多章节内容可以访问云栖社区"异步社区"公众号查看 第1章 词法 ...

  8. c语言 去掉双引号_技术分享|浅谈C语言陷阱和缺陷

    良好的软件架构.清晰的代码结构.掌握硬件.深入理解C语言是防错的要点,人的思维和经验积累对软件可靠性有很大影响.C语言诡异且有种种陷阱和缺陷,需要程序员多年历练才能达到较为完善的地步.软件的质量是由程 ...

  9. 《C陷阱与缺陷》学习笔记

    第一章 词法陷阱 笔记本:<C陷阱与缺陷> 创建时间:2018/4/23 22:06:21                                                  ...

最新文章

  1. android 崩溃搜索 AndroidRuntime
  2. Microbit-高温报警系统
  3. Struts2是什么?Struts2的优势有哪些?
  4. 用于 Keras 用户使用的 TensorFlow.js layers API
  5. html 放到底部,html – 将元素放在页面底部
  6. 高性能中级维修电工及技能培训考核实训装置
  7. fpga学习——zynq图像处理中的DVP流接口封装
  8. 数据库 关系代数表达式
  9. python中def func是什么意思_python中的函数def和函数的参数
  10. 电脑小知识:如何选择合适的内存条?如何查看自己电脑内存条的内存大小和主频呢?
  11. HTML特效代码大全
  12. 【模式识别】Boosting
  13. python自动化发送邮件_使用python自动化发送邮件
  14. magnify.m —— 图像局部放大镜工具函数
  15. 棋类对战小游戏(VS2012 MFC基于对话框)
  16. 开启Intel VT-x
  17. 三菱plc搭配四轴雅马哈机械手在线检测收料案例
  18. 计算一年有多少个周,每个周的开始日期和结束日期是什么
  19. 用Python做“电费计算.exe”,并保存数据到Excel
  20. 自然语言处理NLP星空智能对话机器人系列:深入理解Transformer自然语言处理 Training a GPT-2 language model Steps 2 to 6

热门文章

  1. promise封装读取文件
  2. 服务器按ctrl alt delete没有用_详细教程——用PS制作直邮广告
  3. 未找到 arp 项。_高新热力公司抢工期保供暖 42项新建改造项目全部完工
  4. 设计模式(二)--里氏替换原则(Java的继承规范)
  5. Linux卸载搜狐,搜狐的linux笔试题
  6. unity 中文_Unity无情大爆料时间Unity3D的脚本语言
  7. linux查看进程中的线程名,linux 怎么样查看一个进程的线程
  8. 新娘JAVA_Java之趣味编程结婚问题
  9. android 单选按钮横置,input radio如何实现横向布局
  10. mac 允许任何源 软件安装 -- 在安全模式中没有显示