编写假定大小的数组导致“上限不得省略...”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写假定大小的数组导致“上限不得省略...”相关的知识,希望对你有一定的参考价值。

我正在编写代码来添加一个闭源有限元框架,这个框架迫使我(由于依赖于一些旧的F77样式方法)在一个地方依赖于假定大小的数组。

是否可以将假定大小的数组写入标准输出,无论其大小如何?

这不起作用:

module fun

implicit none

contains

subroutine writer(a)
integer, dimension(*), intent(in) :: a
write(*,*) a
end subroutine writer

end module fun


program test
use fun
implicit none

integer, dimension(2) :: a

a(1) = 1
a(2) = 2

call writer(a)

end program test

随着英特尔Fortran编译器抛出

error #6364: The upper bound shall not be omitted in the last dimension of a reference to an assumed size array.
答案

编译器不知道假定大小的数组有多大。它只有第一个元素的地址。你有责任告诉它有多大。

 write(*,*) a(1:n)

等效地,您可以使用显式大小的数组

integer, intent(in) :: a(n)

然后你就可以做到

write(*,*) a
另一答案

当该引用需要数组的形状时,假定大小的数组可能不会作为整个数组引用出现。作为写入语句中的输出项,这是一个不允许的情况。

所以,在这个意义上,答案是:不,你不可能拥有写声明。

从假定大小的数组中,可能会出现数组部分和数组元素:

write (*,*) a(1:2)
write (*,*) a(1), a(2)
write (*,*) (a(i), i=1,2)

导致如何将值2纳入子程序;在其他时候可能需要7。我们称之为n

当然,改变子程序很诱人:

subroutine writer (a,n)
  integer n
  integer a(n)      ! or still a(*)
end subroutine

甚至

subroutine writer (a)
  integer a(:)
end subroutine

人们常常没有选择,特别是在将过程与虚拟过程与特定接口相关联时。但是,n可以通过以下几种方式进入子例程:作为模块或主机实体,或通过公共块(如果可能,请避免使用此块)。这些方法不需要修改过程的接口。例如:

subroutine writer(a)
  use aux_params, only : n
  integer, dimension(*), intent(in) :: a
  write(*,*) a(1:n)
end subroutine writer

或者我们可以将n作为fun模块中的实体,并通过主机关联在writer中访问它。在任何一种情况下,都需要在执行n之前在主程序中设置此writer的值。

以上是关于编写假定大小的数组导致“上限不得省略...”的主要内容,如果未能解决你的问题,请参考以下文章

数组与字符串:翻转子串

QT调试时怎么查看某个指针指向的一片内存区域的信息

学生成绩

C中用户定义的数组元素和数组大小

MarshalAs 是不是会导致数组副本?

2021-09-03:直线上最多的点数。给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。力扣149。(代码片