2016-03-04 3 views
2

Я не понимая важность СОДЕРЖИТ заявление в Fortran 90Содержит заявление

Например

PROGRAM BLABLA 

IMPLICIT NONE 

INTEGER :: i,j,k 

i = 1; j = 1;k =1 

PRINT *, i,j,k 

CALL ABC(i,j,k) 

PRINT *, i,j,k 

CONTAINS 

    SUBROUTINE ABC(r,s,t) 

    IMPLICIT NONE 

    INTEGER, INTENT(IN) :: r,s 
    INTEGER, INTENT(OUT) :: t 

    t = r + s 

    END SUBROUTINE ABC 
END PROGRAM BLABLA 

и один, определив подпрограммы вне основной программы. Я понимаю для функций, нужно указать тип функции, но для подпрограмм это не требуется. Мне интересно узнать, есть ли какие-либо дополнительные оговорки?

PROGRAM BLABLA 

IMPLICIT NONE 

INTEGER :: i,j,k 

i = 1; j = 1;k =1 

PRINT *, i,j,k 

CALL ABC(i,j,k) 

PRINT *, i,j,k 

END PROGRAM BLABLA 

SUBROUTINE ABC(r,s,t) 

IMPLICIT NONE 

INTEGER, INTENT(IN) :: r,s 
INTEGER, INTENT(OUT) :: t 

t = r + s 

END SUBROUTINE ABC 

ответ

3

В обоих ваших первом и втором вариантах попробуйте изменить линию

CALL ABC(i,j,k) 

в

CALL ABC(i,j) 

и посмотреть, что происходит, во-первых, во время компиляции, а во-вторых, во время выполнения.

Когда вы это сделали и сообщите о своих выводах, я могу превратить это в правильный ответ.

ОК, так вот ответ, большинство из которых вы уже выяснили:

В старые времена, до Fortran 90, оно было общим для FORTRAN (все скандировали имя в те дни) программы скомпилироваться в отдельных «единицах» (это все еще есть). В вашей второй версии программа и подпрограмма находятся в отдельных единицах и скомпилированы отдельно. Информация не доступна компилятору, чтобы проверить, соответствует ли вызов подпрограмме подписи подпрограммы, которую оставляют программисту для проверки. Неправильно вызвать подпрограмму, и почти все может произойти - если вам повезет, программа вылетает или производит явно ошибочные результаты, если вам не повезло, она производит не-явно ошибочные, но все еще ошибочные результаты.

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

Другой способ, чтобы компилятор сгенерировал интерфейс для подпрограмм, и эти подходы также работают для функций, заключается в том, чтобы поместить их в модуль и use модуль в программу. Вы найдете много примеров того, как это сделать в других Qs и As здесь на SO.

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

+0

Когда у меня нет ** СОДЕРЖИТ **, он компилируется, но затем дает мне ошибочный ответ для j (произвольно большой). Когда у меня есть ** CONTAINS **, это не позволяет мне скомпилировать. Поэтому я предполагаю, что ** CONTAINS ** служит дополнительной проверкой аргументов. До сих пор я писал коды без ** CONTAINS **. Если тот же код компилируется с ** CONTAINS **, я могу быть уверен, что другой код верен, насколько аргументы идут. Точнее, если в любом из кодов нет аргументов, переданных (но сохраненных в MODULES как глобальные переменные), будут ли они одинаковыми? – Vaidyanathan

Смежные вопросы