Variables
February 2020
Back to index.html.
Variables
Variable Basics
A variable is storage, which holds value in memory. Once you put a value to the variable, the program holds it until the program unit ends. You can update (rewrite) the variable with a new value. In Fortran, a variable has a couple of limitations compared with other casual languages.
- A variable should be declared before using it at the top of the program.
- A variable holds only a particular data-type.
The strictly-typed variable is helpful to write a strict program in numerical computing. First, we are looking at how to declare variables with a particular type.
Declaration of variables
Sample program
See the following example to find the usage of variables.
program var
implicit none
integer :: a,b
a = 10
b = 20
print *,a+b
end program var
30
The program declares two integer variable a
and b
, assigns values to the variables, and print the sum of the values. We can learn a lesson from this small example.
- A variable has a type.
- The variables should be declared at the beginning of a program unit.
- The statement
implicit none
tells the compiler that all variables will be declared. - You can define multiple variables separated with
,
in the same declaration. - A value is assigned to a variable using
=
. - The variables can be used as literals.
The variable can be re-used (updated) to hold another value.
program var
implicit none
integer :: a,b
a = 10
b = 20
print *,a+b ! 10 + 20
b = 35
print *,a+b ! 10 + 35
end program var
30
45
Note that, when a variable is declared, its value is undefined. Any variables are not automatically initialized with a particular value. It is your responsibility to assigns a value to the variable before using it.
Declaration
The general form of a variable declaration is as follows.
implicit none
variable_type :: variable1, variable2, ...
Using implicit none
, the compiler tells you if there are undeclared variables. The following variable types are available.
Type | Meaning |
---|---|
integer |
integer (default = 4byte, 32bit) |
real |
real, single precision |
real(8) |
real, double precision (see below) |
double precision |
real, double precision |
logical |
logical value |
character |
a character |
character(len=n) |
characters with the length \(n\) |
There are two ways to declare double-precision variables. The magic number 8
is corresponding a precision code, introduced in the previous chapter as real(r,kind=8)
. This 8
is the de facto standard but is may not be portable (that is, some compilers should fail or misinterpret it). For portable (safer) programs, you have to use selected_real_kind
, or use real64
in a built-in module iso_fortran_env
. See the following example.
! Four ways to declare double-precision variables.
program var
use iso_fortran_env ! the use statement comes the first
implicit none
real(8) :: variance
double precision :: sex_ratio
real(selected_real_kind(15,307)) :: average
real(real64) :: ebv
end program var
Naming rules
There are several rules in the variable names.
- The name should start with one of the alphabets.
- The name can contain alphabets, numbers, and
_
. No other characters are not allowed as the variable name. - The maximum length of the variable name is 63 in Fortran 2003 (31 in Fortran 90).
- The name is not case-sensitive.
The variable name is just a label. Even if you use lengthy variable names, the performance of the program never changes.
Assignment or update operator
A value is assigned to the variable using =
. This symbol does not mean the mathematical equivalence between the left-hand side and the right-hand side. It is an operator to update the variable with the new value like mathematically, \(x\leftarrow v\) where \(x\) is a variable, and \(v\) is a value.
The following example has the assignment for various variables.
program var
implicit none
real :: a
integer :: b
logical :: c
character :: d
character(len=10) :: e
a = 3.14
b = 12345
c = (10>=5)
d = "x"
e = "blup"
print *,a,b,c,d,e
end program var
3.14000010 12345 T xblup
There is a typical form to update a numerical variable. See the following code and predict what it is doing.
program var
implicit none
integer :: i
i = 1
print *,i
i = i + 1 ! updating the variable
print *,i
end program var
The statement i=i+1
does not make sense in mathematics, but it is updating i
with a new value. The symbol =
is interpreted as \(x \leftarrow v\) which evaluates the right-hand side (\(v\)) first, and then, rewrite \(x\) with this value. In this case, the program calculates i+1
, which is 2
, and assign this result to i
. In the end, this program print two numbers: 1 and 2.
Temporary variable
There are two ways to show the result of the computation. One is to save the result to a variable, and the other one is just to show the result.
program var
implicit none
integer :: x,y
x = 10
y = x+5
print *,y ! case 1: save the result to y and print it
print *,x+5 ! case 2: show the result without saving it
end program var
The latter case performs the same as the former case. Precisely, the program implicitly prepares a temporary variable and do assign the result (x+5
) to the variable behind the scene. However, you do not have to care about the difference in this case because you should not find any difference in computing time and resource usage. Please use your favorite style in such a simple case.
Read from the keyboard
The program can read a value from the keyboard and assign it to the variable. The following program reads a number from your keyboard and immediately prints it to the screen.
program var
implicit none
integer :: i
read *,i
print *,i
end program var
When running the program, it looks like freezing, but the program is just waiting for your key-in. You can type an integer number and hit the Enter key. The read
statement reads the input and converts it to the integer number. The last print
statement simply prints the value.
The input should be a valid literal in Fortran. For example, 123
is valid for an integer variable, and 3.14
and 6.02e23
are both valid as real. For a logical variable, T
(or t
) and F
(and f
) are valid. For a character variable, any non-space characters should be acceptable. The input may be rounded or truncated so that the variable can handle it. If the input is invalid, the program stops with an error.
It is always good to print a message before the read
statement so that a user understands how to do it.
program var
implicit none
integer :: i
print *,'Input an integer number:'
read *,i
print *,i
end program var
The form of read
is similar to print
; you can list the variables in the statement. The symbol *
means that you do not assume any specific format of the input characters (leaving to the computer). If the input is invalid or nonsense, the program stops with some error messages.
When the read
statement has multiple variables, the program keeps reading until all the variables have the values. The multiple values are separated with white spaces or the Enter key. Confirm the behavior by yourself (see the exercises).
As print
and write
, there is another style of the read
statement.
read(*,*) i
In this style, the statement has a form read(*,*)
as write(*,*)
, the first asterisk for a unit number (not in read *
), and the second for the format (as in read *
). This form is used in reading a file. You can use either read *
or read(*,*)
to read from the keyboard. I will use read *
in this tutorial for this purpose.
Character variable
The character variable looks like an array of characters, which will be introduced in the next chapter. Here, I introduce only a few features of character variables, and the details will be introduced in the later chapter.
See the following program.
program var
implicit none
character(len=12) :: name1,name2
name1 = "John Smith"
name2 = "Chris McDonald"
print *,name1,&,name2
end program var
John Smith &Chris McDona
The character variable must have a pre-defined length of characters. The program defines two character variables, and each should have only 12 characters. If the input is shorter than the defined length (10 for “John Smith”), the variable will be padded with spaces, i.e. "John Smith "
If the input characters are longer than the size of the variable, the input is truncated to meet the length of variable i.e., “Chris McDona”.
You can access a portion of the characters. The following example extracts from 3th to 7th characters from a variable.
program var
implicit none
character(len=12) :: name1
name1 = "John Smith"
print *,name1(3:7)
end program var
hn Sm
When you extract particular characters, you have to specify the range as (start index:end index)
just next to the variable name. When specifying only 1 character, you still specify two indices like (3:3)
for the 3rd character. If you write a single index like (3)
, the compiler stops with an error. Using this technique, you can replace a portion of the characters.
program var
implicit none
character(len=12) :: name1
name1 = "John Smith"
name1(6:10) = 'White'
print *,name1
end program var
John White
Summary
- The statement
implicit none
makes sure all the variables are declared. - A variable should be declared with a type.
- A variable can be used in statements and formulas as the literals.
- A value should be assigned to the variable manually.
- The variable names should contain alphabets, numbers, and the underscore but start with one of the alphabets. The name is not case-sensitive.
- The operator
=
updates the variable. First, the right-hand side is evaluated, and the result is assigned to the variable. - Using
read
, a value can be read from the keyboard and assigned to the variable. The input should be valid as a Fortran literal. - A character variable can hold a certain length of characters. A section of characters is available using
(start:end)
.
Exercises
- Read two real numbers from the keyboards and display their addition, subtraction, product, and division. See the behavior when multiple variables are specified in
read
. - Create a program to read a value in Fahrenheit from the keyboard, convert it to Centigrade, and print the result.
- Define two integer variables with some initial values, swap the values, and print the values.
- Print a variable before assigning a value to it.
Some details of variables
Dangerous feature: using variables without a declaration
Technically, you can use the variables without the declaration and implicit none
. However, this creates a massive problem in your program. See the following example with three variables.
program var
john = 1
kathy = 2
george = 3
print *,john,kathy,george
end program var
1 2 3.00000000
The program compiles without any errors, and it works. The variables john
and kathy
look like integer, but george
is a real variable. So, why? It is tough to explain this behavior without knowing details.
Without the declaration of variables, the type of variable is defined based on its name. If the variable name starts with one of i
, j
, k
, l
, m
, and n
, it becomes an integer variable, and otherwise, it becomes a real variable. The variables with the other types (logical and character) are not automatically defined. This feature is one of the negative legacies in FORTRAN 77, which supported the ancient standard established when the variable declaration was not considered crucial. This feature is extremely confusing, and you must not use it.
The compiler can detect undeclared variables by adding implicit none
just before the variable declaration. With this statement, the compiler should stop if it finds the undeclared variables. I strongly recommend that you always use this statement.
! This program can not compile because of any declarations.
program var
implicit none
john = 1
kathy = 2
george = 3
print *,john,kathy,george
end program var
Uninitialized variables
A variable has no initial value by default. Precisely, it surely has a value when it is created at the declaration statement, but this value is arbitrary. You must not assume the variable automatically has an initial value (like 0
). You must assign the initial value to the variable.
program var
implicit none
integer :: a
print *,a
a = 10
print *,a
end program var
-1475355915
10
The first output is from the uninitialized variable, and it is nonsense. This value is unstable; it may change every time you run the program. A friendly compiler has an option to detect uninitialized variables.
Not-a-number and infinity
The compiler may not detect an invalid value in a particular computation, such as \(0/0\). See the following examples.
program var
implicit none
real :: a
a = 0.0
print *,log(a)
print *,a/a
print *,1/a
end program var
-Infinity
NaN
Infinity
If the result is not defined (mostly \(0/0\)), the variable holds NaN
. If the result becomes the infinity, the variable has Infinity
. Such a value propagates the following computations if it is involved. The following program shows the same output as above.
program var
implicit none
real :: a,b
a = 0.0
b = 1.0
print *,log(a)+b
print *,a/a+b
print *,1/a+b
end program var
Variable initialization
You can assign a value to the variable in the declaration statement.
program var
implicit none
real :: a=0.0, b=1.0
print *,log(a)+b
print *,a/a+b
print *,1/a+b
end program var
Constants (parameters)
You can create a constant (called parameter in Fortran) in the same manner as a variable. The constant is the same as the variable except that it is never updated or rewritten. It is useful when you need a mathematical constant or a setting commonly referred to by the program. To make the variable constant, use the parameter
attribute to the declaration.
! dp and pi will be altered.
program var
implicit none
integer,parameter :: dp = selected_real_kind(15,307)
real(dp),parameter :: pi=3.1415926
print *,2*pi
end program var
In this example, the precision of the real variable (dp
) is defined as a constant. In this way, you can save key-typing in your program.
Exercises
No exercises are available in this section.
Back to index.html.