巨侠——Andrew Koening不愧是巨侠,写的《C traps and pitfalls》从编译程度分析C语言的一些缺陷与陷阱,看过之后,才发觉,原来以前我一直走在陷阱之上(相信很多人和我一样),幸运的是未掉进去而已。下面给出几个我印象比较深的例子:
例1:巧用求值顺序
if(count!=0&&sum/count<smallAverage)
{
printf("average<%d\n",smallAverage);
}
这种写法可以避免除数为0的情况出现。原因是:&&求值顺序是只有当&&左边成立的情况下才去求右边的值,若左边条件为假,则不对右边表达式求值(左边表达式为假时,整个&&的值就为假)。类似的运算符还有“||”、“?:”、“,”。
例2 :看下面两个代码段,看看它们是否有问题。
i=0; | i=0;
while(i<n) | while(i<n)
{ | {
y[i]=x[i++]; | y[i++]=x[i];
} | }
乍看好像没问题。也许也曾写过这种代码,确实也没出现问题。但是以上两个代码段是有问题的,此代码段假设y[i]的地址将在自增操作执行前被求值(这点是没有任何保证的),可能会在之前被求值,也有可能想法(取决于编译器),因此这种代码不安全,且可可移植性不好。比较好的写法如下:
i=0;
while(i<n)
{
y[i]=x[i];
i++;
}
或
for(i=0;i<n;i++)
{
y[i]=x[i];
}
例3 :小心使用宏
#define INT int*
INT a,b;
此时a是int类型的指针,而b则是int类型的变量
我们可以将宏展开得到的是:
int * a,b;
改进的方法:用typedef来定义即typedef int* INT。
曾经年少,未曾想过C中居然有这么多陷阱,现在年少依旧,陷阱也依旧,不同的是开始慢慢发现陷阱的存在。
PS:书中还有很多例子用于说明如何提高C程序的健壮性、可移植性等。本人感觉此书不适合C语言初学者,要等到C语言学到一定程度的时候去看比较有感觉。
2007-8-17 13:32:35
2007
Aug
17
Friday