在计算机的世界里,虽然有很多数学的影子,但在计算公式转换为计算机语言时,很多表达方式并 不一致,这导致新手们初期不习惯,很容易用错,需要一个记忆的过程。就像学习英文,主谓宾定状补的先后顺序于中文是不一致的。在翻译句子时很容易产生中式英语。
本文就问答中经常出现的计算机语言和数学公式写法不一致的,与运算符相关的问题进行梳理,希望新手们能够快速度过适应期。(当然,不同计算机语言在表达时也有差异,本文仅以C/C++为例,也暂不考虑C++新标准的特性)。
1、讨厌的等号
判断值相等,用==符号,而变量赋值使用=符号。新程序员们还不太习惯==这个东西,很容易写成=符号。从而是判断语句变成了赋值语句。而编译器也不会报错,但结果却发生了很大的变化。
比如 if(n=0) {do something;}
原意是想判断n等于0的话,执行某些操作,但写成n=0后,先是将n值改成了0,然后由于if(0)不成立,代码根本就不执行if的代码块。因此完全达不到想要的效果,所以一定要注意,回头找不好发现。
对于==误写成=,如果是判断变量与值是否相等,可以有个好方法,就是将值写在左侧,变量写在右侧,如此一旦误写==为=,编译器会报错提醒。
比如 if(a==0),写成 if(0==a),对于==表达式,两种写法都成立,但对于=操作符,只有a=0成立,0=a是错误的。希望对大家有帮助。
2、讨厌的取值范围判断
数学中表示一个值的取值范围,一般写成如: 1<=x<=10这样子。但计算机语言不是这样写的, 必须是x>=1 && x<=10这样的逻辑与表达式。但同样1<=x<=10编译器并不会报错,也是可以执行的代码。先比较1<=x是否成立,结果是个布尔量,成立则为1,否则为0。然后再判断布尔值是否<=10,这是永远成立的,所以只要右侧的值大于等于1,那么无论x是多少,整个表达式结果都是1。同样,如果右侧值小于0,则整个表达式结果是0。这自然不是程序员需要的结果,因此必须要注意。
3、讨厌的乘号
在数学中,两个数相乘时,乘号是可以省略的,但计算机语言中不可以,一旦乘号省略,会被识别为变量名。比如 2*a,写成2a就会报错,因为2a不符合变量命名规范。如果a*2,写成a2,则会报未定义的变量。一旦不幸前面敲好定义了变量a2,那么编译器就不会报错,但程序结果就完全无法预测了。所以要注意,乘号不能省略。
另外,*号即是乘号,也是指针符号,要注意区分。
4、讨厌的除号
除号容易出两个问题,一是除数为0,二是整除。
除数为0时,如果没有提前排除,也没有异常捕捉,那么程序会崩溃。所以一定要先检查除数是否为0的情况,进行特殊处理。
当两个整数相除时,其结果是整除的结果,比如6/4=1,而不是1.5,因此特别要注意,出错率很高,写错了不容易发现。有时候交换表达式中的顺序结果就不一样。
比如6/4*0.5 = 0.5,但6*0.5/4就是0.75。
5、讨厌的逻辑与和逻辑或
逻辑与和逻辑或有熔断的特性,会导致某部分表达式实际不会执行。
比如:
int a=1,b=3,c=5;
if(a>b && b<++c) {do something;}
对于逻辑与表达式,结果为真的条件是两侧表达式结果都为真。如果左侧表达式为假,那么整个表达式结果必然为假,因此右侧表达式将不再执行。
上述if语句中,由于a>b为假,所以右侧的b<++c并不会执行,c值始终是5,没有改变。
if(a<b || b>++c) {do something;}
对于逻辑或表达式,结果为真的条件是有一侧表达式结果为真。如果左侧表达式为真,那么整个表达式结果必然为真,因此右侧表达式将不再执行。
上述if语句中,由于a<b为真,所以右侧的b<++c并不会执行,c值始终是5,没有改变。
这就是逻辑与和逻辑或的熔断特性。此特性在未来模块化编码中也会经常使用。特别是在指针的应用上。比如经常会有如下代码:
Node *p = head;
if(p != NULL && p->data != x) { p = p->next;}
如果没有熔断特性,当p为空时,右侧表达式就会导致程序崩溃。但由于左侧表达式为假,因此右侧表达式就不会执行,程序正常运行。