阅读《C陷阱与缺陷》的知识增量
版权声明:本文为Focustc原创文章。转载请注明作者及出处。 https://blog.csdn.net/caozhankui/article/details/35925939
看完《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
表示的是一个长度12的数组,每一个元素是一个长度31的数组。
a[12][31] - 3.1 在须要指针的地方假设使用数组名来替换,那么数组名就被视为其下标为0的元素的指针,
p
的写法是非法的(gcc4.8.2仅仅是警告)。
= &a - 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
是不对的,由于溢出时的行为是没有定义的。正确的方法是将两者转换为unsigned型与INT_MAX比較
< 0)- 更巧妙的方法:
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指向的char数组设为缓冲区,改变输出缓存大小。
buf); - 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 整数除法运算时。仅规定
商
。大多数实如今负数的除法时。仅仅保证余数与被除数正负号同样,商与被除数的符号无关。应尽量使n为无符号数。
x 除数 + 余数 == 被除数 - 7.9 toupper/tolower函数均採用int型參数,实现时要检查输入是否符合要求。採用置位实现非常高速。
- 7.11 要求一个按位输出long型数字。须要考虑:不能对-n求值。可能溢出(边界条件),应该把n转换为负的再处理;余数的符号未知。应做归一化处理。
- 7..2 atoi函数把字符串转换为long型整数。应该依照负数来处理以避免溢出。
转载请注明作者:Focustc,博客地址为http://blog.csdn.net/caozhk,原文链接为点击打开
阅读《C陷阱与缺陷》的知识增量的更多相关文章
- C语言学习书籍推荐《C陷阱与缺陷》下载
下载地址:点我 凯尼格 (作者), 高巍 (译者) <C和C++经典著作:C陷阱与缺陷>适合有一定经验的C程序员阅读学习,即便你是C编程高手,<C和C++经典著作:C陷阱与缺陷> ...
- 读书笔记--C陷阱与缺陷(七)
第七章 1.null指针并不指向任何对象,所以只用于赋值和比较运算,其他使用目的都是非法的. 误用null指针的后果是未定义的,根据编译器各异. 有的编译器对内存位置0只读,有的可读写. 书中给出了一 ...
- 读书笔记--C陷阱与缺陷(一)
要参与C语言项目,于是作者只好重拾C语言(之前都是C++,还是C++方便). 看到大家都推荐看看 C陷阱与缺陷(C traps and pitfalls),于是好奇的开始了这本书的读书之旅. 决定将 ...
- C陷阱和缺陷学习笔记
这段时间把<C陷阱和缺陷>看了,没时间自己写总结.就转一下别人的学习笔记吧http://bbs.chinaunix.net/thread-749888-1-1.html Chapter 1 ...
- Spring Cloud微服务实战阅读笔记(一) 基础知识
本文系<Spring Cloud微服务实战>作者:翟永超,一书的阅读笔记. 一:基础知识 1:什么是微服务架构 是一种架构设计风格,主旨是将一个原本独立的系统拆分成多个小型服务 ...
- [C陷阱和缺陷] 第1章 词法“陷阱”
有感自己的C语言在有些地方存在误区,所以重新仔细把"C陷阱和缺陷"翻出来看看,并写下这篇博客,用于读书总结以及日后方便自身复习. 第1章 词法"陷阱" 1.1 ...
- 《C陷阱与缺陷》阅读笔记(个人版)
笔记: 第一章:词法陷阱 提倡显示比较if((x = y) != 0) foo(); 第二章:语法陷阱 已知一个类型的声明 该类型的类型转换:吧声明中的变量名和声明末尾的分号去掉,再将剩余的部分用括号 ...
- [C陷阱和缺陷] 第3章 语义“陷阱”
第3章 语义"陷阱" 一个句子哪怕其中的每个单词都拼写正确,而且语法也无懈可击,仍然可能有歧义或者并非书写者希望表达的意思.程序也有可能表面上是一个意思,而实际上的意思却相 ...
- 《C陷阱与缺陷》读书笔记
1. 词法“陷阱” = 不同于 == , 可以通过if( 1 == a )来避免 & | 不同于 && || 词法分析中的“贪心法” 编译器将程序分解成符号的方法是,从左到右一 ...
随机推荐
- 【转】WEB安全之渗透测试流程
熟悉渗透流程,攻击会像摆积木一样简单! 0x 01:信息收集 收集网站信息对渗透测试非常重要,收集到的信息往往会让你在渗透中获得意外惊喜. 1. 网站结构 可以使用扫描工具扫描目录,主要扫出网站管理员 ...
- [转]Newtonsoft JSON how to dynamically change the date format?
本文转自:http://www.howtobuildsoftware.com/index.php/how-do/cg8K/jsonnet-newtonsoft-json-how-to-dynamica ...
- java 散列运算浅分析 hash()
文章部分代码图片和总结来自参考资料 哈希和常用的方法 散列,从中文字面意思就很好理解了,分散排列,我们知道数组地址空间连续,查找快,增删慢,而链表,查找慢,增删快,两者结合起来形成散列 ...
- 【Hadoop系列】linux下 root用户免密码登录远程主机 ssh
SSH原理:[Hadoop系列]linux SSH原理解析 操作环境: CentOS 6.5 操作对象: 用户A主机和远程主机B 正文部分:斜体加粗代表linux指令. linux下 非root用户免 ...
- Spring学习笔记:Spring动态组装打印机
一.如何开发一个打印机 1.可灵活配置使用彩色魔盒或灰色魔盒 2.可灵活配置打印页面的大小 二.打印机功能的实现依赖于魔盒和纸张 三.步骤: 1.定义墨盒和纸张的接口标准 package cn.pri ...
- 【转】spring boot使用Druid和监控配置
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012100371/article/details/76602612 Druid是Java语言中最好 ...
- javaweb带父标签的自定义标签
1.完整的示例代码:要实现的功能是父标签中有name属性,子标签将父标签的name属性值打印到jsp页面上. 1.1 父类和子类的标签处理器类 testParentTag.java package c ...
- Bzoj1498&1416: [NOI2006]神奇的口袋
什么鬼双倍经验题??? Sol 考虑在第\(k\)次摸到\(y\)的概率 如果上次摸到\(y\),目前有\(sum\)个球,\(y\)有\(a[y]\)个,那么概率就是\(\frac{a[y]+d}{ ...
- Python基础-简介二
一.变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些 ...
- SSIS 使用OLEDB/ADO NET Source 数据流source控件 连接Oracle失败
在做数据提取的时候发现一个非常奇怪的问题. Oracle客户端是安装正确并且Toad可以正常运行的,但是在新建OLEDB/ADO NET Source 数据流source控件连接Oracle的时候一直 ...