2015-06-10 2 views
3

Я написал простую программу в Fortran90 для вычисления площади треугольника. Пользователь вводит три стороны треугольника, а затем программа выводит эту область. Достаточно просто.gfortran не скомпилирует реальные переменные

MODULE Triangle_Operations 
    IMPLICIT NONE 
CONTAINS 
    FUNCTION Area(x,y,z) 
     REAL :: Area ! function type 
     REAL, INTENT(IN) :: x, y, z 
     REAL :: theta, height 
     theta = ACOS((x**2+y**2-z**2)/(2.0*x*y)) 
     height = x*SIN(theta); Area = 0.5*y*height 
    END FUNCTION Area 
END MODULE Triangle_Operations 

PROGRAM Triangle 
    USE Triangle_Operations 
    IMPLICIT NONE 
    REAL :: a, b, c, Area 
    PRINT *, 'Welcome, please enter the & 
       &lengths of the 3 sides.' 
    READ *, a, b, c 
    PRINT *, 'Triangle''s area: ', Area(a,b,c) 
END PROGRAM Triangle 

Когда я компилирую это с gfortrangfortran triangle1.f90, это ошибка я получаю:

triangle1.f90:16.25: 

    REAL :: a, b, c, Area 
         1 
triangle1.f90:14.8: 

    USE Triangle_Operations 
     2 
Error: Symbol 'area' at (1) conflicts with symbol from module 'triangle_operations', use-associated at (2) 
triangle1.f90:19.13: 

    READ *, a, b, c 
      1 
Error: Symbol 'a' at (1) has no IMPLICIT type 
triangle1.f90:19.16: 

    READ *, a, b, c 
       1 
Error: Symbol 'b' at (1) has no IMPLICIT type 
triangle1.f90:19.19: 

    READ *, a, b, c 
        1 
Error: Symbol 'c' at (1) has no IMPLICIT type 

Почему именно будет ли ошибка брошена для переменных a,b,c? Я явно определил их как реалы.

+0

Он компилирует (и работает) отлично для меня. Когда я впервые это сделал, я назвал файл 't.f' и дал ошибки, похожие на ваши. Когда я переименовал его в 't.f90', он скомпилировался в порядке. – wallyk

+0

@wallyk Странно. У меня есть файл с именем 'triangle1.f90'. Возможно, мне нужно изменить расширение или, возможно, использовать конкретный компилятор? Я до сих пор не знаю ... – ShanZhengYang

+5

Я думаю, что вы получаете каскад ошибок из путаного компилятора из-за множественного объявления «Area» (первая ошибка). В основной программе нет необходимости объявлять ее REAL. Это уже объявлено в модуле. Удаление декларации фиксирует все. – RussF

ответ

1

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

Чтобы устранить проблему, удалите разделение Area из вашей основной программы, например. включить

REAL :: a, b, c, Area 

в

REAL :: a, b, c 

последующих ошибок в вашем выходе компиляции являются результатом первой ошибки относительно Area. Эта целая строка становится недействительной, поэтому объявления типа a, b и c не обрабатываются, и это вынуждает компилятор жаловаться на недостающие типы в следующий раз, когда они встречаются. Эти ошибки исчезнут, как только вы сделаете исправление, предложенное выше.


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

use triangle_operations, triangleArea => Area 

, а затем сделать это:

real a, b, c, Area 
Area = triangleArea(a,b,c) 

в основной программе.

+0

(Только личный вопрос) Я полагаю, что во многих современных языках обычно рекомендуется импортировать только определенные переменные или объекты, которые будут использоваться в текущей области, а не неявно импортировать все в модуль. Поэтому я всегда делаю правило использовать «только» вместе с «использованием» в Fortran. Что вы думаете об этой практике ...? Я думал, что для OP также может быть полезно увидеть избыточный характер «Района». – roygvib

+0

@roygvib Как и на других языках, иногда вы импортируете все, иногда вы используете 'only'. Когда вы используете 'only', вы должны принимать его всякий раз, когда вы добавляете или переименовываете что-то, но это помогает отслеживать материал.Если вы импортируете что-то в небольшую подпрограмму, я бы не стал беспокоиться, но иногда это удобно. Для этого нет строгих правил. –

+0

@VladimirF Да, конечно, нет строгих правил, и это также проблема стиля. Фактически обе стратегии (т. Е. Прикрепляют только-список всегда или никогда не присоединяют его) используются во многих больших программах. Импортировать все также очень удобно для коротких программ. С другой стороны, по мере того, как программа становится больше, импорт все неявно в текущую область данных затрудняет отслеживание переменных. Я надеюсь, что будущая версия Fortran будет иметь что-то вроде 'use, explicit :: mymod' и разрешить' call mymod% myfunc() 'как другие языки :) – roygvib

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