为了提高程序的复用性,将特定的功能写成函数或子程序是非常不错的选择。 函数和子程序的区别大概在于函数一般有返回值,而子程序没有。
定义函数和子程序的语法区别不大,除了为首的关键词,函数使用 function
, 而子程序使用 procedure
。定义一个函数或子程序基本上包含以下几个步骤,
由一个关键词 function
或 procedure
开头,空格后接函数名称,注意函 数名的取法要紧贴函数所实现的功能,同时建议使用下划线命名法;函数名后是以小括号括 起来的的形参列表,每一个形参用逗号隔开;形参后可用一个或多个中括号接数值或星号 (指任意大小)来指定形参变量的维数和大小,如 [2][*]
;后也可接冒号和NCL类 型关键词如 integer
,string
来指定该形参的类型。
- 第一种模式 只给形参变量名(变量名也可以没有)
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][*], ... )
局部变量的声明在NCL函数定义中是可选的,但是从可靠性和严谨的思路上讲,声明局部变量 是非常有帮助的,这可以避免函数体中对局部变量可能的错误引用。局部变量的声明以关键 词 local
开头,后接所有在函数中出现的局部变量,各个变量间以逗号隔开。局部 变量的相关知识将在下文深入讨论。
local local_var1, local_var2, local_var3, ...
之前的学习中,我们已经知道,程序主体可以用 begin
和 end
来封装,封装后的运行将首先进行语法检查,且这种封装是可选的。而在函数定义中,必须 使用 begin
和 end
来封装函数主体,否则将引发NCL异常。
begin
函数的主体是实现函数功能的NCL语句集合
statement list
函数一般有返回值,而子程序没有,函数在执行一定计算后,通常要返回一个计算结果。 使用 return
语句来返回函数结果, return
后接括号,将返回值置于 其中即可。实际上,由于return是一个语句,这对括号是可选的,直接空格接返回值亦可。
return(return_value)
end
调用函数或子程序的方式很简单,使用函数或子程序名称接一对小括号,括号中是传给函数 或子程序的参数,多个参数以逗号分隔:
val = function_name(arg1, arg2, ...) ; 函数调用
procedure_name(arg1, arg2, ...) ; 子程序调用
涉及到函数内容,不得不提变量的作用域。 时常碰到这样的问题,位于函数体内的变量在函数体外能不能使用? 主程序中,函数体外的变量能不能直接在函数体内使用? 这些都是变量作用域的问题,也就是变量的生存周期问题,下面介绍。
局部变量是拥有局部作用域的变量。这样的变量只能由声明它的函数或块中访问。1 在函数体中定义的变量是函数的内部变量,其只在函数体内有效,而在函数体外,并不存在 也无法使用。这种在函数或子程序体内定义的变量就叫做 局部变量 。
下面看一个具体例子
../code_examples/function_procedure/local_val.ncl
- 在14行中,我们试图使用函数
array_insert
中的dim_val
变量,引发NCL异常 - 在22行,我们又试图使用函数
array_insert
中的new_arr
变量,引发NCL异常并退出
在程序设计中,全局变量是在所有作用域都可访问的变量,与之对应的是局部变量。2