【程序设计】2.1 [做判断] 逻辑运算
2.1 逻辑运算
假如我们想计算一个数的绝对值(其实 SPL 有 abs 函数,但这里用别的方法来尝试),这需要判断这个数是大于 0 还是小于 0 的,我们引入 if 函数来实现:
=if(x>0,x,-x)
if(a,b,c) 函数有三个参数,其中 a 是一个条件,如果条件成立,则返回 b,否则返回 c。
利用 if 函数,还可以实现 max(x,y),即:
=if(x>y,x,y)
大多数现代程序语言中都有一种称为布尔的数据类型。它只有两种取值:true 和 false。
条件判断,比如上面的 x>0 或 x>y ,在程序语言中也被理解成是一种计算表达式,和我们常规的算术表达式一样,只不过它的计算结果是个布尔值。当这个条件成立时它的计算结果就是 true,否则会计算出 false。
if(a,b,c) 函数更严格的描述是这样:如果 a 是 true,则返回 b,否则返回 c。
把一个其它类型的数据转换成布尔型,可以用 bool(x) 函数,如果 x 不是空值(null),则会返回 true,否则返回 false。其实在 SPL 中并不区分 null 和 false。
既然布尔值也是一种数据,那么它应该可以参与运算。我们来看更复杂的例子:给定一个年份,计算出这一年有多少天。
我们知道平年 365 天、闰年 366 天,那么只要判断年份是否闰年就行了。完整的规则是这样:如果年份能被 4 整除且不能被 100 整除或者能被 400 则它是闰年。比如 2004 年是闰年(能被 4 整除不能被 100 整除),2000 年是闰年(能被 400 整数),1900 年不是闰年(能被 4 整数但也能被 100 整除)。写来的 SPL 表达式是这样 (y 是要判断的年份):
=if(y%4==0 && y%100!=0 || y%400==0,366,365)
后两个参数好理解,我们来解释第一个参数,即 y%4==0 && y%100!=0 || y%400==0。
% 是用于计算除法余数的运算,== 用来判断是否相等的运算符,y%4==0 表示 y 除以 4 后的余数是不是等于 0,也就是能判断出 y 是不是能被 4 整除。如果 y 能被 4 整数,那么 y%4==0 的计算结果就是 true,反之是 false。比如 2004%4==0 的结果就是 true,而 1998%4==0 则会计算出 false。
SPL 延用了 C 语言的习惯,用!= 表示不等于,很多程序语言用 <> 来表示不等于。SPL 中其它的比较运算符,如 >=,<= 等,和大多数程序写法都是一样的。
那么,y%100!=0 就可以判断 y 是不是不能被 100 整除,同样地,1900%100!=0 是 false,而 1998%100!=0 则是 true。类似地,y%400==0 将用来判断 y 是否能被 400 整除。
剩下那两个 && 和 || 是什么东西?
这就是布尔值的运算符,&& 表示“并且”,在程序设计中通常称为与;|| 表示“或者”,在程序设计中称为或。&& 和 || 都是两元运算符,即像加法一样有两个操作数。&& 和 || 的运算规则是这样的:
true && true = true
true && false = false
false && true = false
false && false = false
true || true = true
true || false = true
false || true = true
false || false = false
其实也就是常规的“并且”和“或者”的意思。&& 的优先级比 || 高,也就是说如果没有括号的话,会先计算 && 再计算 ||,就像先乘除后加减一样。这个表达式写成 y%400==0 || y%4==0 && y%100!=0 也会计算出同样的结果。
还有一个很常用的单操作数运算符!,称为非,表示“不是”的意思,运算规则如下:
!true = false
!false = true
! 有点像算术运算中的负号 -,它的优先级比 && 更高。
SPL 延用了 C 语言的计算符,有些程序语言中直接用单词 AND 和 OR 和 NOT 来表示 && 和 || 和! 这几种运算。
现在,我们就可以理解 y%4==0 && y%100!=0 || y%400==0 的意思了,它确实正确地表达了闰年判断的规则。
这里还有一个问题,为什么判断相等要使用两个等号 ==,而不像我们在算术表达式中用一个等号?
这是因为 SPL 延用了 C 语言的习惯,把 a=x 这样的赋值语句也理解成为一种运算表达式,它也有个计算结果,就是 x。比如我们在 A1 格里写 =a=5,SPL 并不会报错而会正常执行,并且可以看到不仅有了一个变量 a 的值为 5,A1 格本身也有值了,也是 5。因为 a=5 也被理解成是一种计算式,它的计算结果就是 5,可以赋给 A1 格了。
但这样约定之后,判断相等如果也用 = 的话,就无法区分了。所以 C 语言规定,判断相等要用两个等号 ==,就不会和赋值运算混淆了。SPL 也延用了这个规则。
习惯之后,我们会看到这种约定的优越性,能让代码简单很多。但这也有个风险,容易把该写成 == 的时候写成 = 了,本来是想判断相等,结果却做了赋值,在写代码时要特别注意。
需要说明的是,不是所有程序设计语言都是这样规定的。比如 BASIC 语言就不把赋值看成是一种运算符,a=5 只完成赋值而不会有一个计算结果,用于判断相等也是用一个等号。好处是不易出错了,但代码有时会显得比较累赘。
还是那个话,这世界上没有啥都好的事。