Constants

Literal Constants

Like variables, C and Fortran constants also have types, which are determined by how the constant is written. For example, constants containing a decimal point are floating point values. Whether they are single or double precision is determined by an optional suffix.

Table 17.4, “C Constants and Types” and Table 17.6, “Fortran 90 Constants and Types” illustrate the types that compilers assign to various constants.

Table 17.4. C Constants and Types

ConstantType
45int
45uunsigned int
45llong
45ulunsigned long
45lllong long
45ullunsigned long long
45.0double
4.5e1double
45ffloat
45.0llong double
(45.0, 0.0)double complex
'A'int (not char!)
"45"const char * (array of char)

Integer constants that begin with '0' are interpreted as octal values, so 045 is equivalent to 4 * 8 + 5, or 37. Constants beginning with '0x' are interpreted as hexadecimal, so 0x45 = 4 * 16 + 5 = 69.

Note that a character between single quotes in C is not a string constant, but a character constant. It represents the ISO code of that character, and its type is int, not char. For example, in C, 'A' is exactly the same as 65, '0' is the same as 48, and '!' is the same as 33.

Note

In C++, the type of a character constant is char. This is one of very few places where C++ is not backward-compatible with C.

There are also special sequences known as escape sequences to represent non-graphic characters. The most common ones are listed in Table 17.5, “C Escape Sequences”.

Table 17.5. C Escape Sequences

SequenceISO code (decimal)Description
'\n'10Newline / Line feed
'\r'13Carriage return
'\0'0Null byte
'\t'9Tab

Table 17.6. Fortran 90 Constants and Types

ConstantType
45integer
45_8integer(8)
45.0real
4.5e1 = 4.5 * 10^1 = 45.0real
4.5d1 = 4.5 * 10^1 = 45.0real(8) (double precision)
45.0d0 = 4.5 * 10^0 = 4.5real(8) (double precision)
(45.0, 0.0)complex
(45.0d0, 0.0d0)complex(8) (double complex)
'45'character(2) (string of length 2)
.true.logical

Named Constants

Virtually every constant in your program should be assigned a name. Using names for constants makes the code much easier to read and allows the program to be more easily modified.

In C, we can define constants using the #define preprocessor directive, or using a variable definition with the const modifier. When using the const modifier, we must provide an initializer. Any attempts by a program statement to alter the value will result in a compiler error.

#define PI 3.1415926535897832
            
const double PI = 3.1415926535897832;
            

When using #define, the preprocessor simply replaces the name (PI) with the value (3.1415926535897832) wherever it is used as an identifier in the program. In the printf statement below, only the second instance of PI is replaced by the preprocessor. The PI embedded in the string is not replaced.

printf("The value of PI is ", PI);
            

In Fortran 90, constants are defined like variables, but with the parameter modifier, which informs the compiler that the variable is read-only. Any attempts by a statement to alter its value will result in a compiler error.

real(8), parameter :: PI = 3.1415926535897832d0 
            

A constant without a name is known as a hard-coded constant. Using named constants such as PI and MAX_RADIUS throughout the program instead of hard-coded constants such as 3.1415926535897832 and 10.0 has the following advantages:

  • It allows the compiler to catch typos. If we mistype PI or MAX_RADIUS, the compiler will complain about an undefined variable or constant name. If we mistype 10.5 as 1.05, the program will compile just fine, but produce incorrect output. This is the hardest type of bug to find, and could have disastrous results if it goes undetected. Bugs like this have been known to cause catastrophic failures in cars, planes, spacecraft, and consumer products, leading to heavy financial losses, injury, and even death.
  • If the names of the constants are descriptive (as they should be), the reader has an easier time understanding the code. This reduces the need for comments. It will likely take a bit of effort to figure out what a hard-coded constant actually means in a given context, whereas a good name makes it obvious.
  • If you need to change the value of a constant (not an issue for PI, but quite possible for MAX_RADIUS), then having a named constant means you only need to make one change to the program. If you have the hard-coded constant 10.5 sprinkled all of the program, you'll have to carefully hunt them all down and change them. You can't simply change every instance of 10.5, since some of them might have a different purpose, and coincidentally have the same value as the maximum radius.

Example of bad C code:

#include <stdio.h>
#include <sysexits.h>

int     main(int argc,char *argv[])

{
    // Bad idea: Using hard-coded constants
    printf("Area = %f\n", 3.1415926535897932 * 2.0 * 2.0);
    return EX_OK;
}

Example of better C code:

#include <stdio.h>
#include <math.h>       // Use M_PI provided with standard libraries
#include <sysexits.h>

#define RADIUS  10.0

int     main(int argc,char *argv[])

{
    printf("Area = %f\n", M_PI * RADIUS * RADIUS);
    return EX_OK;
}

Example of bad Fortran code:

program circle_area
    use iso_fortran_env
    
    ! Bad idea: Using hard-coded constants
    print *, 'Area = ', 3.1415926535897932d0 * 2.0 * 2.0
end program

Example of better Fortran code:

module constants
    ! Define only constants in modules, not variables! (i.e. use 'parameter')
    real(8), parameter :: &
        PI = 3.1415926535897932d0, &
        RADIUS = 10.0d0
end module constants

program circle_area
    use iso_fortran_env
    use constants           ! Constants defined above
    
    print *, 'Area = ', PI * RADIUS * RADIUS
end program

Practice

Note

Be sure to thoroughly review the instructions in Section 2, “Practice Problem Instructions” before doing the practice problems below.
  1. What is the data type of each of the following C constants?

    • 16

    • 16.0

    • 'x'

    • "x"

  2. What is the data type of each of the following Fortran constants?

    • 16

    • 16.0

    • 'x'

  3. Show how to write the constant 32 so that it has each of the following data types:

    1. C: int, float, unsigned long, long long, double, float complex

    2. Fortran: integer, real(4), real(8), complex, integer(2)

  4. Show how to define a constant names AVOGADRO with the value 6.02 * 10^23, using:

    1. The C preprocessor.

    2. A C const definition.

    3. A Fortran constant definition.

  5. Why should we almost always used named constants instead of hard-coded constants?

  6. What are some potential long-term consequences of using hard-coded constants?