传递比实际小的数组 [英] Passing arrays as smaller than they actually are

查看:71
本文介绍了传递比实际小的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我声明了一个包含20个元素的数组 mass .当传递给子程序 foo 时, foo 会被告知 mass 仅包含10个元素.但是,我仍然可以访问第20个元素.我的问题是:

In the following code, I declare an array mass with 20 elements. When passed to the subroutine foo, foo is told that mass has only 10 elements. However, I can still access the 20th element. My questions are:

  • 为什么我可以将数组传递给子例程,并告诉子例程该数组的大小错误?

  • Why can I pass an array to a subroutine and tell the subroutine the wrong size for the array?

即使子例程认为它只有10个元素,为什么我仍然可以访问第20个元素?

Why can I still access the 20th element even though the subroutine thinks it only has 10 elements?

我在数组 foo 中对数组第20个元素所做的任何更改是否会保留在数组中,就像 foo 知道正确的大小一样数组?

Would any changes I make to the 20th element in the array while in foo remain with the array just the same as if foo knew the proper size of the array?

这是代码:

  program test
  implicit none

  integer num2,i
  real*8 mass(20)

  num2=10

  do i = 1,num
     mass(i) = 1.d0
  end do

  call foo(num2,mass)

  end


  subroutine foo(num2,mass)

  integer num2
  real*8 mass(num2)
  write(*,"(A20,E15.9)") "first one:",mass(1)
  write(*,"(A20,E15.9)") "tenth one:",mass(10)
  write(*,"(A20,E15.9)") "twentieth one:",mass(20)

  continue

  end

注意:这种情况下,子例程被告知数组的大小错误是我尝试修改以适合自己的用法的其他人的代码中遇到的一种情况.

Note: This situation of a subroutine being told the wrong size for an array is one I am encountering in someone else's code I am trying to modify for my own usage.

推荐答案

您的问题有两个误解,我将在此答案中解决.M. S. B.的答案给出了一些实际的含义.

There are a couple of misconceptions underlying your question which I'll address in this answer. Some practical implications are given in the answer by M. S. B..

您说您声明了一个包含20个元素的数组 mass ,但是该 foo 却被告知只有十个元素.这是不正确的.

You say that you declare an array mass with twenty elements, but that foo is told that it has only ten. This is not correct.

实际上,您拥有两个不同的实体:主程序中的一个数组 mass ,具有二十个元素,以及一个大小为10的数组(也称为 mass ).子例程 foo .

What you have are actually two distinct entities: an array mass in the main program, with twenty elements, and an array (also called mass) of size ten in the subroutine foo.

通过"正在建立这两个实体之间的关联(所谓的自变量关联).主程序中名为 mass 的数组是子例程中的实际参数,子程序中名为 mass 的数组是虚拟参数.

The "passing" is establishing an association (so-called argument association) between those two entities. The array called mass in the main program is the actual argument in the subroutine and the array called mass in the subroutine is the dummy argument.

伪参数是一个显式形状数组,范围为 num2 (也是与主程序的 num2 相关联的参数).虚拟参数的前 num2 个元素与实际参数的前 num2 个元素相关联.[这导致在主程序的数组中至少需要有 num2 个元素.]

The dummy argument is an array of explicit shape, extent num2 (which is also argument associated with the num2 of the main program). The first num2 elements of the dummy argument are associated with the first num2 elements of the actual argument. [This leads to the requirement that there are at least num2 elements in the array in the main program.]

那么,第一个问题的答案

So, the answer to your first question

为什么我可以将数组传递给子例程,并告诉子例程错误的数组大小?

Why can I pass an array to a subroutine and tell the subroutine the wrong size for the array?

就是这样:您并不是在告诉它错误的大小,只是在说子例程中的数组与参数的前 num2 个元素相对应.

is just this: you aren't telling it the wrong size, you are merely saying that the array in the subroutine corresponds to the first num2 elements of the argument.

来到

即使子例程认为它只有10个元素,为什么我仍然可以访问第20个元素?

Why can I still access the 20th element even though the subroutine thinks it only has 10 elements?

这是编程错误.不允许使用大于数组范围的下标值.当您尝试执行此操作时,将由编译器决定.就像另一个答案所说的那样,很有可能只是访问(由于实现关联的方式)内存中与实际参数的大元素相对应的位置.但是同样地,编译器可能会抱怨(尤其是选择了那些检查编译选项的选项),或者如果传递是通过临时复制完成的,则该事物可能会崩溃.[后者不太可能.]

This is a programming error. You are not allowed to use a subscript value larger than the extent of the array. What happens when you try this is up to the compiler. As the other answer says, it's quite possible that this is just accessing (because of the way the association is implemented) that location in memory corresponding to the large element of the actual argument. But equally the compiler could complain (especially with those checking compilation options chosen), or if the passing is done with temporary copying the thing could crash. [This latter is unlikely.]

最后

在foo中保留对数组第20个元素的更改时,是否与foo知道数组的正确大小一样?

Would any changes I make to the 20th element in the array while in foo remain with the array just the same as if foo knew the proper size of the array?

这又是特定于实现的.没有正确的Fortran答案,因为您的程序不符合要求.与上一点一样,如果那是与实际参数的适当元素相对应的内存区域,并且没有界限,则检查是否可以继续进行.如果编译器选择进行复制,则可能会导致崩溃或返回时忽略超出范围的更改.[同样,后两个不太可能,因为这要求编译器聪明".]

This is again implementation specific. There is no correct Fortran answer, as your program isn't conforming. As with the previous point, if that's an area of memory corresponding to the appropriate element of the actual argument and there's no bounds checking going on the changes could persist. If the compiler chose to do a copy there could either be a crash or the changes outside the bounds could be ignored on return. [Again, these last two are unlikely as it would require the compiler to be "clever".]

这篇关于传递比实际小的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆