Область применения и работа с подпрограммами со многими входами - PullRequest
0 голосов
/ 04 июня 2018

Некоторые из моих подпрограмм на фортране имеют огромное количество входных данных, передаваемых им, иногда даже 30 или 40. Причина этого двоякая: во-первых, у этих подпрограмм есть много четко связанных подпрограмм, которым нужны некоторые из этих переменных в качестве входных данных,и, во-вторых, чтобы избежать определения глобальных переменных, и решение этой проблемы, по-видимому, заключается в том, чтобы каждый раз явно передавать каждую переменную подпрограмме.

Это кажется мне неприемлемым, но у меня действительно нет решения дляэто, и я не уверен на 100%, что это проблема, во-первых, возможно, это правильный способ сделать что-то на этом языке.

Тогда мой вопрос: это проблема?Если это так, есть ли лучший способ управлять областью действия на этом языке, не обязательно вводя объекты?

1 Ответ

0 голосов
/ 05 июня 2018

Я понимаю, почему дизайнеры хотят избегать глобальных переменных.Мне приходится работать с кодом, который использует противоположный подход, почти без аргументов, и все находится в глобальном состоянии в различных модулях, и это ужасно, независимо от того, как часто они используют предложение only в операторах use.

Мы можем с уверенностью сказать, что это количество аргументов (скажем, 30) слишком велико.Все рекомендации по стилю кода, вероятно, согласятся с этим.Часто бывает немного неприятно работать со многими аргументами, которые требуются библиотекам, таким как LAPACK, и это далеко не 30.

Существует несколько способов, которыми Fortran 90 и более поздние версии могут уменьшить количество аргументов.

Во-первых, вы можете связать логически связанные переменные в производный тип

type particle
  integer :: species
  real    :: mass
  real    :: x, y, z
  real    :: vx, vy, vz
  ...
end type

Во-вторых, используя предполагаемые массивы фигур, вы можете избежать передачи размеров массива.Это позволяет, например, современным интерфейсам LAPACK иметь значительно меньшее количество аргументов (как интерфейсы Netlib, так и интерфейсы MKL).

subroutine sub(A, NX, NY, NZ)
  integer :: NZ, NY, NZ
  real :: A(NX, NY, NZ)

против

subroutine sub(A)
  real :: A(:,:,:)

Это изменение требует явного интерфейсадля процедуры, так что на практике процедуры должны быть перемещены в модули.

Оба эти изменения являются довольно значительными изменениями и требуют значительных усилий по рефакторингу для больших устаревших кодов.

...