Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming Microcontrollers in C, 2-nd edit (Ted Van Sickle, 2001).pdf
Скачиваний:
296
Добавлен:
12.08.2013
Размер:
7.2 Mб
Скачать

12 Chapter 1 Introduction to C

be able to discard accesses to that value because the program never alters the value. In such a circumstance, if you had an analog-to-digital converter peripheral in your system, the program would never be re­ quired to read its return value more than once. “The program did not change the value stored in the input location subsequent to the first read, therefore its value has not changed and it is not necessary to read the location again.” This will always produce wrong results. The key word volatile indicates to the program that a variable must not be optimized. Therefore, if the input location is identified as a vola­ tile variable, it will not be optimized and the problem will go away. As a point of interest, accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all defined as side effects by the standard.

Storage Classes, Linkage, and Scope

Additional modifiers are called storage classes and designate where a variable is to be stored and how it is initialized. These stor­ age classes are auto (for automatic), static, and malloced. The first two storage classes are described in the following sections. The storage class malloc provides dynamic memory allocation and is discussed in detail in Chapter 2.

Automatic variables

For local variables defined within a function, the default storage class is auto. An automatic variable has the scope of the block in which it is defined, and it is uninitialized when it is created. Auto­ matic variables are usually stored on the program stack, so space for the variable is created when the function is entered. When the stack is cleaned up prior to the return at the end of the function, all vari­ ables stored on the stack are deleted.

As we saw in our first program example, variables can be initial­ ized at the time of declaration by assigning the variable an initial value:

int rupt=17;

An automatic variable will be assigned its initial value each time the block in which it is declared is entered. If the variable is not initialized at declaration, it will contain the contents of uninitialized memory, which can be any value.

Storage Classes, Linkage, and Scope

13

 

 

Another class of variable is register. A register class variable is automatic, i.e., it comes into being at the beginning of the block in which it is defined and it goes out of scope at the end of the block. If a register is available in the computer, a register variable will be stored in a register. To define a register variable, you should use the form

register int roger=10;

These variables can be long, short, int, or char.

When a register is not available, a register variable will be stored just like any other automatic variable. A programmer might consider the use of register variables in code that contains “tight loops” to save the time of memory accesses while executing the loop. A bit of advice. Compilers have improved continuously over the past years. With today’s compilers, the optimizers are so efficient that the compiler can probably do a better job of assigning register vari­ ables than the programmer. Therefore, it makes little sense to specify a lot of register variables just to improve the efficiency of your code.

Static variables

Sometimes you might want to assign a value to a variable and have it retain that value for later function calls. Such a variable can be created by calling it static at its definition. There are two groups of static variables: Local static variables which have a scope of the function in which they are defined, and global or external static class variables. Unless otherwise declared, all static class variables are initialized to 0 when they are created.

There are two groups of external static variables. Any exter­ nal variable is a static class variable. It is automatically initialized to the value 0 when the program is loaded unless the value is other­ wise declared in the definition statement. An external variable that is declared as static in its definition statement like

static int redoubt;

will have file scope. Remember normal external variables can be accessed from any module in the entire program. A static exter­ nal variable can be accessed only from within the file in which it is defined. Note that static variables are not stored on the stack, but rather stored in a static data memory area.

14 Chapter 1 Introduction to C

Inside of a function, the following declaration is made:

static int keep = 1;

When the program is loaded and executed, the value 1 is assigned to keep. Thereafter, each time the function is entered, keep will not be initialized but will retain the value assigned to it the last time the function was executed.

Global variables can be designated as static. A global vari­ able that is static is similar to a conventional global variable with the exception that it can be accessed only from the file in which it is declared.

If there is an external variable that is declared in one file that is to be accessed by a function defined in another file, the function must notify the compiler that the variable is external with the use of the keyword extern. The following is an example of such an access.

In file 1:

int able;

int main(void)

{

long quickstart(void); long r;

.

.

.

able=17;

l=quickstart();

.

.

}

In file 2:

long quickstart(void)

{

extern int able;

.

/* do something with able */

.

Character Constants

15

 

 

return result;

}

When the file 1 is compiled, the variable able is marked as external, and memory is allocated for its storage. When the file 2 is compiled, the variable able is recognized to be external because of the extern keyword, and no memory is allocated for the variable. When the link phase of the compilation is completed, all address references to able in file 2 will be assigned the address of able that was defined in file 1. The example above in which the declaration

extern int able;

allowed access to able from the file 2 will not work if able had been declared as follows in file 1:

static int able;

Character Constants

Character constants or escape sequences are data that can be stored in memory locations designated as char. A character constant is identified by a backslash preceding the character. We have seen the use of the character constants ‘\n’ and ‘\t’ in previous examples. Several of these escape sequences shown in the following table have predefined meanings.

Escape

Meaning

Sequence

 

\a

bell character

\b

backspace

\f

form feed

\n

new line

\r

carriage return

\v

vertical tab

\t

horizontal tab

\?

question mark

\\back slash

\’

single quote

\”

double quote

\ooo

octal number

\xxx

hexadecimal number

16 Chapter 1 Introduction to C

If these constants are used within a program, they must be identified by quotes. In the earlier example, the new line character was a part of a string. Therefore, it effectively was contained in quotes. If a single character constant is to be generated, the constant must be included in single quotes. For example, a test might include a statement like

if(c!=’\t’)

....

This statement causes the variable c to be compared with the constant ‘\t’, and the statement following the if will be executed if they are not the same. Another preprocessor command is #define. With the #define command, you can define a character sequence that will be placed in your code sequence whenever it is encountered. If you have character constants that you wish to use in your code, these constants can be identified as

#define CR ‘\x0d’ #define LF ‘\x0a’ #define BELL ‘\x07’ #define NULL ‘\x00’

and so forth.

We’ll discuss the #define preprocessor command further later. The following program shows use of an escape character.

/* Count lines of text in an input */

#include <stdio.h>

int main(void)

{

int c,nl=0; /* the number of lines is in nl */ while((c=getchar())!=EOF)

if(c==’\n’)

nl++;

printf(“The number of lines is %d\n”,nl); return 0;

}

Character Constants

17

 

 

Often you will want to leave “clues” as to what the program or line of code is supposed to do. Comments within the code provide this documentation. A C comment is delimited by

/* . . . . . . . */

and the comment can contain anything except another comment. In other words, comments may NOT be nested. The first line of code in the above program is a comment, and the sixth line contains both code and a comment. The compiler ignores all information inside the comment delimiters.

This program uses two integer variables c and nl. The variable c is the temporary storage location in which input data are stored, and nl is where the number of input lines are counted.

The while statement contains a rather complicated argument. At any point in a C program when a value is calculated, it can be stored in a specified location. For example, in the while expression

while((c=getchar()) != EOF)

the inner expression

c=getchar()

causes the function getchar() to be executed. The return from getchar() is a character from the input stream. This character is assigned to the variable c. After this operation is completed, the re­ sult returned from getchar() is compared with the constant EOF. EOF means end-of-file, and it is the value returned by getchar() when a program tries to read beyond the end of the data stream. It is defined in the file stdio.h. The symbol != is read “is not equal to.’’ Therefore, the argument of the while will be TRUE so long as getchar() does not return an EOF and the statement following the while will be continually executed until an EOF is returned.

Operators in an expression that have the higher precedence will be executed before the lower precedence operators. In the expression

c= getchar() != EOF

the operator != has a higher precedence than that of the = operator. Therefore, when this expression is evaluated, the logical portion of the expression will be evaluated first, and the result of the logical