All the basics of fortran will be covered in this repo.
The f90 extension will be used for the fortran program.
- Fortran Program starts with PROGRAM <program_name>
- Program ends with END PROGRAM <program_name>
PROGRAM HELLO_WORLD
IMPLICIT NONE
PRINT *, "Hello, World"
END PROGRAM HELLO_WORLD
Fortran 90 is case insensitive but it is standard practice for keywords to be in UPPERCASE.
To compile,
# To compile the program to objects
gfortran -c -o main.o main.f90
# To link the objects to form the binary
gfortran -o hello_world main.o
The names in fortran can have a maximum of 31 alphnumeric characters (letters, numbers, underscore). The first letter of the identifier must be letter. identifiers are case insensitive.
Fortran defaults to implicit typing. It means it will assign the variable type based on the first letter of the variable.
If the name of the variable starts with i, j, k, l, m or n, it is an integer. Otherwise it is an real number.
It is highly discouraged to use implicit typing. To disable implicit typing,
PROGRAM DISABLE
IMPLICIT NONE
END PROGRAM DISABLE
A variable is a data object which can be defined and redefined. All variables have a type to them. Varibles are to be declared at the beggining of a program or a sub program in a type declaration statement.
To declare a variable,
PROGRAM VARIABLE
IMPLICIT NONE
INTEGER :: VAR_1
END PROGRAM VARIABLE
All variables have implicit type assigned to them by default. To avoid it, use IMPLICIT NONE keyword.
A constant is a data object whose value cannot be changed.
A literal constant is a value without a name such as 3.14(real constant), "Hello"(character constant), (3.0,3.1)(complex constant), true(literal constant).
A named constant is a constant value with name. To declare a named constant, declare it with the rest of the variables at the beginning of the program with the parameter attribute.
PROGRAM CONSTANTS
IMPLICIT NONE
INTEGER, PARAMETER :: CONST_1 = 500
END PROGRAM CONSTANTS
Fortran has 5 intrinsic data types. Fortran allows you to use derived data types which are created by the user.
INTEGER type allows you to use integers.
For real numbers the processor provides two REAL types,
- single precision (default REAL)
- double precision
For COMPLEX number. Consist of two real numbers for real and complex part. For 2+1i, the value is (2.0,1.0)
To assign a variable to another complex, use CMPLX() function.
Two LOGICAL values. .TRUE. and .FALSE.. Periods are important.
For characters and strings. Length of the string is specified by the LEN specifier. If no length is specified, the default is 1.
Series of variables can be collected into array. Arrays can be 1 - 7 dimensional arrays. Arrays are declared with DIMENSION attribute. Fortran arrays follow 1 based indexing.
To declare the array,
PROGRAM ARRAYS
IMPLICIT NONE
! Array with 3 x 4 x 5 dimension.
REAL, DIMENSION(3,4,5) :: MATRIX
END PROGRAM ARRAYS
To declare explicit lower bounds,
PROGRAM ARRAYS
IMPLICIT NONE
! Array with 3 x 4 x 5 dimension.
REAL, DIMENSION(0:4) :: MATRIX
END PROGRAM ARRAYS
String is a character array. The length of the string can be specified with the LEN parameter. The slices of string can be referred with (m:n) parameter.
To declare a string,
PROGRAM STRING
IMPLICIT NONE
CHARACTER(LEN = 20) :: STRING
STRING="lorem ipsum"
PRINT *,STRING
PRINT *,STRING(:4)
PRINT *,STRING(4:)
END PROGRAM STRING
Derived data type is basically a struct. It consists of different types inside it.
To access the types inside the derived type, use % operator. To create a derived type,
PROGRAM DERIVED_TYPE
TYPE :: PERSON
CHARACTER(LEN=20) :: NAME
INTEGER :: AGE
END TYPE PERSON
IMPLICIT NONE
TYPE(PERSON) :: PERSON_1
PERSON_1%CHARACTER="John Doe"
PERSON_1%AGE=18
END PROGRAM DERIVED_TYPE
Fortran supports the following operators,
- exponentiation **
- multiplication *
- division /
- addition +
- subtraction -
Fortran follows integer division by default, if no types are specified. To do real division, use the REAL() function.
Fortran supports the following operators,
- .NOT.
- .AND.
- .OR.
- .EQV.
- .NEQV.
.EQV. and .NEQV. are only for logical statements.
Fortran supports the following operators,
- == (Equal to)
- > (Greater than)
- >= (Greater than or equal to)
- < (Less than)
- <= (Less than or equal to)
- /= (Not equal to)
Fortran provides these intrinsic function by default.
Function name | Purpose |
---|---|
abs(x) | absolute value of numeric argument |
acos(x) | inverse cosine function |
asin (x) | inverse sine function |
atan (x) | inverse tan function |
complx (x, y, [,ikind]) | converts to complex |
cos (x) | cos function |
cosh (x) | hyperbolic cosine function |
exp (x) | exponential function |
floor (x) | greatest integer less than or equal to x |
int (x) | convert to int. Removes the decimal off |
log (x) | calculate the natural log of x |
log10 (x) | calculate the log base 10 of x |
mod (x,y) | remainder function of dividing x/y. x - int(x/y)*y |
modulo (x/y) | modulo function (x - floor(x/y)*y) |
nint (x, [,ikind]) | round to nearest integer |
real (x, [,ikind]) | convert to the real number |
sin (x) | sine function |
sinh (x) | hyperbolic sine function |
sqrt (x) | square root function |
tan (x) | tan function |
tanh (x) | hyperbolic tan function |
To output a text in fortran we use PRINT or WRITE functions.
- PRINT will only writes to the stdout.
- WRITE can write to any file descriptor.
Prints the given args to the stdout.
PRINT f [, iolist]
PRINT grname
PRINT takes the following arguments,
- f (format identifier)
- iolist (list of variables, substrings, arrays, records)
- grname (name of Namelist group)
f is an format identifier and can be,
- An asterisk (*) which indicates list-directed io
- The label of the FORMAT statement in the program.
- Integer of the label of FORMAT
- String that identifies the format.
iolist can be empty or contain these output items.
- Variables
- Substrings
- Arrays
- Array elements
- Record fields
- Any other expression
grname is name of the namelist.
Reads from the unit identifier given to the args specified.
READ([UNIT=] u [, [FMT=]f] [, IOSTAT=ios] [, REC=rn] [, END=s] [, ERR=s])iolist
READ f [, iolist]
READ grname
u can either be external unit identifier or internal file identifier.
An external unit identifier must be one of these:
- A nonegative integer expression
- An asterisk(*), identifying the stdin.
f is an format identifier and can be,
- An asterisk (*) which indicates list-directed io
- The label of the FORMAT statement in the program.
- Integer of the label of FORMAT
- String that identifies the format.
ios must be an integer variable or an integer array element. This will be set to zero if the read is successful and set to positive number if the read is unsuccessful.
rn must be a positive integer expression, and can be used for direct-access files only. rn can be specified for internal files.
s must be the label of an executable statement in the same program unit in which the READ statement occurs.
s must be the label of an executable statement in the same program unit in which the READ statement occurs.
iolist can be empty or contain these output items.
- Variables
- Substrings
- Arrays
- Array elements
- Record fields
- Any other expression
grname is name of the namelist.
Writes to the unit identifier given to the args specified.
WRITE([UNIT=] u [, [FMT=]f] [, IOSTAT=ios] [, REC=rn] [, END=s] [, ERR=s])iolist
WRITE f [, iolist]
WRITE grname
u can either be external unit identifier or internal file identifier.
An external unit identifier must be one of these:
- A nonegative integer expression
- An asterisk(*), identifying the stdin.
f is an format identifier and can be,
- An asterisk (*) which indicates list-directed io
- The label of the FORMAT statement in the program.
- Integer of the label of FORMAT
- String that identifies the format.
ios must be an integer variable or an integer array element. This will be set to zero if the write is successful and set to positive number if the read is unsuccessful.
rn must be a positive integer expression, and can be used for direct-access files only. rn can be specified for internal files.
s must be the label of an executable statement in the same program unit in which the WRITE statement occurs.
s must be the label of an executable statement in the same program unit in which the WRITE statement occurs.
iolist can be empty or contain these output items.
- Variables
- Substrings
- Arrays
- Array elements
- Record fields
- Any other expression
grname is name of the namelist.
IF statement is used to run a program if the condition given is true.
LABEL IF (LOGICAL_EXPRESSION) THEN
!STATEMENT
END IF LABEL
The label is optional for the if statement.
Both ENDIF and END IF is allowed.
ELSE statement can also be used along with the IF for running statements if condition was false.
LABEL IF (LOGICAL_EXPRESSION) THEN
!STATEMENT
ELSE
!ALTERNATE STATEMENTS
END IF LABEL
Block if statements can be nested.
LABEL IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 1
ELSE IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 2
ELSE IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 3
ELSE IF (LOGICAL_EXPRESSION) THEN
!STATEMENT 4
ELSE
!ALTERNATE STATEMENTS
END IF LABEL
The case construct has the following form,
LABEL SELECT CASE (EXPRESSION)
CASE (SELECTOR_1):
!STATEMENT
CASE (SELECTOR_2):
!STATEMENT
CASE (SELECTOR_3):
!STATEMENT
CASE DEFAULT:
!DEFAULT STATEMENT
END SELECT LABEL
Range of numbers can be specified in a case using (m:n)
The simplest loop can be achieved using DO loop in fortran. The following code is an endless loop.
LABEL DO
!STATEMENT
END DO LABEL
To break out of the do loop, use the EXIT statement.
LABEL DO
!STATEMENT
IF (EXPRESSION) THEN
EXIT
END IF
END DO LABEL
To skip to the next iteration use CYCLE statement.
LABEL DO
!STATEMENT
IF (EXPRESSION) THEN
CYCLE
END IF
END DO LABEL
To specify a do to iterate said times. use a DO VAR=START, END, STEP statement
INTEGER :: I !CONTROL VARIABLE
DO I=0,5
!STATEMENTS
END DO
To execute a condition while true, use DO WHILE loop.
LABEL DO WHILE (LOGICAL EXPRESSION)
!STATEMENTS
END DO WHILE LABEL
A program can be built up from a collection of program units. They are,
- Main program
- Modules
- External subprogramms or Procedures
Subprogramms or Procedures can be called from the program.They can be,
- Functions
- Subroutines
Functions accepts arguments and returns a single quantity of any type including arrays.
Functions in principle should not modify the arguments. It is a bad practice.
Functions are of two types. They are,
- Intrinsic Functions: They are built into the language itself.
- External Functions: They are user defined.
Structure of functions is,
FUNCTION CIRCLE_AREA (RADIUS)
IMPLICIT NONE
REAL :: CIRCLE_AREA
REAL :: RADIUS
REAL, PARAMETER :: PI = 3.141592654
CIRCLE_AREA = PI * ( R**2 )
END FUNCTION CIRCLE_AREA
Functions return value is the function name itself. Return type and the argument type should be declared inside the function. Arguments are dummy and the real variable from where the function is called is used.
Note that IMPLICIT NONE should be used inside the function as well as the main program.
The result of the function can be given a different name using the RESULT option. The RESULT option is optional in most cases but must be used when using the recursive functions.
FUNCTION CIRCLE_AREA (RADIUS) RESULT (AREA)
IMPLICIT NONE
REAL :: CIRCLE_AREA
REAL :: RADIUS
REAL, PARAMETER :: PI = 3.141592654
AREA = PI * ( R**2 )
END FUNCTION CIRCLE_AREA
To call the function from the program, one must declare the function with type to use. Functions can be assigned to the variables directly.
PROGRAM MAIN
IMPLICIT NONE
REAL, PARAMETER :: RADIUS = 2
REAL :: CIRCLE_AREA
PRINT *, CIRCLE_AREA (RADIUS)
END PROGRAM MAIN
FUNCTION CIRCLE_AREA (RADIUS)
IMPLICIT NONE
REAL :: CIRCLE_AREA
REAL :: RADIUS
REAL, PARAMETER :: PI = 3.141592654
CIRCLE_AREA = PI * ( R**2 )
END FUNCTION CIRCLE_AREA
To return from a function early, use the RETURN keyword.
Functions are only used in case it returns only one thing. In all other cases, subroutines are used. Subroutines returns nothing. Subroutines may or may not modify the arguments given. Subroutines has to be called and cannot be assigned to a variable.
PROGRAM SWAP_NUMBERS
IMPLICIT NONE
REAL :: X = 5
REAL :: Y = 6
PRINT *,X,Y
CALL SWAP (X,Y)
PRINT *,X,Y
END PROGRAM SWAP_NUMBERS
SUBROUTINE SWAP (X,Y)
IMPLICIT NONE
REAL :: BUFFER
REAL :: X
REAL :: Y
BUFFER = X
X = Y
Y = BUFFER
END SUBROUTINE SWAP
Fortran allows the specification of intention of the arguments used for in the subroutine. There are three intents,
- INTENT (IN) Arguments are read only
- INTENT (OUT) Arguments are write only
- INTENT (INOUT) Arguments are read and write allowed
Intents are mentioned as options in argument type declaration.
PROGRAM SWAP_NUMBERS
IMPLICIT NONE
REAL, INTENT (INOUT) :: X = 5
REAL, INTENT (INOUT) :: Y = 6
PRINT *,X,Y
CALL SWAP (X,Y)
PRINT *,X,Y
END PROGRAM SWAP_NUMBERS
SUBROUTINE SWAP (X,Y)
IMPLICIT NONE
REAL :: BUFFER
REAL :: X
REAL :: Y
BUFFER = X
X = Y
Y = BUFFER
END SUBROUTINE SWAP
This project is licensed under GNU GPL v3.0 or later license. Feel free to use the project.