NCL循环和条件判断¶
循环语句¶
处理实际问题时,经常碰到许多具有规律性的重复操作,此时就需要在程序中重复执行某些 语句。能否继续重复,决定循环的终止条件。循环结构是在一定条件下反复执行某段程序的 流程结构,被反复执行的程序被称为循环体 [1] 。 循环语句是由循环体及循环的终止条 件两部分组成的。
与其他语言类似,NCL中循环可以分为二种,指定运行次数的循环(do循环)以及指定继续 运行条件(或停止条件)的循环(do while循环),基本上NCL中的循环与Fortran一致。
do 循环¶
模型:
do i = start, end, stride
;; 代码段
end do
- i为循环变量,start,end,stride为循环变量的初值,终止值和步长
- 初值,终止值和步长都可以为表达式,但其结果必须为标量
- 循环变量的步长可以省略,使用时必须为正
- 省略步长的循环中,若初值大于终止值,循环不会被执行;若初值等于终止值,循环将被执行一次
- 使用步长的循环中,初值可以大于终止值,为后向循环
do while循环¶
模型:
do while (标量逻辑表达式)
;; 代码段
end do
- 当标量逻辑表达式的值为真(
True
)时,执行循环体代码段 - 标量逻辑表达式指的是逻辑表达式的值必须为标量,若为序列或数组将引发异常
- 标量逻辑表达式的值不能为缺测值
.and.
和.or.
的短路求值同样发生- 相比于do循环,此循环结构适用于循环次数未知的情况
循环的控制¶
NCL中可以使用 continue
和 break
关键词对循环进行控制,它们的含义与C语言一致。
continue
语句用于终止本次循环,继续进行下一次循环或循环判断break
语句用于终止本层循环,当循环内代码执行到break时,循环便被终止
循环结构的注意点¶
由于解释性语言的在效率上的缺陷,因此对于循环的使用要做到“能不用则不用、一定要用注 意优化”。
避免不必要的循环¶
在NCL中的循环效率不高,应尽量减少循环,特别是大循环、高层嵌套循环的使用。 那么该如何减少循环的使用呢?最好的方法是使用NCL函数,事实上 我们许多的数组运算和操作,在NCL中都有函数可以直接的进行。一些 新手由于对NCL函数不熟悉,经常写出一些没必要的多层循环结构。
优化循环结构¶
- 多重循环中,可能的情况下,将长循环放在内层,短循环放在外层,可节省循环时间
- 避免在循环体内改变循环变量,防止出现不期待的循环结果
- 循环嵌套控制在3层以内,过多的循环层数使代码变得难以理解
条件判断if语句¶
NCL提供if语句来进行流的控制,NCL中的if语句包含两种:
if-then-else语句¶
模型:
if( 标量逻辑表达式 ) then
;; 语句
else
;; 语句
end if
注解
需要强调的,也是导致if语句经常报错的是,标量逻辑表达式的结果必须是单个标量值并且不能为缺测。
if语句的嵌套¶
NCL中允许对if语句进行嵌套,然而NCL中并没有else if语句,但这并不妨碍我们在NCL中使 用else if,通过将else和if放置在一行上,可以构成else if,尽管这并不是真正意义上的 else if,而是对if语句的嵌套。因而这个if后面同样需要end if。
if ( 标量逻辑表达式 ) then
;; 语句
else if (标量逻辑表达式 ) then
;; 语句
else if ( 标量逻辑表达式 ) then
;; 语句
else
;; 语句
end if
end if
end if
关于缺测¶
逻辑表达式中已经提到在NCL中的逻辑值不仅包含True,False,还包含了missing。 而在if语句中,逻辑表达式的值并不允许是missing,事实上使用以下语句判断元素是否为 缺测时,将出现错误:
if( a(i) .eq. a@_FillValue) then
...
引发异常:
错误
fatal:The result of the conditional expression yields a missing value. NCL can not determine branch, see ismissing function
在该if语句中,逻辑表达式的值将是missing,所以引发异常。
正确的判断是否为缺测的方式是使用 ismissing
函数
if(ismissing(a(i))) then
...
关于数组逻辑表达式¶
既然if语句的逻辑表达式必须要求单标量值,那么数组逻辑表达式有什么好的方法可以在
if语句中使用呢?一些函数( any, all, ismissing
)能提供有益的帮助。
all
,当所有的逻辑元素为真时,all函数返回真any
,只要有一个逻辑元素为真,any函数返回真ismissing
,对所有的数组元素判断其是否为缺测,并生成与数组同样大小形状的逻辑值,合理利用ismissing函数能在很大程度上避免if语句错误发生
关于短路求值¶
逻辑表达式中已经提到短路求值的概念,由于逻辑表达式从左到右执行,在.and. 和.or.中, 如果逻辑表达式的第一项就能确定逻辑表达式的值,那么后面的逻辑表达式将不被求值。 因此,合理地布局if语句中的多个逻辑表达式的位置,有益于避免错误和减少不必要的运算。
比如:
if((i .lt. dimsizes(a)) .and. (a(i) .gt. 10 )) then
...
end if
以上语句将避免索引值超出变量a的索引范围。
[1] | http://baike.baidu.com/view/961969.htm |