NCL运算符与表达式

运算符或操作符指的是那些你从小就在使用的加号 + 、减号 - 等等。 运算符通过对值做“操作”或“运算”来生成新的值,运算符操作的对象是 操作数运算子 ,根据操作对象的数量可以将常见的运算符分为 一元运算符 如求反 -二元运算符 如加减乘除 + - * / 。对于二元运算符,可以将 其操作的两个操作数按相对位置分为左操作数和右操作数。

按照运算符的功能,可以将常用的运算符分为赋值运算符、算术运算符和逻辑运算符等

算术运算符

算术运算符操作基本数值类型的数组。NCL包含九个主要的算术运算符,分别是乘 * 、 除 / 、幂指数 ^ 、加 + 、减 - 、取模(求余) % 、 小于选择 > 、大于选择 < 、和求反 - 。 除求反运算符为一元运算符外,所有的运算符都是二元运算符,都要求两个操作数。

一般来说,所有的操作数要求有相同的类型,如果对不同的类型变量进行算术运算, NCL将尝试转换它们到相同的类型,如转换失败,NCL将抛出类型不匹配错误。 同时,操作数应该有相同的维数和大小,或者操作数分别为标量和数组,运算符 对整个数组进行操作。

运算符 符号名称 符号解释
- 一元求反 生成操作数的负数
^ 幂指数 右操作数成为左操作数的幂

*

/

%

#

左操作数乘右操作数
左操作数除右操作数,支持整数除法
取模 整数除法的整数余数,要求操作数都为整数
矩阵乘 支持一维或二维数组,计算两数组的点积

+

-

左操作数加右操作数
左操作数减右操作数

<

>

小于选择 选择对应位置左右操作数中的较小的值(标量和数组,扩展标量到整个数组)
大于选择 类似小于选择运算符,相反操作

注:同一栏下优先级相同,不同栏从上之下优先级降低,即求反优先级最高。

关系运算符

NCL参考手册中将关系运算符(大于、小于、大于等于、小于等于、等于、不等于)和逻辑 运算符(与、或、非、异或)合并在一起,这里我将把这两种运算符拆分开来说明。

关系运算符是你熟悉的小于、大于这类运算符,关系运算符是构成关系表达式的基础,当然 关系表达式也是逻辑表达式最简单的一种情形。

NCL关系运算符和其他语言一致,提供6种关系运算符分别是大于、小于、大于等于、 小于等于、等于、不等于。比较可惜的是,只能使用英文字母缩写的形式。

运算符 含义 数学符号 英语含义
.gt. 大于 \(>\) greater than
.ge. 大于等于 \(\geqslant\) greater than or equa to
.lt. 小于 \(<\) less than
.le. 小于等于 \(\leqslant\) less than or equal to
.eq. 等于 \(=\) equal to
.ne. 不等于 \(\ne\) not equal to

逻辑运算符

逻辑运算符通常用于逻辑变量的运算,返回结果为逻辑值。现实生活中常常碰到逻辑运算的 情况,比如“他不在家,并且也不在学校”。NCL中提供了四个逻辑逻辑运算符,以应对可能 的复合逻辑命题。

运算符 中文名 英语含义 示例 说明
.and. 逻辑与 and A .and. B A,B都为真时,结果为真
.or. 逻辑或 or A .or. B A,B之一为真时,结果为真
.not. 逻辑非 not .not. A A为真时,结果为假
.xor. 逻辑异或 exclusive or A .xor. B A,B只有一个为真时,结果为真

短路求值/惰性求值

逻辑表达式支持所谓的短路求值或惰性求值,是一种逻辑运算符的求值策略,只有当第一个 操作数的值无法确定逻辑运算的结果时,才对第二个操作数进行求值。例如,当 .and. 的第一个操作数的值为 False 时,其结果必定为 False ; 当or的第一个操作数为 True 时,最后结果必定为 True ,在这种情况下, 就不需要知道第二个操作数的具体值。对于一些逻辑运算,如 .xor. , 短路求值是不可能的。[1]

NCL中短路求值的具体判定如下表

左操作数 运算符 右操作数 结果 短路求值
False .and. 任何逻辑值 False yes
True .and. False False no
True .and. True True no
True .and. Missing Missing no
Missing .and. 任何逻辑值 Missing no
True .or. 任何逻辑值 True yes
False .or. True True no
False .or. False False no
False .or. Missing Missing no
Missing .or. 任何逻辑值 Missing no

可以发现任何包含 Missing 操作数的逻辑运算其结果都将是 Missing

赋值运算符

赋值运算符是程序语言中使用最普遍的一个运算符,然而要深究其含义则在各种不同语言中 有不同的内在功效。由于NCL变量包含元数据,理解NCL赋值运算显得更加必要。

等号 = 即为赋值运算符,是赋值表达式的基础。通常而言,赋值运算符基于右操 作数给左操作数赋值。即, x = y ,将把y的值赋给x。然而在NCL中实际情况并不 往往如此,由于变量具有元数据,如当y具有一些属性时,赋值表达式就不仅仅是赋值了。

正因此,NCL将赋值运算分为了值到变量( Value-only )的赋值和变量到变量 ( Variable-to-variable )的赋值两种情形,下面也分别讨论。

值到变量赋值

指的是等号右边的仅仅是值,而不包含任何元数据的情况。这种情况是常见的赋值运算,等 号右边的值将被赋给左边的变量。如若仅仅要将一个包含元数据的变量的值赋给等号左边的 变量,需要使用数据定义符 (/ /) 将变量置于其中,此时元数据将全部丢弃。

a = 1
b = (/1, 2, 3, 4, 5/)
a@att1 = 1
a@att2 = 2
c = (/a/)

变量到变量赋值

指的是等号右边的是一个已经存在的变量,可能包含各种元数据。此时的赋值语句将尝试将 等号右边变量的属性、维名称和坐标赋给左侧变量。

b = (/ (/1.0,2.0,3.0/), (/4.0,5.0,6.0/), (/7.0,8.0,9.0/) /)
b!0 = "dim0"
b!1 = "dim1"
b@units = "none"
b&dim0 = (/.1,.2,.3/)
b&dim1 = (/10,100,1000/)
a = b
print(a)
a = (/ (/1.1,1.2,1.3/), (/2.1,2.2,2.3/), (/3.1,3.2,3.3/) /)
a!0 = "test0"
a!1 = "test1"
a@units = "Degrees"
a@long_name = "A"
b = (/ (/1.0,2.0,3.0/), (/4.0,5.0,6.0/), (/7.0,8.0,9.0/) /)
b!0 = "dim0"
b!1 = "dim1"
b@units = "none"
b&dim0 = (/.1,.2,.3/)
b&dim1 = (/10,100,1000/)
a = b
print(a)

重新赋值运算符

有时,我们可能需要给一个已经赋值过的的变量再次赋值,比如循环处理某些数据,而这些 数据的维数大小在每次循环中可能发生变化。这种情况下,我们自然而然地就会出现NCL 异常:

错误

fatal:Dimension sizes of left hand side and right hand side of assignment do not match fatal:[“Execute.c”:8573]:Execute: Error occurred at or near line 1

在NCL6.1.1版以前,面对这种情况,我们需要在循环结束前使用程序 delete 来释 放变量。但是在NCL6.1.1版中加入重新赋值运算符,可以很好地处理这一情况。

重新赋值运算符的形式为 := ,即冒号和等号,中间不可有空格。 其含义是,尝试重新使用一个已经定义过的变量(若没有定义过,则重新赋值运算符等价于 赋值运算符),即将运算符右边的值或变量赋值(或重新赋值)给左边的变量,而不论左边 变量是否已经定义。事实上,如果左边的变量已经定义,那么NCL解释器将删除左边的变量, 然后根据右边的类型和维数重新定义左边的变量。

值到变量重新赋值

a = (/1, 2, 3, 4, 5/)  ; 将整型一维5元素数组赋给变量a
a := (/"I", "like", "NCL"/)  ; 给变量a重新赋值, a变为字符串型一维3元素数组

变量到变量重新赋值

a = new((/2, 2/), string)  ; 创建一个20*20的字符串组
; 定义一个新的NCL变量b
b = (/ (/1.0,2.0,3.0/), (/4.0,5.0,6.0/), (/7.0,8.0,9.0/) /)
b!0 = "dim0"
b!1 = "dim1"
b@units = "none"
b&dim0 = (/.1,.2,.3/)
b&dim1 = (/10,100,1000/)
a := b  ; 用变量b给变量a重新赋值,注意变量a此前已经定义
c := b  ; 用变量b给变量c重新赋值,注意变量c此前未定义
print(a)
print(c)

表达式

[1]ttps://zh.wikipedia.org/wiki/%E7%9F%AD%E8%B7%AF%E6%B1%82%E5%80%BC
../_images/donate2.png

评论