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

如果读起来感觉很吃力,那我推荐你读一读书,书上的例子比较多,看着能轻松一点,老鸟看起来应该不是很难,作为复习一下,应该还不错,5min可以看完。

五、 库函数

1、 返回整数的getchar函数

尽量使用系统头文件
1、返回整数的getchar函数

char c;
while((c=getchar())!=EOF)
putchar(c);

这个存在三种可能:
1)某些合法的输入字符在被”截断“后使得c的取值与EOF相同,程序将在文件复制的中途终止。
2)c取不到EOF这个值,程序将陷入死循环。
3) 因为巧合可以工作。

2、更新顺序文件

访问文件时,不能同时进行读写操作,如果想要同时进行,必须插入fseek函数调用。
类似:

read
seek
write
seek

第二次的seek改变文件状态,使得下一次文件可以正常读写。

3、缓冲输出与内存分配

setbuf(stdout,buf);可以将输出暂存起来,然后大块写入
使用时,为了避免错误,可以用两种方法:
1)将缓冲区成为静态数组,例如 static char buf[BUFSIZE];setbuf(stdout,buf);
2)动态分配缓冲区,例如:setbuf(stdout,malloc(BUFSIZE));

4、 使用errno检测错误

正确使用errno的方式

/*调用库函数*/
if(返回的错误值)
检查 errno;

5、 库函数signal

signal(signal type,handler function);
捕获异步事件的一种方式,信号非常复杂,而且具有一些从本质上而言不可移植的特性,我们要让signal处理函数尽可能简单。
例如: 打印一条错误消息,然后直接exit退出程序。

六、 预处理器

预处理器的重要性可以由两个主要的原因说明:
1)预处理器可以实现只需要改动一处数值,便可将用到该值的地方的所以地方都修改,将这个数定义为显式常量。
2)没有函数调用带来的系统开销

1、 不能忽视宏定义中的空格

1、不能忽视宏定义中的空格
例如:

#define  f  (x)  ((x)-1)

f(x) 代表 ((x)-1) 错误
f 代表 (x) ((x)-1) 正确
#define f(x) ((x)-1)
这样才能实现 f(x) 代表 ((x)-1)

2、 宏并不是函数

宏定义中最好把每个参数都用括号括起来,来避免错误。
例如

#define abs(x)  x>0?x:-x

abs(a)+1 会得到 a>0 ? a : -a+1
但我们的本意不是这样。
如果宏实现比较复杂,那么尽量使用函数来实现。
宏的展开可能会产生庞大的展开式。

3、 宏并不是语句

这里的例子有点晦涩,不知如何表达,只是记住宏并不能直接当作语句去使用,并且要注意分号即可。

4、 宏并不是类型定义

#define FOOTYPE	struct foo 
FOOTYPE a;
FOOTYPE b,c;

这样我们只需要修改一行代码就可以改变abc的类型,但是我们并不推荐如此使用,最好还是使用类型定义

typedef  struct foo   FOOTYPE;

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、付费专栏及课程。

余额充值