Variable Definitions and Declarations

Variable definitions were introduced in the section called “The Basics of Variable Definitions”. We will now examine them in greater detail. A variable definition allocates memory to store a value, and assigns the memory location a name and a data type. The compiler uses the data type to determine which machine instructions to use to process the data. For example, adding two integers is done with a different machine instruction than adding two floating point values. The integer add instruction is faster, so defining a variable as int rather than double will lead to a faster program.

A C variable definition consists of a data type followed by one or more variable names separated by commas, and ultimately a semicolon:

type name [, name ...]; 
        
double height, width, area; 
        

A Fortran 90 variable definition consists of a type, followed by two colons, followed by a list of variable names separated by commas:

type :: name [, name ...]
        
real(8) :: height, width, area 
        

Variable names must begin with a letter or an underscore, and may contain letters, underscores, and digits after that.

The words definition and declaration are often used interchangeably in programming. In the context of languages such as C and C++, definition and declaration have different meanings. A definition in C allocates memory, whereas a declaration merely alludes to a variable or function defined elsewhere. For example, all C programs contain a global variable called errno, which contains the error code from the most recent standard library function. We can declare it in a given function by using the extern modifier to tell the compiler that this variable is defined somewhere else and we want to access it from here:

    extern int  errno;  // Declare (allude to), not define, errno
        

Without the extern modifier, we would be defining a new local variable called errno rather than alluding to the one already defined globally. The local variable would take precedence over the preexisting global variable under the variable scope rules of C, which means it would be impossible to access the global variable where the local variable is defined.

Note that while we can declare errno using an allusion as shown above, the modern method is to include errno.h, which contains this allusion:

#include <errno.h>
        
Initializers

Both C and Fortran support assigning an initial value to a variable in the definition.

double sum = 0.0;
            
real(8) :: sum = 0.0d0
            

Using this feature reduces the length of a program slightly by eliminating an assignment statement further down. Some would argue that it is less cohesive, however. It is generally a good practice to group related statements together in one cohesive block. In this context, it would mean initializing variables immediately before the code that depends on that initial value. This way, we can see that the variable is initialized properly without having to scroll up or search through the source code. This will save time and distractions while debugging.

double  sum;

// Suppose there are 100 lines of additional code here

// A cohesive block of code
sum = 0.0;
for (c = 0; c < list_size; ++c)
    sum += value;
            
double  sum = 0.0;

// Suppose there are 100 lines of additional code here

// This is not cohesive since the initialization of sum is far away from
// the loop that requires it
for (c = 0; c < list_size; ++c)
    sum += value;
            
Memory Maps

Memory locations for variables are generally allocated together in a block. Suppose we have the following variable definitions:

double  height, width, area;
int     list_size, age; 
            

or

real(8) :: height, width, area
integer :: list_size, age 
            

The program will have 8 bytes (64 bits) of memory allocated for each double or real(8) variable, and 4 bytes (32 bits) for each integer variable. A possible map of the memory space, assuming the block begins at memory address 4000, is shown in Table 17.3, “Memory Map”. Recall that each memory location contains 1 byte (8 bits), so each of these variables will occupy multiple memory addresses.

Table 17.3. Memory Map

AddressVariable
4000 to 4007height
4008 to 4015width
4016 to 4023area
4024 to 4027list_size
4028 to 4031age

Practice

Note

Be sure to thoroughly review the instructions in Section 2, “Practice Problem Instructions” before doing the practice problems below.
  1. What does a variable definition do?

  2. What are the rules for naming variables?

  3. What does a variable declaration do?

  4. State one argument for and one against using initializers in a variable definition.
  5. Draw a possible memory map for the following variable definitions:
    int     age, year;
    float   gpa;