Fortran is one of the oldest computer languages. It was developed in the 1950s by IBM for numeric calculations (Fortran is an abbreviation of «Formula Translation»). Despite its age, it is still used for high-performance computing such as weather prediction. However, the language has changed considerably over the years, although mostly maintaining backwards compatibility; well known versions are FORTRAN 77, Fortran 90, Fortran 95, Fortran 2003, Fortran 2008, Fortran 2018 and Fortran 2023.
This overview will discuss the features of Fortran 2008 since it is the most widely implemented of the more recent specifications and the later versions are largely similar (by comparison FORTRAN 77 is a very different language).
1! This is a comment.
2
3program example ! declare a program called example.
4
5 ! Code can only exist inside programs, functions, subroutines or modules.
6 ! Using indentation is not required but it is recommended.
7
8 ! Declaring Variables
9 ! ===================
10
11 ! All declarations must come before statements and expressions.
12
13 implicit none ! prevents dynamic declaration of variables
14 ! Recommended!
15 ! Implicit none must be redeclared in every function/program/module...
16
17 ! IMPORTANT - Fortran is case insensitive.
18 real z
19 REAL Z2
20
21 real :: v, x ! WARNING: default initial values are compiler dependent!
22 real :: a = 3, b = 2E12, c = 0.01
23 integer :: i, j, k = 1, m
24 real, parameter :: PI = 3.14159265 ! declare a constant.
25 logical :: y = .TRUE., n = .FALSE. ! boolean type.
26 complex :: w = (0, 1) ! sqrt(-1)
27 character(len=3) :: month ! string of 3 characters.
28
29 ! declare an array of 6 reals.
30 real :: array(6)
31 ! another way to declare an array.
32 real, dimension(4) :: arrayb
33 ! an array with a custom index -10 to 10 (inclusive)
34 integer :: arrayc(-10:10)
35 ! A multidimensional array.
36 real :: array2d(3, 2)
37
38 ! The '::' separators are not always necessary but are recommended.
39
40 ! many other variable attributes also exist:
41 real, pointer :: p ! declare a pointer.
42
43 integer, parameter :: LP = selected_real_kind(20)
44 real(kind=LP) :: d ! long precision variable.
45
46 ! WARNING: initialising variables during declaration causes problems
47 ! in functions since this automatically implies the 'save' attribute
48 ! whereby values are saved between function calls. In general, separate
49 ! declaration and initialisation code except for constants!
50
51 ! Strings
52 ! =======
53
54 character :: a_char = 'i'
55 character(len=6) :: a_str = "qwerty"
56 character(len=30) :: str_b
57 character(len=*), parameter :: a_long_str = "This is a long string."
58 !can have automatic counting of length using (len=*) but only for constants.
59
60 str_b = a_str//" keyboard" ! concatenate strings using // operator.
61
62 ! Assignment & Arithmetic
63 ! =======================
64
65 Z = 1 ! assign to variable z declared above
66 j = 10 + 2 - 3
67 a = 11.54/(2.3*3.1)
68 b = 2**3 ! exponentiation
69
70 ! Control Flow Statements & Operators
71 ! ===================================
72
73 ! Single-line if statement
74 if (z == a) b = 4 ! conditions always need parentheses.
75
76 if (z /= a) then ! z not equal to a
77 ! Other symbolic comparisons are < > <= >= == /=
78 b = 4
79 else if (z .GT. a) then ! z greater than a
80 ! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE.
81 b = 6
82 else if (z < a) then ! 'then' must be on this line.
83 b = 5 ! execution block must be on a new line.
84 else
85 b = 10
86 end if ! end statement needs the 'if'
87
88 if (.NOT. (x < c .AND. v >= a .OR. z == z)) then ! boolean operators.
89 inner: if (.TRUE.) then ! can name if-construct.
90 b = 1
91 end if inner ! then must name endif statement.
92 endif ! 'endif' is equivalent to 'end if'
93
94 i = 20
95 select case (i)
96 case (0, 1) ! cases i == 0 or i == 1
97 j = 0
98 case (2:10) ! cases i is 2 to 10 inclusive.
99 j = 1
100 case (11:) ! all cases where i>=11
101 j = 2
102 case default
103 j = 3
104 end select
105
106 month = 'jan'
107 ! Condition can be integer, logical or character type.
108 ! Select constructions can also be named.
109 monthly:select case(month)
110 case ("jan")
111 j = 0
112 case default
113 j = -1
114 end select monthly
115
116 do i = 2, 10, 2 ! loops from 2 to 10 (inclusive) in steps of 2.
117 innerloop: do j = 1, 3 ! loops can be named too.
118 exit ! quits the loop.
119 end do innerloop
120 cycle ! jump to next loop iteration.
121 end do
122
123 ! Goto statement exists but it is heavily discouraged.
124 goto 10
125 stop 1 ! stops the program, returns condition code 1.
12610 j = 201 ! this line is labeled as line 10
127
128 ! Arrays
129 ! ======
130 array = (/1, 2, 3, 4, 5, 6/)
131 array = [1, 2, 3, 4, 5, 6] ! using Fortran 2003 notation.
132 arrayb = [10.2, 3e3, 0.41, 4e-5]
133 array2d = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [3, 2])
134
135 ! Fortran array indexing starts from 1.
136 ! (by default but can be defined differently for specific arrays).
137 v = array(1) ! take first element of array.
138 v = array2d(2, 2)
139
140 print *, array(3:5) ! print all elements from 3rd to 5th (inclusive).
141 print *, array2d(1, :) ! print first column of 2d array.
142
143 array = array*3 + 2 ! can apply mathematical expressions to arrays.
144 array = array*array ! array operations occur element-wise.
145 ! array = array*array2d ! these arrays would not be compatible.
146
147 ! There are many built-in functions that operate on arrays.
148 c = dot_product(array, array) ! this is the dot product.
149 ! Use matmul() for matrix maths.
150 c = sum(array)
151 c = maxval(array)
152 print *, minloc(array)
153 c = size(array)
154 print *, shape(array)
155 m = count(array > 0)
156
157 ! Loop over an array (could have used Product() function normally).
158 v = 1
159 do i = 1, size(array)
160 v = v*array(i)
161 end do
162
163 ! Conditionally execute element-wise assignments.
164 array = [1, 2, 3, 4, 5, 6]
165 where (array > 3)
166 array = array + 1
167 elsewhere(array == 2)
168 array = 1
169 elsewhere
170 array = 0
171 end where
172
173 ! Implied-DO loops are a compact way to create arrays.
174 array = [(i, i=1, 6)] ! creates an array of [1,2,3,4,5,6]
175 array = [(i, i=1, 12, 2)] ! creates an array of [1,3,5,7,9,11]
176 array = [(i**2, i=1, 6)] ! creates an array of [1,4,9,16,25,36]
177 array = [(4, 5, i=1, 3)] ! creates an array of [4,5,4,5,4,5]
178
179 ! Input/Output
180 ! ============
181
182 print *, b ! print the variable 'b' to the command line
183
184 ! We can format our printed output.
185 print "(I6)", 320 ! prints ' 320'
186 print "(I6.4)", 3 ! prints ' 0003'
187 print "(F6.3)", 4.32 ! prints ' 4.320'
188
189 ! The letter indicates the expected type and the number afterwards gives
190 ! the number of characters to use for printing the value.
191 ! Letters can be I (integer), F (real), E (engineering format),
192 ! L (logical), A (characters) ...
193 print "(I3)", 3200 ! print '***' since the number doesn't fit.
194
195 ! we can have multiple format specifications.
196 print "(I5,F6.2,E6.2)", 120, 43.41, 43.41
197
198 ! 3 repeats of integers (field width = 5).
199 print "(3I5)", 10, 20, 30
200
201 ! repeated grouping of formats.
202 print "(2(I5,F6.2))", 120, 43.42, 340, 65.3
203
204 ! We can also read input from the terminal.
205 read (*, *) v
206 read (*, "(2F6.2)") v, x ! read two numbers
207
208 ! To write a file.
209 open (unit=12, file="records.txt", status="replace")
210 ! The file is referred to by a 'unit number', an integer that you pick in
211 ! the range 9:99. Status can be one of {'old','replace','new'}.
212 write (12, "(F10.2,F10.2,F10.2)") c, b, a
213 close (12)
214
215 ! To read a file.
216 open (newunit=m, file="records.txt", status="old")
217 ! The file is referred to by a 'new unit number',
218 ! an integer that the compiler picks for you.
219
220 read (unit=m, fmt="(3F10.2)") a, b, c
221 close (m)
222
223 ! There are more features available than discussed here and alternative
224 ! variants due to backwards compatibility with older Fortran versions.
225
226 ! Built-in Functions
227 ! ==================
228
229 ! Fortran has around 200 functions/subroutines intrinsic to the language.
230 ! Examples -
231 call cpu_time(v) ! sets 'v' to a time in seconds.
232 k = ior(i, j) ! bitwise OR of 2 integers.
233 v = log10(x) ! log base 10.
234 i = floor(b) ! converts b to integer by rounding down.
235 v = aimag(w) ! imaginary part of a complex number.
236
237 ! Functions & Subroutines
238 ! =======================
239
240 ! A subroutine runs some code on some input values and can cause
241 ! side-effects or modify the input values.
242
243 call routine(a, c, v) ! subroutine call.
244
245 ! A function takes several input parameters and returns a single value.
246 ! However the input parameters may still be modified and side effects
247 ! executed.
248
249 m = func(3, 2, k) ! function call.
250
251 ! Function calls can also be evoked within expressions.
252 print *, func2(3, 2, k)
253
254 ! A pure function is a function that doesn't modify its input
255 ! parameters or cause any side-effects.
256 m = func3(3, 2, k)
257
258contains ! Start defining the program's internal procedures:
259
260 ! Fortran has a couple of slightly different ways to define functions.
261
262 integer function func(a, b, c) ! a function returning an integer value.
263 ! implicit none ! - no longer used in subvariable fields
264 integer, intent(in) :: a, b, c ! type of input parameters
265 ! the return variable defaults to the function name.
266
267 if (a >= 2) then
268 func = a + b + c
269 return ! returns the current value at 'func'
270 end if
271 func = a + c
272
273 ! Don't need a return statement at the end of a function.
274 end function func
275
276 function func2(a, b, c) result(f) ! return variable declared to be 'f'.
277 integer, intent(in) :: a, b ! can declare and enforce that variables
278 !are not modified by the function.
279 integer, intent(inout) :: c
280 integer :: f
281 ! function return type declared inside the function.
282 integer :: cnt = 0 ! GOTCHA -
283 ! assigning a value at initalization
284 ! implies that the variable is
285 ! saved between function calls.
286
287 f = a + b - c
288 c = 4 ! changing value of input variable c.
289 cnt = cnt + 1 ! count number of function calls.
290
291 end function func2
292
293 pure function func3(a, b, c) ! a pure function has no side-effects.
294 integer, intent(in) :: a, b, c
295 integer :: func3
296
297 func3 = a*b*c
298
299 end function func3
300
301 ! a subroutine does not return anything,
302 ! but can change the value of arguments.
303 subroutine routine(d, e, f)
304 real, intent(inout) :: f
305 real, intent(in) :: d, e
306
307 f = 2*d + 3*e + f
308
309 end subroutine routine
310
311end program example
312! End of Program Definition -----------------------
313
314! Functions and Subroutines declared externally to the program listing need
315! to be declared to the program using an Interface declaration (even if they
316! are in the same source file!) (see below). It is easier to define them within
317! the 'contains' section of a module or program.
318
319elemental real function func4(a) result(res)
320! An elemental function is a Pure function that takes a scalar input variable
321! but can also be used on an array where it will be separately applied to all
322! of the elements of an array and return a new array.
323 real, intent(in) :: a
324
325 res = a**2 + 1.0
326
327end function func4
328
329! Modules
330! =======
331
332! A module is a useful way to collect related declarations, functions and
333! subroutines together for reusability.
334
335module fruit
336
337 real :: apple
338 real :: pear
339 real :: orange
340
341end module fruit
342
343module fruity
344 ! Declarations must be in the order: modules, interfaces, variables.
345 ! (can declare modules and interfaces in programs too).
346
347 use fruit, only: apple, pear ! use apple and pear from fruit module.
348 implicit none ! comes after module imports.
349
350 ! By default all module data and functions will be public
351 private ! Instead set default to private
352 ! Declare some variables/functions explicitly public.
353 public :: apple, mycar, create_mycar
354 ! Declare some variables/functions private to the module (redundant here).
355 private :: func4
356
357 ! Interfaces
358 ! ==========
359 ! Explicitly declare an external function/procedure within the module
360 ! (better in general to put functions/procedures in the 'contains' section).
361 interface
362 elemental real function func4(a) result(res)
363 real, intent(in) :: a
364 end function func4
365 end interface
366
367 ! Overloaded functions can be defined using named interfaces.
368 interface myabs
369 ! Can use 'module procedure' keyword to include functions already
370 ! defined within the module.
371 module procedure real_abs, complex_abs
372 end interface
373
374 ! Derived Data Types
375 ! ==================
376 ! Can create custom structured data collections.
377 type car
378 character(len=100) :: model
379 real :: weight ! (kg)
380 real :: dimensions(3) ! i.e. length-width-height (metres).
381 character :: colour
382 contains
383 procedure :: info ! bind a procedure to a type.
384 end type car
385
386 type(car) :: mycar ! declare a variable of your custom type.
387 ! See create_mycar() routine for usage.
388
389 ! Note: There are no executable statements in modules.
390
391contains
392
393 subroutine create_mycar(mycar)
394 ! Demonstrates usage of a derived data type.
395 type(car), intent(out) :: mycar
396
397 ! Access type elements using '%' operator.
398 mycar%model = "Ford Prefect"
399 mycar%colour = 'r'
400 mycar%weight = 1400
401 mycar%dimensions(1) = 5.0 ! default indexing starts from 1!
402 mycar%dimensions(2) = 3.0
403 mycar%dimensions(3) = 1.5
404
405 end subroutine create_mycar
406
407 subroutine info(self)
408 class(car), intent(in) :: self
409 ! 'class' keyword used to bind a procedure to a type here.
410
411 print *, "Model : ", self%model
412 print *, "Colour : ", self%colour
413 print *, "Weight : ", self%weight
414 print *, "Dimensions: ", self%dimensions
415
416 end subroutine info
417
418 real pure function real_abs(x)
419 real, intent(in) :: x
420
421 if (x < 0) then
422 real_abs = -x
423 else
424 real_abs = x
425 end if
426
427 end function real_abs
428
429 real pure function complex_abs(z)
430 complex, intent(in) :: z
431 ! long lines can be continued using the continuation character '&'
432
433 complex_abs = sqrt(real(z)**2 + &
434 aimag(z)**2)
435
436 end function complex_abs
437
438end module fruity
439
440! ISO Standard Fortran 2008 introduced the DO CONCURRENT construct to allow you
441! to express loop-level parallelism
442
443integer :: i
444real :: array(10)
445
446DO CONCURRENT (i = 1:size(array))
447 array(i) = sqrt(real(i)**i)
448END DO
449
450
451! Only calls to pure functions are allowed inside the loop and we can declare
452! multiple indices:
453
454integer :: x, y
455real :: array(8, 16)
456
457do concurrent (x = 1:size(array, 1), y = 1:size(array, 2))
458 array(x, y) = real(x)
459end do
460
461! loop indices can also declared inside the contruct:
462
463real :: array(8, 16)
464
465do concurrent (integer :: x = 1:size(array, 1), y = 1:size(array, 2))
466 array(x, y) = real(x)
467end do
More Resources ¶
For more information on Fortran: