返回介绍

6.2.6 作用域

发布于 2025-03-08 16:28:36 字数 3856 浏览 0 评论 0 收藏 0

a) 作用域单元

在用带有语句标号的 GOTO 语句实现语句间的转移时会遇到这样一个问题,即程序中在什么情况下可以使用相同的语句标号而不会产生歧义?这就是语句标号的作用域问题。实际上主程序或每个过程都有—套独立的语句标号,包括宿主程序含有几个内部过程的情况。类似地,对变量名称也会有这样的问题,这就是名称的作用域问题。对于语句标号来说,它的作用域是主程序或过程,但不包括它含有的内部过程,相同的语句标号可以用在宿主程序和内部过程里而不会产生歧义。

F90 标准以作用域单元的形式来定义名称。作用域单元是一个程序或程序的一部分,在作用域单元中定义一个名称,这个名称在作用域单元中有效。作用域单元可以是整个程序、程序单元、一个单独的语句或语句的一部分。名称可以是常量名、变量名、过程名、操作符或任何其它名称。名称可以用于程序、过程、变量、数组、哑元、命名常量、派生类型或块结构。名称有三种:全局名称、局部名称和语句名称。

作用域单元有以下几种:1、派生类型定义;2、过程接口体,不包括其内部的派生类型定义和过程接口体;3、程序单元或过程,不包括内部的派生类型定义、过程接口体以及内部过程。

下面是包括 5 个作用域单元的例子,作用域单元可以包含其他作用域单元。

MODULE SCOPE1 ! Scoping unit 1

... ! Scoping unit 1

CONTAINS ! Scoping unit 1

FUNCTION SCOPE2 ! Scoping unit 2

TYPE SCOPE3 ! Scoping unit 3

... ! Scoping unit 3

END TYPE SCOPE3 ! Scoping unit 3

INTERFACE ! Scoping unit 3

... ! Scoping unit 4

END INTERFACE ! Scoping unit 3

... ! Scoping unit 2

CONTAINS ! Scoping unit 2

SUBROUTINE SCOPE5 ! Scoping unit 5

... ! Scoping unit 5

END SUBROUTINE SCOPE5 ! Scoping unit 5

END FUNCTION SCOPE2 ! Scoping unit 2

END MODULE SCOPE1 ! Scoping unit 1

b) 名称的作用域

全局名称

全局名称用来识别程序单元、公共块和外部过程。全局名称在程序的任何地方都是有效的,所以只能在程序中定义一次。例如,如果用户在一个程序中使用了名为 Son 的子程序,就不能再在该程序中使用名为 Son 的公共块或函数。

局部名称

局部名称是用来识别变量(标量和数组)、常量、命名常量、语句函数、内部过程、模块过程、哑元过程、内在过程、一般标识符、派生类型和名称列表组的名称。派生数据类型的成员和关键字变元(哑元) 也是局部名称。局部名称可以覆盖全局名称和同一程序单元中的其它局部名称(关键字变元、类属名称和公共块名称除外)。如果一个名称对某个程序单元是局部的,同样的名称即可以作为全局名称又可以作为其它程序单元中的局部名称。

内在过程的双重名称

因为 FORTRAN 语言的关键字不予保留,所以用户可以创建名称和 FORTRAN 内在过程名称一样的变量、常量或过程。一旦创建了这样的名称,原来的内在函数就不能再被访问。例如,下面定义了新的函数 sin:

SUBROUTINE sub

...

CONTAINS

FUNCTION sin(x)

...

END FUNCTION sin

END SUBROUTINE sub

任何在子程序 sub 中对 sin 的引用都会调用其中定义的内部函数,而不是原来的内在函数。

类似地,任何与同名内在过程的标准类型不同的类型声明都会产生一个局部名称。下面的例子声明了一个名为 sin 的变量:

CHARACTER(LEN=5) :: sin

任何使用这个字符变量的程序或内部过程都不能再使用原来的内在函数。如果该变量在模块中以 PRIVATE 属性声明,模块外的程序单元仍可以使用内在函数 sin。

语句名称

语句名称的作用域是一条语句。语句名称可以出现在语句函数的语句中、一个 DATA 语句的隐 DO 循环中、一个数组构造器中。在语句函数语句中作为哑元出现的变量名,在其出现之处的范围就是语句域。DO 变量的域(必须是整数) 是隐 DO 列表。例如:

DIMENSION x(10)

Add(a,b)=a+b

DO n=1,10

x(n)=add(y,z)

END DO

在此例中,a 和 b 的域被限制在语句函数内部。n 的域是整个 DO 循环。

公共块名称

公共块名称是全局名称。因为局部名称可以和全局名称重名,在局部实体中对这个名称的引用指的是局部名称。当公共块在 SAVE 语句中命名时,它应该用斜杠围起来以和其它同名的局部变量区分。例如:

COMMON/happy/cat,dog,mouse

CHARACTER(20) happy

SAVE /happy/ !SAVE 的是公共块而不是变量

函数结果名

函数结果是另一个允许出现重名的例子。对每一个在函数过程中的 FUNCTION 语句或 ENTRY 语句都可有一个结果变量。如果没有用 RESULT 指定另外的变量名,结果变量和函数定义时同名。

派生类型成员名称

如果一个变量是其它名称的成员,它的域和包含该变量的名称的域一样。例如,一个模块中定义的派生类型和模块的域一致,也和任何使用该模块的域一致;承认派生类型的的程序同样承认派生类型的成员;对于数组的情况也是类似的,在数组适用的域内,数组片段也是有效的。

其它情形

其它实体,例如语句标号、I/O 单元、操作符和赋值号等都有域的概念。对于这些实体应遵守下面的规则:1、语句标号始终被认为是局部的,两个域相同的单元不能使用相同的标号;2、内在操作符(例如+,-,*,**,或/) 是全局的,但自定义的操作符是局部实体,特殊操作符的域由定义该操作符的过程的范围决定。可以通过使用过程接口块使自定义的操作符成为全局的;3、赋值符号(=) 是全局实体,可以在一个接口块中确定附加的一般赋值操作。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文