linux下C语言开发16,考虑问题要面面俱到
发表于: 2019-01-07 18:26:16 | 已被阅读: 94 | 分类于: Linux笔记
在前面 15 节的介绍中,我们写了不少 linux 中的C语言程序。相信大家也发现了,即使再简单的C语言程序,也是有可能写错的,毕竟人不是机器。
linux 中的程序错误
写C语言程序出的错千奇百怪,有的是手误写错了符号,有的是头脑发热写反了逻辑,甚至有时还会写错数字。语法错误,编译器能够直接指出,对照着修正没有什么难度。逻辑出错的程序才叫人头疼,这类程序能够编译通过,却得不到正确结果,因为没有编译器帮忙,只能由程序员自己去找错误修正。

程序逻辑出错大体可以分为两种:
- 一是出错时,程序不会退出,可以继续往下执行。例如调用 open 函数打开文件失败,程序不会退出,还能执行程序员设定的错误处理语句,例如打印错误信息等。
- 一是一旦出错,程序就直接崩溃退出。比如非法操作内存引起的段错误(这种错误在大型项目开发中经常出现),再例如把 0 当作被除数的浮点错误等。
第一种错误可以勉强认为是预料之中的错误。以 open 函数为例,在定义 open 函数时就已经考虑可能会出现的各种情况了:大多数情况下,open 函数能够成功打开文件。但是在权限不足,或者打开方式不正确时,的确会出现 open 函数打开文件失败的情况。
程序员在定义 open 函数时,会尽力将所有可能的情况都纳入考虑,最后看起来好像 open 函数本身就具有处理错误的能力,输入 man 命令查询其手册:

不管成功还是出错,open 函数都告诉计算机该如何处理,所以即使出错,程序也不会意外退出。


第二种错误则完全出乎意料之外了。程序员之前没有考虑到这种情况,所以没有告诉计算机该如何处理,死板的计算机自己又懒得思考,所以出现这种错误时,直接草草结束掉程序了事。
例如,程序员不小心让 0 做被除数了:
#include <stdio.h>
int main()
{
int a = 8/0;
printf("%d\n", a);
return 0;
}
这时程序处理不了 8/0 的计算,只好罢工,直接退出:

设计程序要考虑全面
第二种错误的症结往往很隐蔽,要从几万行甚至几十万行代码中找出错误的原因,难度可想而知。所以,程序员在编写代码时,要将所有可能会发生的事情都考虑到,否则就可能会出现第二种错误。
例如下面这个问题:
编写 C语言程序,取 100 个最大值为 10 的随机数 num,打印出 100/num 的值。
这个问题是简单的,很快就能写出程序:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char i, j = 100;
while(j--){
i = rand()%10;
printf("num %d: %d\n", 100-j, 100/i);
}
return 0;
}


所以,程序员一定要足够细心,把所有可能的情况都要考虑到。以上代码可以改写为:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char i, j = 100;
while(j--){
i = rand()%10;
if(i)
printf("num %d: %d\n", 100-j, 100/i);
else
printf("num %d: inf\n", 100-j);
}
return 0;
}

