Variables

Yutaka Masuda

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.

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.

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 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

Exercises

  1. 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.
  2. Create a program to read a value in Fahrenheit from the keyboard, convert it to Centigrade, and print the result.
  3. Define two integer variables with some initial values, swap the values, and print the values.
  4. 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.