C语言进阶:C陷阱与缺陷(读书笔记四)

如果需要pdf文档,请私信我,我发给你,这本书今天读完了,说一下感受,如果只是入门的话,读完感受并不强烈,如果在工作了一段时间后,就会发现书中的错误确实是新手容易犯而且一些之前不理解的地方确实有了更新的认识,值得一读。

七、 可移植性缺陷

因为编译环境的不同,可移植性就成了一个重要话题,本节讨论几个最常见的错误来源。

1、 应对C语言标准变更

新标准无法在旧编译器中使用,为了增强可移植性,我们最好的做法在旧的环境和新的环境收益中做好选择。

2、 标识符名称的限制

不要用大写的函数名称与库函数同名,例如malloc和Malloc,假如你自己写的是Malloc,但是编译器如果不区分外部名称大小写,这里就会出错,要避免这种情况。

3、 整数的大小

非正式情况下short 与 int 是16位 long 是32位,这与机器的字符长度有关。
可移植性最好的办法就是声明该变量为long型,但在这种情况下我们去定义一个新的类型更加清晰:例如

typedef long tenmil;

4、 字符是有符号还是无符号整数

将char型转换为int型需要做出选择;如果要转换为有符号数,那么编译器将char类型扩展为int 型时需要复制符号位,如果是转换为无符号数,那么编译器只需要在多余的位上直接填充0即可。如果最高位是1,那么将这数定义成为无符号字符
,无论什么编译器,在该字符转换为整型时都只需在多余的位填充0即可。
一个常见错误:如果c是一个字符变量,使用(unsigned)c 强制类型转换成无符号整型,这里会出现错误。因为转换为无符号时,会先转换为int型,这里会得到非预期的结果。
正确的方法是(unsigned char)c;

5、 移位运算符

在向右移位时,空出的位是由0填充还是由符号位的副本填充?
如果将操作的变量声明为无符号类型,那么空出的位是由0填充,如果是有符号位,那么二者都可以。
移位计数(即移位操作的位数)允许的取值范围是什么?
如果被移位的对象是n位,那么移位计数应该大于0且小于n,为什么要加这个限制,因为加上这个限制后,我们就能够在硬件上高效地实现移位运算。

6、 内存位置为0

null指针并不指向任何对象,除非是用于赋值或比较运算,出于其他任何目的使用null指针都是非法的。

7、 除法运算时发生的截断

q=a/b
r=a%b
性质1:q*b+r==a;性质2:如果改变a的正负号,我们希望只改变q的符号,但不改变q的绝对值;性质3:当b>0时,我们希望r>=0且r<b;
这三条性质不可能同时在计算机中成立,所以在实现整数除法截断运算时,会放弃三条原则中的至少一条,一般是第三条。
最好是避免a为负数这样的情况,并且声明a为无符号数

8、 随机数的大小

与机器的整数长度有关,如果是32位,那么最大为2的31次方-1。
RAND_MAX为随机数的最大取值。

9、 大小写转换

使用宏定义
#define _toupper© (©+’A’-’a’)
#define _tolower© (©+’a’-’A’)

10、 首先释放、然后重新分配

malloc:申请分配一块新内存
realloc:指向已分配的内存,重新定义大小,可能涉及到内存的拷贝
free :释放内存

八、 建议

在代码编写中,如何减少程序错误,以下是一些通用的建议:

1、通用建议

1、不要说服自己相信错误
2、直接了当地表明意图
3、考察最简单的特例
4、使用不对称边界
5、注意潜伏在暗处的bug
6、防御性编程:能想到可能发生的错误就一定会发生,所以应做出规避
C陷阱与缺陷(读书笔记一)
C陷阱与缺陷(读书笔记二)
C陷阱与缺陷(读书笔记三)
C陷阱与缺陷(读书笔记总)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小师兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值