上一篇文章写完之后感觉还算不错,因此我决定再写一些C的文章。
C语言从出生到现在恐怕是寿命最长是用的人数最多的一种语言了。他以其简洁的语法和较高的执行效率讲过程语言带到了最高峰,然而在出现了面向对象语言之后C语言的地位受到了动摇,但他的执行速度仍然是无人能比的。
针对这种情况有发展出了C++,他完全兼容C并且面向对象的功能强大,但这并不意味着C语言的历史使命就完成了。有一些程序还是要用C来写,最典型的就是Windows的API。
其实在C中仍然具有一些面向对象的雏形,这些内容我会在后续的文章中提到,在本文中将讨论表达式的用法。和《java中的数据类型转换》一样,这篇文章的论题看似简单,但读过之后定会让你有不少的收获。
只要是略懂编程的人都知道表达式是个什么玩艺儿,所以我就不多说了。在这里我要说的是一些表达式的非常巧妙的用法。
首先,让我们来看看逻辑运算符&&和||。这两个运算符有一个非常有用的操作,那就是可以用来替代if语句。“什么?if语句跟那个有什么关系?”你也许会有这样的疑问,让我们来看一段程序:
#include <stdio.h>
void main()
{
int a=5,b=45;
a+b-50&&a++;
printf("a=%d",a);
}这段代码的结果是:
a=5
从这里就可以看出a++并没有执行。这种操作称为“短路”,因为a+b-50等于0也就是false,这样a+b-50&&a++肯定就为false,C语言为了提高执行效率就不运算&&后面的表达式了。这就和if(a+b-50) a++;是一样的。||的原理和&&一样,它等价于if(!(a+b-50)) a++; 这个就不多说了。
&和|这两个虽然是位运算符,但是他们也可以做为逻辑运算符来使用,来看一个例子:
#include <stdio.h>
void main()
{
int a=1,b=0;
if(a&b)
printf("表达式为true");
else
printf("表达式为false");
}
结果为:
表达式为false
这说明a&b的值为和a&&b的效果是一样的,同样,a|b等价于a||b。过一会我再来解释为什么他们的效果是一样的。
下面我们来讨论臭名昭著的goto语句。goto一直被规范化编程的支持者所唾骂的对象,但是他为什么还保留在C语言中呢?我们来看一个例子:
void main()
{
int i,j,k,l;
for(i=0;i<100;i++)
for(j=0;j<i;j++)
for(k=0;k<j;k++)
for(l=0;l<k;l++)
if(l==5)
break;
}
在这里,break只能推出当前的这一层循环,如果想退出到最外层循环只能使用goto语句:
#include <stdio.h>
void main()
{
int i,j,k,l;
for(i=0;i<100;i++)
for(j=0;j<i;j++)
for(k=0;k<j;k++)
for(l=0;l<k;l++)
if(l==5)
goto breakloop;
breakloop:
printf("循环退出了");
}
这样就可以直接退出循环了。
最后,我们来讨论一下位运算的技巧。
数据是用二进制数来存储的,如果我们想知道单个数据的某一部分可以借助于位运算。比如我们想知道一个整数是正数还是负数只要取它的第一位就能辨别出来。要想知道一个浮点数小数点后面有几位也可以用这种方法。还有想某些地址也要取出某些位来实现重要功能。我们用一个例子来解释这种用法:
#include <stdio.h>
void main()
{
int a=120,b=-2;
if(a&0x80)//0x80转为二进制数是10000000,这样首位如果是0表达式就为0了
printf("负数");
else
printf("正数");
if(b&0x80)//如果首位是1那么他的结果就是非零数
printf("负数");
else
printf("正数");
}
结果是:
正数负数
如果想取出第一位的数只要a&0x80>>7这样就可以了。
下面我们来解释一下前面那个&&和&为什么会等效。&&只要两边有一个为0那么整个表达式就为0,而&两边的任何一个数的所有位都为0(所有位都为0也就是0了)那么他的结果也是0。所以如果把表达式的结果做为逻辑条件的话就一定是等价的。
这篇文章的主题就谈论完了,在下一篇文章我将介绍指针的用法。
2004.6.16