函数和子程序

为了提高程序的复用性,将特定的功能写成函数或子程序是非常不错的选择。 函数和子程序的区别大概在于函数一般有返回值,而子程序没有。

函数和子程序定义

定义函数和子程序的语法区别不大,除了为首的关键词,函数使用 function , 而子程序使用 procedure 。定义一个函数或子程序基本上包含以下几个步骤,

1 定义函数或子程序名

由一个关键词 functionprocedure 开头,空格后接函数名称,注意函 数名的取法要紧贴函数所实现的功能,同时建议使用下划线命名法;函数名后是以小括号括 起来的的形参列表,每一个形参用逗号隔开;形参后可用一个或多个中括号接数值或星号 (指任意大小)来指定形参变量的维数和大小,如 [2][*] ;后也可接冒号和NCL类 型关键词如 integerstring 来指定该形参的类型。

第一种模式 只给形参变量名(变量名也可以没有)
function 函数名 (变量1, 变量2, ...)
第二种模式 给定形参变量名,并限定形参变量数据类型
function 函数名 (变量1:数据类型, 变量2:数据类型, ...)
第三种模式 给定形参变量名,并限定形参变量维数大小 和/或 数据类型
function 函数名 (变量1[第1维大小], 变量2[*表示任意大小]:数据类型, 变量1[第1维大小][第2维大小]:数据类型, 变量3[1维大小][*表示任意大小]:数据类型, ...)
function function_name ( arg1, arg2, ... )
function function_name ( arg1:numeric, arg2:float, ... )
function function_name ( arg1[2]:snumeric, arg2[*]:double, arg3[2][*], ... )

2 声明局部变量(可选步骤)

局部变量的声明在NCL函数定义中是可选的,但是从可靠性和严谨的思路上讲,声明局部变量 是非常有帮助的,这可以避免函数体中对局部变量可能的错误引用。局部变量的声明以关键 词 local 开头,后接所有在函数中出现的局部变量,各个变量间以逗号隔开。局部 变量的相关知识将在下文深入讨论。

local local_var1, local_var2, local_var3, ...

3 使用begin来开始封装函数主体

之前的学习中,我们已经知道,程序主体可以用 beginend 来封装,封装后的运行将首先进行语法检查,且这种封装是可选的。而在函数定义中,必须 使用 beginend 来封装函数主体,否则将引发NCL异常。

begin

4 函数主体语句

函数的主体是实现函数功能的NCL语句集合

statement list

5 返回函数结果(可选步骤)

函数一般有返回值,而子程序没有,函数在执行一定计算后,通常要返回一个计算结果。 使用 return 语句来返回函数结果, return 后接括号,将返回值置于 其中即可。实际上,由于return是一个语句,这对括号是可选的,直接空格接返回值亦可。

return(return_value)

6 用end来结束函数主体和封装

end

函数和子程序调用

调用函数或子程序的方式很简单,使用函数或子程序名称接一对小括号,括号中是传给函数 或子程序的参数,多个参数以逗号分隔:

val = function_name(arg1, arg2, ...)  ; 函数调用
procedure_name(arg1, arg2, ...)  ; 子程序调用

变量作用域

涉及到函数内容,不得不提变量的作用域。 时常碰到这样的问题,位于函数体内的变量在函数体外能不能使用? 主程序中,函数体外的变量能不能直接在函数体内使用? 这些都是变量作用域的问题,也就是变量的生存周期问题,下面介绍。

局部变量

局部变量是拥有局部作用域的变量。这样的变量只能由声明它的函数或块中访问。[1] 在函数体中定义的变量是函数的内部变量,其只在函数体内有效,而在函数体外,并不存在 也无法使用。这种在函数或子程序体内定义的变量就叫做 局部变量

下面看一个具体例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
; 定义一个扩展一维数组的函数
function array_insert(orig[*], val[*], loc[1])
begin
    dim_orig = dimsize(orig)
    dim_val = dimsize(val)
    new_arr = new(dim_orig+dim_val, typeof(orig))
    new_arr(0:loc) = orig(0:loc)
    new_arr(loc+1:loc+dim_val) = val
    new_arr(loc+dim_val:) = orig(loc+1:)
    return new_arr
end

; 打印函数体中定义的dim_val变量
print(dim_val)

begin
    x = (/1, 2, 3, 4, 5, 6, 7, 8, 9/)
    ; 调用函数
    x_ext = array_insert(x, (/10, 11, 12, 13/), 4)
    print(x_ext)
    ; 打印函数体中定义的new_arr变量
    print(new_arr)
end
  • 在14行中,我们试图使用函数 array_insert 中的 dim_val 变量,引发NCL异常
  • 在22行,我们又试图使用函数 array_insert 中的 new_arr 变量,引发NCL异常并退出

全局变量

在程序设计中,全局变量是在所有作用域都可访问的变量,与之对应的是局部变量。[2]

[1]https://zh.wikipedia.org/wiki/%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F
[2]https://zh.wikipedia.org/wiki/%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F
../_images/donate2.png

评论