                       C DATA TYPES & VARIABLES

                            Matthew Probert
                           Servile  Software


There are four basic types of data in the C language; character, integer, 
floating point, and valueless that are referred to by the C key words; 
"char", "int", "float" and "void" respectively. 

To the basic data types may be added the type modifiers; signed, unsigned, 
long and short to produce further data types. By default data types are 
assumed signed, and the signed modifier is rarely used, unless to overide a 
compiler switch defaulting a data type to unsigned. 

The size of each data type varies from one hardware platform to another, but 
the least range of values that can be held is described in the ANSI standard 
as follows; 


TYPE                SIZE        Range

char                8           -127 to 127
unsigned char       8           0 to 255
int                 16          -32767 to 32767
unsigned int        16          0 to 65535
long int            32          -2147483647 to 2147483647
unsigned long int   32          0 to 4294967295
float               32          Six digit precision
double              64          Ten digit precision
long double         80          Ten digit precision


In practice, this means that the data type 'char' is particularly suitable 
for storing flag type variables, such as status codes, which have a limited 
range of values. The 'int' data type can be used, but if the range of values 
does not exceed 127 (or 255 for an unsigned char), then each declared 
variable would be wasting storage space. 

Which real number data type to use: 'float', 'double' or 'long double' is 
another tricky question. When numeric accuracy is required, for example in 
an accounting application, the instinct would be to use the 'long double', 
but this requires at least 10 bytes of storage space for each variable. And 
real numbers are not as precise as integers anyway, so perhaps one should 
use integer data types instead and work around the problem. The data type 
'float' is worse than useless since its six digit precision is too 
inaccurate to be relied upon. Generally, then, you should use integer data 
types where ever possible, but if real numbers are required use at least a 
'double'. 

Declaring a variable:

All variables in a C program must be declared before they can be used. The 
general form of a variable definition is; 

    type name;

So, for example to declare a variable "x", of data type "int" so that it may 
store a value in the range -32767 to 32767, you use the statement; 

    int x;

Character strings may be declared, which are in reality arrays of 
characters. They are declared as follows; 

    char name[number_of_elements];

So, to declare a string thirty characters long, and called 'name' you would 
use the declaration; 

    char name[30];


Arrays of other data types also may be declared in one, two or more 
dimensions in the same way. For example to declare a two dimensional array 
of integers; 

    int x[10][10];

The elements of this array are then accessed as;

    x[0][0]
    x[0][1]
    x[n][n]

There are three levels of access to variable; local, module and global. A 
variable declared within a code block is only known to the statements within 
that code block. A variable declared outside any function code blocks but 
prefixed with the storage modifier "static" is known only to the statements 
within that source module. A variable declared outside any functions and not 
prefixed with the static storage type modifier may be accessed by any 
statement within any source module of the program. 

For example;

int error;
static int a;

main()
{
    int x;
    int y;

}

funca()
{
    /* Test variable 'a' for equality with 0 */
    if (a == 0)
    {
        int b;
        for(b = 0; b < 20; b++)
            printf("\nHello World");
    }

}

In this example the variable 'error' is accessible by all source code 
modules compiled together to form the finished program. The variable 'a' is 
accessible by statements in both functions 'main()' and 'funca()', but is 
invisible to any other source module. Variables 'x' and 'y' are only 
accessible by statements within function 'main()'. The variable 'b' is only 
accessible by statements within the code block following the 'if' statement. 

If a second source module wished to access the variable 'error' it would 
need to declare 'error' as an 'extern' global variable thus; 

extern int error;

funcb()
{
}

C will quite happily allow you, the programmer, to assign different data 
types to each other. For example, you may declare a variable to be of type 
'char' in which case a single byte of data will be allocated to store the 
variable. To this variable you can attempt to allocate larger values, for 
example; 

main()
{


    x = 5000;

}

In this example the variable 'x' can only store a value between -127 and 
128, so the figure 5000 will NOT be assigned to the variable 'x'. Rather the 
value 136 will be assigned! 

Often you may wish to assign different data types to each other, and to 
prevent the compiler from warning you of a possible error you can use a cast 
to tell the compiler that you know what you're doing. A cast statement is a 
data type in parenthesis preceding a variable or expression; 

main()
{
    float x;
    int y;

    x = 100 / 25;

    y = (int)x;
}

In this example the (int) cast tells the compiler to convert the value of 
the floating point variable x to an integer before assigning it to the 
variable y. 



Formal parameters:

A C function may receive parameters from a calling function. These 
parameters are declared as variables within the parentheses of the function 
name, thus; 

int MULT(int x, int y)
{
    /* Return parameter x multiplied by parameter y */
    return(x * y);
}

main()
{
    int a;
    int b;
    int c;

    a = 5;
    b = 7;
    c = MULT(a,b);

    printf("%d multiplied by %d equals %d\n",a,b,c);
}


Access modifiers:

There are two access modifiers; 'const' and 'volatile'. A variable declared 
to be 'const' may not be changed by the program, whereas a variable declared 
as type  as type 'volatile' may be changed by the program. In addition, 
declaring a variable to be volatile prevents the C compiler from allocating 
the variable to a register, and reduces the optimization carried out on the 
variable. 

Storage class types:

C provides four storage types; 'extern', 'static', 'auto' and 'register'.

The extern storage type is used to allow a source module within a C program 
to access a variable declared in another source module. 

Static variables are only accessible within the code block that declared 
them, and additionally if the variable is local, rather than global, they 
retain their old value between subsequent calls to the code block. 

Register variables are stored within CPU registers where ever possible, 
providing the fastest possible access to their values. 

The auto type variable is only used with local variables, and declares the 
variable to retain its value locally only. Since this is the default for 
local variables the auto storage type is very rarely used. 



