mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-01-17 13:38:38 +01:00
remove trailing spaces
This commit is contained in:
parent
72e1462437
commit
84272ab865
@ -5,8 +5,8 @@ contributors:
|
|||||||
filename: learnfortran.f90
|
filename: learnfortran.f90
|
||||||
---
|
---
|
||||||
|
|
||||||
Fortran is one of the oldest computer languages. It was developed in the 1950s
|
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
|
by IBM for numeric calculations (Fortran is an abbreviation of "Formula
|
||||||
Translation"). Despite its age, it is still used for high-performance computing
|
Translation"). Despite its age, it is still used for high-performance computing
|
||||||
such as weather prediction. However, the language has changed considerably over
|
such as weather prediction. However, the language has changed considerably over
|
||||||
the years, although mostly maintaining backwards compatibility; well known
|
the years, although mostly maintaining backwards compatibility; well known
|
||||||
@ -30,29 +30,29 @@ program example !declare a program called example.
|
|||||||
|
|
||||||
! Declaring Variables
|
! Declaring Variables
|
||||||
! ===================
|
! ===================
|
||||||
|
|
||||||
! All declarations must come before statements and expressions.
|
! All declarations must come before statements and expressions.
|
||||||
|
|
||||||
implicit none !prevents dynamic declaration of variables (recommended!)
|
implicit none !prevents dynamic declaration of variables (recommended!)
|
||||||
! Implicit none must be redeclared in every function/program/module...
|
! Implicit none must be redeclared in every function/program/module...
|
||||||
|
|
||||||
! IMPORTANT - Fortran is case insensitive.
|
! IMPORTANT - Fortran is case insensitive.
|
||||||
real z
|
real z
|
||||||
REAL Z2
|
REAL Z2
|
||||||
|
|
||||||
real :: v,x ! WARNING: default initial values are compiler dependent!
|
real :: v,x ! WARNING: default initial values are compiler dependent!
|
||||||
real :: a = 3, b=2E12, c = 0.01
|
real :: a = 3, b=2E12, c = 0.01
|
||||||
integer :: i, j, k=1, m
|
integer :: i, j, k=1, m
|
||||||
real, parameter :: PI = 3.1415926535897931 !declare a constant.
|
real, parameter :: PI = 3.1415926535897931 !declare a constant.
|
||||||
logical :: y = .TRUE. , n = .FALSE. !boolean type.
|
logical :: y = .TRUE. , n = .FALSE. !boolean type.
|
||||||
complex :: w = (0,1) !sqrt(-1)
|
complex :: w = (0,1) !sqrt(-1)
|
||||||
character (len=3) :: month !string of 3 characters.
|
character (len=3) :: month !string of 3 characters.
|
||||||
|
|
||||||
real :: array(6) !declare an array of 6 reals.
|
real :: array(6) !declare an array of 6 reals.
|
||||||
real, dimension(4) :: arrayb !another way to declare an array.
|
real, dimension(4) :: arrayb !another way to declare an array.
|
||||||
integer :: arrayc(-10:10) !an array with a custom index.
|
integer :: arrayc(-10:10) !an array with a custom index.
|
||||||
real :: array2d(3,2) !multidimensional array.
|
real :: array2d(3,2) !multidimensional array.
|
||||||
|
|
||||||
! The '::' separators are not always necessary but are recommended.
|
! The '::' separators are not always necessary but are recommended.
|
||||||
|
|
||||||
! many other variable attributes also exist:
|
! many other variable attributes also exist:
|
||||||
@ -65,8 +65,8 @@ program example !declare a program called example.
|
|||||||
! in functions since this automatically implies the 'save' attribute
|
! in functions since this automatically implies the 'save' attribute
|
||||||
! whereby values are saved between function calls. In general, separate
|
! whereby values are saved between function calls. In general, separate
|
||||||
! declaration and initialisation code except for constants!
|
! declaration and initialisation code except for constants!
|
||||||
|
|
||||||
|
|
||||||
! Strings
|
! Strings
|
||||||
! =======
|
! =======
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ program example !declare a program called example.
|
|||||||
character (len = 30) :: str_b
|
character (len = 30) :: str_b
|
||||||
character (len = *), parameter :: a_long_str = "This is a long string."
|
character (len = *), parameter :: a_long_str = "This is a long string."
|
||||||
!can have automatic counting of length using (len=*) but only for constants.
|
!can have automatic counting of length using (len=*) but only for constants.
|
||||||
|
|
||||||
str_b = a_str // " keyboard" !concatenate strings using // operator.
|
str_b = a_str // " keyboard" !concatenate strings using // operator.
|
||||||
|
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ program example !declare a program called example.
|
|||||||
! Other symbolic comparisons are < > <= >= == /=
|
! Other symbolic comparisons are < > <= >= == /=
|
||||||
b = 4
|
b = 4
|
||||||
else if (z .GT. a) then !z greater than a
|
else if (z .GT. a) then !z greater than a
|
||||||
! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE.
|
! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE.
|
||||||
b = 6
|
b = 6
|
||||||
else if (z < a) then !'then' must be on this line.
|
else if (z < a) then !'then' must be on this line.
|
||||||
b = 5 !execution block must be on a new line.
|
b = 5 !execution block must be on a new line.
|
||||||
@ -145,32 +145,32 @@ program example !declare a program called example.
|
|||||||
cycle !jump to next loop iteration.
|
cycle !jump to next loop iteration.
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
|
||||||
! Goto statement exists but it is heavily discouraged though.
|
! Goto statement exists but it is heavily discouraged though.
|
||||||
goto 10
|
goto 10
|
||||||
stop 1 !stops code immediately (returning specified condition code).
|
stop 1 !stops code immediately (returning specified condition code).
|
||||||
10 j = 201 !this line is labeled as line 10
|
10 j = 201 !this line is labeled as line 10
|
||||||
|
|
||||||
|
|
||||||
! Arrays
|
! Arrays
|
||||||
! ======
|
! ======
|
||||||
array = (/1,2,3,4,5,6/)
|
array = (/1,2,3,4,5,6/)
|
||||||
array = [1,2,3,4,5,6] !using Fortran 2003 notation.
|
array = [1,2,3,4,5,6] !using Fortran 2003 notation.
|
||||||
arrayb = [10.2,3e3,0.41,4e-5]
|
arrayb = [10.2,3e3,0.41,4e-5]
|
||||||
array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2])
|
array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2])
|
||||||
|
|
||||||
! Fortran array indexing starts from 1.
|
! Fortran array indexing starts from 1.
|
||||||
! (by default but can be defined differently for specific arrays).
|
! (by default but can be defined differently for specific arrays).
|
||||||
v = array(1) !take first element of array.
|
v = array(1) !take first element of array.
|
||||||
v = array2d(2,2)
|
v = array2d(2,2)
|
||||||
|
|
||||||
print *, array(3:5) !print all elements from 3rd to 5th (inclusive).
|
print *, array(3:5) !print all elements from 3rd to 5th (inclusive).
|
||||||
print *, array2d(1,:) !print first column of 2d array.
|
print *, array2d(1,:) !print first column of 2d array.
|
||||||
|
|
||||||
array = array*3 + 2 !can apply mathematical expressions to arrays.
|
array = array*3 + 2 !can apply mathematical expressions to arrays.
|
||||||
array = array*array !array operations occur element-wise.
|
array = array*array !array operations occur element-wise.
|
||||||
!array = array*array2d !these arrays would not be compatible.
|
!array = array*array2d !these arrays would not be compatible.
|
||||||
|
|
||||||
! There are many built-in functions that operate on arrays.
|
! There are many built-in functions that operate on arrays.
|
||||||
c = dot_product(array,array) !this is the dot product.
|
c = dot_product(array,array) !this is the dot product.
|
||||||
! Use matmul() for matrix maths.
|
! Use matmul() for matrix maths.
|
||||||
@ -180,13 +180,13 @@ program example !declare a program called example.
|
|||||||
c = size(array)
|
c = size(array)
|
||||||
print *, shape(array)
|
print *, shape(array)
|
||||||
m = count(array > 0)
|
m = count(array > 0)
|
||||||
|
|
||||||
! Loop over an array (could have used Product() function normally).
|
! Loop over an array (could have used Product() function normally).
|
||||||
v = 1
|
v = 1
|
||||||
do i = 1, size(array)
|
do i = 1, size(array)
|
||||||
v = v*array(i)
|
v = v*array(i)
|
||||||
end do
|
end do
|
||||||
|
|
||||||
! Conditionally execute element-wise assignments.
|
! Conditionally execute element-wise assignments.
|
||||||
array = [1,2,3,4,5,6]
|
array = [1,2,3,4,5,6]
|
||||||
where (array > 3)
|
where (array > 3)
|
||||||
@ -196,30 +196,30 @@ program example !declare a program called example.
|
|||||||
elsewhere
|
elsewhere
|
||||||
array = 0
|
array = 0
|
||||||
end where
|
end where
|
||||||
|
|
||||||
! Implied-DO loops are a compact way to create arrays.
|
! Implied-DO loops are a compact way to create arrays.
|
||||||
array = [ (i, i = 1,6) ] !creates an array of [1,2,3,4,5,6]
|
array = [ (i, i = 1,6) ] !creates an array of [1,2,3,4,5,6]
|
||||||
array = [ (i, i = 1,12,2) ] !creates an array of [1,3,5,7,9,11]
|
array = [ (i, i = 1,12,2) ] !creates an array of [1,3,5,7,9,11]
|
||||||
array = [ (i**2, i = 1,6) ] !creates an array of [1,4,9,16,25,36]
|
array = [ (i**2, i = 1,6) ] !creates an array of [1,4,9,16,25,36]
|
||||||
array = [ (4,5, i = 1,3) ] !creates an array of [4,5,4,5,4,5]
|
array = [ (4,5, i = 1,3) ] !creates an array of [4,5,4,5,4,5]
|
||||||
|
|
||||||
|
|
||||||
! Input/Output
|
! Input/Output
|
||||||
! ============
|
! ============
|
||||||
|
|
||||||
print *, b !print the variable 'b' to the command line
|
print *, b !print the variable 'b' to the command line
|
||||||
|
|
||||||
! We can format our printed output.
|
! We can format our printed output.
|
||||||
print "(I6)", 320 !prints ' 320'
|
print "(I6)", 320 !prints ' 320'
|
||||||
print "(I6.4)", 3 !prints ' 0003'
|
print "(I6.4)", 3 !prints ' 0003'
|
||||||
print "(F6.3)", 4.32 !prints ' 4.320'
|
print "(F6.3)", 4.32 !prints ' 4.320'
|
||||||
|
|
||||||
! The letter indicates the expected type and the number afterwards gives
|
! The letter indicates the expected type and the number afterwards gives
|
||||||
! the number of characters to use for printing the value.
|
! the number of characters to use for printing the value.
|
||||||
! Letters can be I (integer), F (real), E (engineering format),
|
! Letters can be I (integer), F (real), E (engineering format),
|
||||||
! L (logical), A (characters) ...
|
! L (logical), A (characters) ...
|
||||||
print "(I3)", 3200 !print '***' since the number doesn't fit.
|
print "(I3)", 3200 !print '***' since the number doesn't fit.
|
||||||
|
|
||||||
! we can have multiple format specifications.
|
! we can have multiple format specifications.
|
||||||
print "(I5,F6.2,E6.2)", 120, 43.41, 43.41
|
print "(I5,F6.2,E6.2)", 120, 43.41, 43.41
|
||||||
print "(3I5)", 10, 20, 30 !3 repeats of integers (field width = 5).
|
print "(3I5)", 10, 20, 30 !3 repeats of integers (field width = 5).
|
||||||
@ -230,7 +230,7 @@ program example !declare a program called example.
|
|||||||
read "(2F6.2)", v, x !read two numbers
|
read "(2F6.2)", v, x !read two numbers
|
||||||
|
|
||||||
! To read a file.
|
! To read a file.
|
||||||
open(unit=11, file="records.txt", status="old")
|
open(unit=11, file="records.txt", status="old")
|
||||||
! The file is referred to by a 'unit number', an integer that you pick in
|
! The file is referred to by a 'unit number', an integer that you pick in
|
||||||
! the range 9:99. Status can be one of {'old','replace','new'}.
|
! the range 9:99. Status can be one of {'old','replace','new'}.
|
||||||
read(unit=11, fmt="(3F10.2)") a, b, c
|
read(unit=11, fmt="(3F10.2)") a, b, c
|
||||||
@ -241,39 +241,39 @@ program example !declare a program called example.
|
|||||||
write(12, "(F10.2,F10.2,F10.2)") c, b, a
|
write(12, "(F10.2,F10.2,F10.2)") c, b, a
|
||||||
close(12)
|
close(12)
|
||||||
|
|
||||||
! There are more features available than discussed here and alternative
|
! There are more features available than discussed here and alternative
|
||||||
! variants due to backwards compatibility with older Fortran versions.
|
! variants due to backwards compatibility with older Fortran versions.
|
||||||
|
|
||||||
|
|
||||||
! Built-in Functions
|
! Built-in Functions
|
||||||
! ==================
|
! ==================
|
||||||
|
|
||||||
! Fortran has around 200 functions/subroutines intrinsic to the language.
|
! Fortran has around 200 functions/subroutines intrinsic to the language.
|
||||||
! Examples -
|
! Examples -
|
||||||
call cpu_time(v) !sets 'v' to a time in seconds.
|
call cpu_time(v) !sets 'v' to a time in seconds.
|
||||||
k = ior(i,j) !bitwise OR of 2 integers.
|
k = ior(i,j) !bitwise OR of 2 integers.
|
||||||
v = log10(x) !log base 10.
|
v = log10(x) !log base 10.
|
||||||
i = floor(b) !returns the closest integer less than or equal to x.
|
i = floor(b) !returns the closest integer less than or equal to x.
|
||||||
v = aimag(w) !imaginary part of a complex number.
|
v = aimag(w) !imaginary part of a complex number.
|
||||||
|
|
||||||
|
|
||||||
! Functions & Subroutines
|
! Functions & Subroutines
|
||||||
! =======================
|
! =======================
|
||||||
|
|
||||||
! A subroutine runs some code on some input values and can cause
|
! A subroutine runs some code on some input values and can cause
|
||||||
! side-effects or modify the input values.
|
! side-effects or modify the input values.
|
||||||
|
|
||||||
call routine(a,c,v) !subroutine call.
|
call routine(a,c,v) !subroutine call.
|
||||||
|
|
||||||
! A function takes a list of input parameters and returns a single value.
|
! A function takes a list of input parameters and returns a single value.
|
||||||
! However the input parameters may still be modified and side effects
|
! However the input parameters may still be modified and side effects
|
||||||
! executed.
|
! executed.
|
||||||
|
|
||||||
m = func(3,2,k) !function call.
|
m = func(3,2,k) !function call.
|
||||||
|
|
||||||
! Function calls can also be evoked within expressions.
|
! Function calls can also be evoked within expressions.
|
||||||
Print *, func2(3,2,k)
|
Print *, func2(3,2,k)
|
||||||
|
|
||||||
! A pure function is a function that doesn't modify its input parameters
|
! A pure function is a function that doesn't modify its input parameters
|
||||||
! or cause any side-effects.
|
! or cause any side-effects.
|
||||||
m = func3(3,2,k)
|
m = func3(3,2,k)
|
||||||
@ -297,7 +297,7 @@ contains ! Zone for defining sub-programs internal to the program.
|
|||||||
|
|
||||||
function func2(a,b,c) result(f) !return variable declared to be 'f'.
|
function func2(a,b,c) result(f) !return variable declared to be 'f'.
|
||||||
implicit none
|
implicit none
|
||||||
integer, intent(in) :: a,b !can declare and enforce that variables
|
integer, intent(in) :: a,b !can declare and enforce that variables
|
||||||
!are not modified by the function.
|
!are not modified by the function.
|
||||||
integer, intent(inout) :: c
|
integer, intent(inout) :: c
|
||||||
integer :: f !function return type declared inside the function.
|
integer :: f !function return type declared inside the function.
|
||||||
@ -328,14 +328,14 @@ contains ! Zone for defining sub-programs internal to the program.
|
|||||||
end program example ! End of Program Definition -----------------------
|
end program example ! End of Program Definition -----------------------
|
||||||
|
|
||||||
|
|
||||||
! Functions and Subroutines declared externally to the program listing need
|
! Functions and Subroutines declared externally to the program listing need
|
||||||
! to be declared to the program using an Interface declaration (even if they
|
! to be declared to the program using an Interface declaration (even if they
|
||||||
! are in the same source file!) (see below). It is easier to define them within
|
! are in the same source file!) (see below). It is easier to define them within
|
||||||
! the 'contains' section of a module or program.
|
! the 'contains' section of a module or program.
|
||||||
|
|
||||||
elemental real function func4(a) result(res)
|
elemental real function func4(a) result(res)
|
||||||
! An elemental function is a Pure function that takes a scalar input variable
|
! An elemental function is a Pure function that takes a scalar input variable
|
||||||
! but can also be used on an array where it will be separately applied to all
|
! but can also be used on an array where it will be separately applied to all
|
||||||
! of the elements of an array and return a new array.
|
! of the elements of an array and return a new array.
|
||||||
real, intent(in) :: a
|
real, intent(in) :: a
|
||||||
res = a**2 + 1.0
|
res = a**2 + 1.0
|
||||||
@ -345,7 +345,7 @@ end function func4
|
|||||||
! Modules
|
! Modules
|
||||||
! =======
|
! =======
|
||||||
|
|
||||||
! A module is a useful way to collect related declarations, functions and
|
! A module is a useful way to collect related declarations, functions and
|
||||||
! subroutines together for reusability.
|
! subroutines together for reusability.
|
||||||
|
|
||||||
module fruit
|
module fruit
|
||||||
@ -358,7 +358,7 @@ end module fruit
|
|||||||
module fruity
|
module fruity
|
||||||
! Declarations must be in the order: modules, interfaces, variables.
|
! Declarations must be in the order: modules, interfaces, variables.
|
||||||
! (can declare modules and interfaces in programs too).
|
! (can declare modules and interfaces in programs too).
|
||||||
|
|
||||||
use fruit, only: apple, pear ! use apple and pear from fruit module.
|
use fruit, only: apple, pear ! use apple and pear from fruit module.
|
||||||
implicit none !comes after module imports.
|
implicit none !comes after module imports.
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ module fruity
|
|||||||
public :: apple,mycar,create_mycar
|
public :: apple,mycar,create_mycar
|
||||||
! Declare some variables/functions private to the module (redundant here).
|
! Declare some variables/functions private to the module (redundant here).
|
||||||
private :: func4
|
private :: func4
|
||||||
|
|
||||||
! Interfaces
|
! Interfaces
|
||||||
! ==========
|
! ==========
|
||||||
! Explicitly declare an external function/procedure within the module
|
! Explicitly declare an external function/procedure within the module
|
||||||
@ -377,14 +377,14 @@ module fruity
|
|||||||
real, intent(in) :: a
|
real, intent(in) :: a
|
||||||
end function func4
|
end function func4
|
||||||
end interface
|
end interface
|
||||||
|
|
||||||
! Overloaded functions can be defined using named interfaces.
|
! Overloaded functions can be defined using named interfaces.
|
||||||
interface myabs
|
interface myabs
|
||||||
! Can use 'module procedure' keyword to include functions already
|
! Can use 'module procedure' keyword to include functions already
|
||||||
! defined within the module.
|
! defined within the module.
|
||||||
module procedure real_abs, complex_abs
|
module procedure real_abs, complex_abs
|
||||||
end interface
|
end interface
|
||||||
|
|
||||||
! Derived Data Types
|
! Derived Data Types
|
||||||
! ==================
|
! ==================
|
||||||
! Can create custom structured data collections.
|
! Can create custom structured data collections.
|
||||||
@ -394,19 +394,19 @@ module fruity
|
|||||||
real :: dimensions(3) !i.e. length-width-height (metres).
|
real :: dimensions(3) !i.e. length-width-height (metres).
|
||||||
character :: colour
|
character :: colour
|
||||||
end type car
|
end type car
|
||||||
|
|
||||||
type(car) :: mycar !declare a variable of your custom type.
|
type(car) :: mycar !declare a variable of your custom type.
|
||||||
! See create_mycar() routine for usage.
|
! See create_mycar() routine for usage.
|
||||||
|
|
||||||
! Note: There are no executable statements in modules.
|
! Note: There are no executable statements in modules.
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
subroutine create_mycar(mycar)
|
subroutine create_mycar(mycar)
|
||||||
! Demonstrates usage of a derived data type.
|
! Demonstrates usage of a derived data type.
|
||||||
implicit none
|
implicit none
|
||||||
type(car),intent(out) :: mycar
|
type(car),intent(out) :: mycar
|
||||||
|
|
||||||
! Access type elements using '%' operator.
|
! Access type elements using '%' operator.
|
||||||
mycar%model = "Ford Prefect"
|
mycar%model = "Ford Prefect"
|
||||||
mycar%colour = 'r'
|
mycar%colour = 'r'
|
||||||
@ -414,7 +414,7 @@ contains
|
|||||||
mycar%dimensions(1) = 5.0 !default indexing starts from 1!
|
mycar%dimensions(1) = 5.0 !default indexing starts from 1!
|
||||||
mycar%dimensions(2) = 3.0
|
mycar%dimensions(2) = 3.0
|
||||||
mycar%dimensions(3) = 1.5
|
mycar%dimensions(3) = 1.5
|
||||||
|
|
||||||
end subroutine
|
end subroutine
|
||||||
|
|
||||||
real function real_abs(x)
|
real function real_abs(x)
|
||||||
@ -425,7 +425,7 @@ contains
|
|||||||
real_abs = x
|
real_abs = x
|
||||||
end if
|
end if
|
||||||
end function real_abs
|
end function real_abs
|
||||||
|
|
||||||
real function complex_abs(z)
|
real function complex_abs(z)
|
||||||
complex :: z
|
complex :: z
|
||||||
! long lines can be continued using the continuation character '&'
|
! long lines can be continued using the continuation character '&'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user