Fortran. Какой из приведенных ниже кодов является правильным? - PullRequest
0 голосов
/ 08 июля 2019

Я обнаружил следующую интересную вещь в Фортране. Это показано ниже в примере кода.

Я не могу понять и ничего не нашел, почему код на метках 10 и 12 работает, а на 11 и 13 - нет.

implicit none
integer     :: i
integer     :: IA(8) = [(i, i=1,8)]
integer     :: IP

IP = 5
10  IA(IP:2) = [11, 12]     ! works
11  IA(5:2) = [11, 12]      ! doesn't work
12  print *, IA(IP:IP+1)    ! works 
13  print *, IA(IP:2)       ! doesn't work

В чем разница?

1 Ответ

1 голос
/ 08 июля 2019

Обе версии оператора с пометкой 10 и 11 неверны.

Секция массива ia(5:2) является секцией массива, состоящей из нулевых элементов массива ia. Секция массива ia(IP:2) (когда IP является переменной со значением 5) одинакова.

При использовании литеральной константы в индексах элементов массива ваш компилятор знает, что при компиляции он может проверять совпадение формы левой и правой частей. Ваш компилятор здесь определил, что ia(5:2) имеет форму [0], а [11, 12] имеет несовместимую форму [2]. Поэтому он сообщает об ошибке.

Ваш компилятор не обнаруживает во время компиляции ошибку с непостоянными подписками в ia(IP:2). Код, однако, нарушает стандарт Фортрана точно так же. На первый взгляд правильный вывод: плохо удача.

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

Другие компиляторы вполне могут жаловаться, например, с сообщением:

Rank 1 of constant array operand has extent 2 instead of 0
Program terminated by fatal error
Abort (core dumped)

С заявлением

print *, IA(IP:2)

это «работает» (в противном случае правильно сформированная программа). Однако оно страдает от того же недоразумения, что и раньше.

Этот оператор печати печатает нулевые элементы массива ia в отличие от двух элементов ia(5:6). Вместо того, чтобы «не работать», отсутствие очевидного вывода означает правильную печать ничего / пустую строку.

В заключение, ia(5:2) не является ссылкой на два элемента после и включая ia(5). Для этого вам понадобится ia(5:6) или ia(ip:ip+1). Индексы - это границы, а не границы и количество.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...