Read Sams Teach Yourself C in 24 Hours Online
Authors: Tony. Zhang
}
The for statement first evaluates expression1, which is usually an expression that initializes one or more variables. The second expression, expression2, is the conditional part that is evaluated and tested by the for statement for each iteration. If expression2
evaluates to a nonzero value, the statements within the braces, such as statement1 and statement2, are executed. If expression2 evaluates to 0 (zero), the looping is stopped
24
and the execution of the for statement is finished. The third expression in the for statement, expression3, is evaluated after each looping before the statement goes back to test expression2 again. This third expression is often used to increment an index variable.
The following for statement makes an infinite loop because all three expressions are empty:
for ( ; ; ){
/* statement block */
}
The general form of the while statement is
while (expression) {
statement1;
statement2;
.
.
.
}
Here expression is the conditional expression in the while statement. The expression is evaluated first. If it evaluates to a nonzero value, the looping continues; that is, the statements inside the statement block, such as statement1 and statement2, are executed.
After the execution, the expression is evaluated again. Then the statements are executed one more time if the expression still evaluates to a nonzero value. The process is repeated over and over until the expression evaluates to zero.
30 067231861x CH24 1/25/00 10:48 AM Page 428
428
Hour 24
You can also make a while loop infinite by putting 1 (one) in the expression field like this:
while (1) {
/* statement block */
}
The general form for the do-while statement is
do {
statement1;
statement2;
.
.
.
} while (expression);
Here expression is the conditional expression that is evaluated in order to determine whether the statements inside the statement block are executed one more time. If the expression evaluates to a nonzero value, the do-while loop continues; otherwise, the looping stops. Note that the do-while statement ends with a semicolon, which is an important distinction. The statements controlled by the do-while statement are guaranteed to execute at least once before the conditional expression is evaluated.
Conditional Branching
The if, if-else, switch, break, continue, and goto statements fall into the conditional branching category.
The general form of the if statement is
if (expression) {
statement1;
statement2;
.
.
.
}
Here expression is the conditional expression. If expression evaluates to nonzero, the statements inside the braces ({ and }), such as statement1 and statement2, are executed. If expression evaluates to 0, the statements are skipped.
As an expansion of the if statement, the if-else statement has the following form: if (expression) {
statement1;
statement2;
.
.
.
30 067231861x CH24 1/25/00 10:48 AM Page 429
Where Do You Go From Here?
429
}
else {
statement_A;
statement_B;
.
.
.
}
Here if expression evaluates to nonzero, the statements controlled by if, including statement1 and statement2, are executed. Otherwise, the statements, such as statement_A and statement_B, inside the statement block following the else keyword are executed.
The general form of the switch statement is
switch (expression) {
24
case expression1:
statement1;
case expression2:
statement2;
.
.
.
default:
statement-default;
}
Here the conditional expression, expression, is evaluated first. If the value produced by expression is equal to the constant expression expression1, execution begins at the statement statement1. If the value of expression is the same as the value of expression2, execution then begins at statement2. If, however, the value of expression is not equal to any values of the constant expressions labeled by the case keyword, the statement statement-default, following the default keyword, is executed.
You can add a break statement at the end of the statement list following each case label if you want to exit the switch construct after the statements within a selected case have been executed.
The break statement can also be used to break out of an infinite loop.
There are times when you want to stay in a loop but skip over some of the statements within the loop. To do this, you can use the continue statement.
The following gives the general form of the goto statement:
label-name:
statement1;
statement2;
30 067231861x CH24 1/25/00 10:48 AM Page 430
430
Hour 24
.
.
.
goto label-name;
Here label-name is a label name that tells the goto statement where to jump. You have to place label-name in two places: at the place where the goto statement is going to jump and at the place following the goto keyword. Also, the place for the goto statement to jump to can appear either before or after the statement. Note that a colon (:) must follow the label name at the place where the goto statement will jump to. The use of goto is not recommended, however, because it makes your program hard to debug.
Pointers
A
pointer
is a variable whose value is used to point to another variable. The general form of a pointer declaration is
data-type
*pointer-name;
Here data-type specifies the type of data to which the pointer points. pointer-name is the name of the pointer variable, which can be any valid variable name in C. When the compiler sees the asterisk (*) prefixed to the variable name in the declaration, it makes a note that the variable can be used as a pointer.
Usually, the address associated with a variable name is called the
left value
of the variable. When a variable is assigned with a value, the value is stored into the reserved memory location of the variable as the content. The content is also called the
right value
of the variable.
A pointer is said to be a
null pointer
when it has been assigned the right value of 0.
Remember that a null pointer can never point to valid data, so you can use it to test for the validity of a pointer.
The dereference operator (*) is a unary operator that requires only one operand. For instance, the *ptr_name expression produces the value pointed to by the pointer variable ptr_name, where ptr_name can be any valid variable name in C.
The & operator is called the
address-of operator
because it can return the address (that is, left value) of a variable.
Several pointers can point to the same location of a variable in memory. In C, you can move the position of a pointer by adding or subtracting integers to or from the pointer.
Note that for pointers of different data types, the integers added to or subtracted from the pointers have different scalar sizes.
30 067231861x CH24 1/25/00 10:48 AM Page 431
Where Do You Go From Here?
431
Pointing to Objects
You can access an element in an array by using a pointer. For instance, given an array, an_array, and a pointer, ptr_array, if an_array and ptr_array are of the same data type, and ptr_array is assigned with the start address of the array like this: ptr_array = an_array;
the expression
an_array[n]
is equivalent to the expression
*(ptr_array + n)
Here n is a subscript number in the array.
24
In many cases, it’s useful to declare an array of pointers and access the contents pointed to by the array through dereferencing each pointer. For instance, the following declaration declares an int array of pointers:
int *ptr_int[3];
In other words, the variable ptr_int is a three-element array of pointers with the int type.
Also, you can define a pointer of struct and refer to an item in the structure via the pointer. For example, given the following structure declaration:
struct computer {
float cost;
int year;
int cpu_speed;
char cpu_type[16];
};
a pointer can be defined like this:
struct computer *ptr_s;
Then, the items in the structure can be accessed by dereferencing the pointer. For instance, to assign the value of 1997 to the int variable year in the computer structure, you can use the following assignment statement:
(*ptr_s).year = 1997;
Or, you can use the arrow operator (->) for the assignment, like this: ptr_s->year = 1997;
30 067231861x CH24 1/25/00 10:48 AM Page 432
432
Hour 24
Note that the arrow operator (->) is commonly used to reference a structure member with a pointer.
Functions
Functions
are the building blocks of C programs. Besides the standard C library functions, you can also use other functions made by you or by another programmer in your C
program. The opening brace ({) signifies the start of a function body, while the closing brace (}) marks the end of the function body.
According to the ANSI standard, the
declaration
of a variable or function specifies the interpretation and attributes of a set of identifiers. The
definition
, on the other hand, requires the C compiler to reserve storage for a variable or function named by an identifier.
In fact, a variable declaration is a definition. But the same is not true for functions. A
function declaration
alludes to a function that is defined elsewhere, and specifies what kind of value is returned by the function. A
function definition
defines what the function does, as well as the number and type of arguments passed to the function.
The ANSI standard allows the number and types of arguments passed to a function to be added into the function declaration. The number and types of arguments are called the
function prototype
.
The general form of a function declaration, including its prototype, is as follows: data_type_specifier
function_name(
data_type_specifier argument_name1,
data_type_specifier argument_name2,
data_type_specifier argument_name3,
.
.
.
data_type_specifier argument_nameN,
);
Here data_type_specifier determines the type of the value returned by the function or specifies the data types of arguments, such as argument_name1, argument_name2, argument_name3, and argument_nameN, passed to the function named function_name.
The purpose of using a function prototype is to help the compiler to check whether the data types of arguments passed to a function match what the function expects. The compiler issues an error message if the data types do not match. The void data type is needed in the declaration of a function that takes no argument.
30 067231861x CH24 1/25/00 10:48 AM Page 433
Where Do You Go From Here?
433
To declare a function that takes a variable number of arguments, you have to specify at least the first argument and use the ellipsis (...) to represent the rest of the arguments passed to the function.
A function call is an expression that can be used as a single statement or within other expressions or statements.
It’s often more efficient to pass the address of an argument, instead of its copy, to a function so that the function can access and manipulate the original value of the argument.
Therefore, it’s a good idea to pass the name of a pointer, which points to an array, as an argument to a function, instead of the array elements themselves.
You can also call a function via a pointer that holds the address of the function.
Input and Output (I/O)
24
In C, a
file
refers to a disk file, a terminal, a printer, or a tape drive. In other words, a file represents a concrete device with which you want to exchange information. A
stream
, on the other hand, is a series of bytes through which you read or write data to a file. Unlike a file, a stream is device independent. All streams have the same behavior.
In addition, there are three file streams that are pre-opened for you:
• stdin—The standard input for reading.
• stdout—The standard output for writing.
• stderr—The standard error for writing error messages.
Usually, the standard input stdin links to the keyboard, while the standard output stdout and the standard error stderr point to the screen. Also, many operating systems allow you to redirect these file streams.
By default, all I/O streams are buffered. Buffered I/O is also called
high-level I/O
.
The FILE structure is the file control structure defined in the header file stdio.h. A pointer of type FILE is called a
file pointer
and references a disk file. A file pointer is used by a stream to conduct the operation of the I/O functions. For instance, the following defines a file pointer called fptr:
FILE *fptr;
In the FILE structure, there is a member, called the
file position indicator
, which points to the position in a file where data will be read from or written to.
The C language provides a rich set of library functions to perform I/O operations. Those functions can read or write any types of data to files. Among them, fopen(), fclose(), fgetc(), fputc(), fgets(), fputs(), fread(), fwrite(), feof(), fscanf(), 30 067231861x CH24 1/25/00 10:48 AM Page 434
434
Hour 24
fprintf(), fseek(), ftell(), rewind(), and freopen() have been introduced in this book.
The C Preprocessor