We begin today with an examination of US Coins program being done this week in lab.
We had had a chance now to examine a complete program written in C – in fact, we have seen complete programs in the book and in the notes on the web.
We need have to take a more structured look at the instructions (lines of code) in these programs to understand how they work.
First – we have to understand an important principle.
Lots of names (identifiers) appear in the programs we
have seen. There are two types of these identifiers: reserved
words, and user-defined identifiers. Reserved words have a special meaning as defined by
the C language and you should try to never use them for any other
purpose. Principle: User-defined identifiers, on the other
hand, must be declared in one way or another, before they used. Otherwise, the compiler will give you an
error.
As it turns out, some identifiers are defined for us as part of the C Standard Library components. We will find it very helpful to use and reuse these components whenever
possible.
Let’s see how this might be done.
A. Compiler directives - general
1. Compiler directives are handled by the C pre-processor as it makes its first pass through your program file.
2. The resulting pre-processed file is then compiled in the second pass by the C compiler to generate the object file which is in the machine language code
B.
The #include directive
How #include works:
Include the contents of another file, commonly called a header file, in your file
The line of code where the #include compiler directive occurs is replaced by the contents of the header file
Example 1: If the contents of a header file named myinclude.h were:
/* This is an empty include file with nothing but comments */
/* There is no meaningful code in this file */
and the program file contained the following lines of code:
#include "myinclude.h"
int
main ()
{
printf ("This is a 1 line program\n");
}
the pre-processing step would produce the following lines code:
/* This
is an empty include file with nothing but comments */
/*
There is no meaningful code in this file */
int
main ()
{
printf ("This is a 1 line
program\n");
}
Example 2:
#include
<stdio.h>
(The angle brackets < > tell the C pre-processor that the included file is a C Standard Library header file (sometimes called a “system” file.)
What other kind of library header file
is there?
The standard input/output library file, stdio.h, contains the declarations (definitions) of all the standard names needed to do input and output in our programs. It must be included, for example, to use the printf and scanf Standard Input / Output functions
Note 1: The C Standard Library (the header and implementation files) come with the C compiler software. There are 18 such libraries, including stdio, and library files for string manipulation functions, math functions, character manipulation functions, etc.
Note 2: You don't have to know where system header files are located the C pre-processor knows where to find them
Example 3: #include "myheader.h"
Include the source code for header file myheader.h
Double quotes, "", tell the C pre-processor that the included
file is a user-defined header file as opposed to a C Standard Library header
file.
-- User defined header files are header files that you create
-- If the user defined header file is not located in the same directory where you compile the program then the information inside the double quotes must contain the path information for the user defined header file, the C pre-processor does not know where to find user defined header files
myheader.h may define information specific to your program
-- This assumes that the file myheader.h is located in the same directory where the program is compiled
C. The #define
directive
How #define works:
Defines a macro constant (or, naming a macro constant) - the defined macro constant name is automatically replaced by the macro constant value throughout the program file
Example 1:
#define KMS_PER_MILE 1.609
Substitute the macro constant name KMS_PER_MILE with the macro
constant value 1.609 throughout the program file
We would write the C line of code
kms
= miles * KMS_PER_MILE;
After the C pre-processor step, this line would look like this:
kms = miles * 1.609;
How comments work:
§ Comments are statements that clarify the meaning and content of your program file
§ Comments are a means of documenting your program code so that people can better understand how the program is works
§ Comments are removed by the C pre-processor before the resulting program code is compiled so the C Compiler does not see them but they can be read by humans looking at the contents of your program file
§ Comments start with /* and end with */
EVERYTHING between /* and */ is removed by the C pre-processor
Example 1:
/* This is a single comment */
Example 2:
/*
* This is also a single comment
*/
Note 1: Be VERY careful to terminate your comments correctly or you may get surprising results!
Example 3: The comment on the first line (below) is not terminated which results in the C pre-processor removing the #include and #define statements that follow it. It is as though these lines were never in the program to begin with.
/* Include the standard input and output header file
#include <stdio.h>
#define KMS_PER_MILE 1.609 /* Kilometer conversion factor */
int
main
()
{
...
This kind of error is very hard to find, by the way – just like a lot of other errors.
Why
isn’t the additional code (int, main, etc) also “swallowed up by the
pre-processor?
Example 4: The comment on the first line (below) is terminated which results in the C pre-processor processing the #include and #define statements:
/*
Include the standard input and output header file */
#include <stdio.h>
#define KMS_PER_MILE 1.609 /* Kilometer conversion factor
*/
int
main
()
{
...
§ Declaring a variable reserves enough bytes in RAM memory to store value of the declared type.
A data type is a set of values and a set of operations on those values.
The values and operations “go together.” You can think of them as a unit that looks like this:
The int type …
output
(print)
operations such as
mod % (remainder)

§ Some of the intrinsic or predefined types (those included or supported in the C language) are char for character values, int for integer values and float or double for real values.
§ The objects of a data type can be variables or constants. You can get a brief introduction to data types in the Hanly/Koffman text, Section 2.2, pp 42-44. We will cover more about them later (in Chapter 7).
§ Note that there is no string data type. There is also no logical or bool data type. We will have more to say about this later.
Type Bytes Reserved Declared variables can store
------ ------------------- --------------------------------------------
char 1 byte of RAM Characters such as 'A', '-', 'z', etc.
int 4 bytes of RAM Integer numbers such as 1, 3, 100, etc.
double 8 bytes of RAM Real numbers such as 1.5, 0.75, 100.10, etc.
§ The appropriate type of value can be written to or read from the reserved memory by referring to the associated variable name
Example 1: Declare the variable miles that can store a real number
double miles;
8 bytes of memory that can store real values are now reserved in RAM and are associated with the variable name miles
We can assign a value to the variable miles
miles
= 1.5;
The 8 bytes of reserved memory associated with the variable name miles now contain a series of 0's and 1's that represent the real value 1.5
Example 2: Read a value from the variable miles
scanf (%f, &miles);
printf ("The value of
miles is %f\n", miles);
The series of 0's and 1's that are contained in the 8 bytes of reserved memory associated with the variable name miles is read as the real value 1.5 and printed to the screen:
The value of miles is 1.5
Example 3: Declare the variables kids and courses that can store integer numbers
int
kids, courses;
4 bytes of memory that can store integer values are now reserved in RAM and are associated with the variable name kids
4 bytes of memory that can store integer values are now reserved in RAM and are associated with the variable name courses
Example 4: Declare the variable initial that can store characters
char initial;
1 byte of memory that can store a character value is now reserved in RAM and is associated with the variable name initial.
As we mentioned earlier, all C programs are written as a collection of functions, including the “main” function. There are two kinds of functions: user-written functions such as main, and C Standard Library (CSL) functions. All remaining information in this section pertains to CSL functions for input (scanf) and output (printf).
1. printf - Output text to the user
Form: printf
(format string);
§ The format string is enclosed by double quotes "" and may contain any literal text, placeholders (or format specifiers) and format control characters such as the \n which means "new line"
§ Literal text is interpreted literally by the compiler and does not cause the program to perform any action
§ Format control characters are interpreted as a format control action by the compiler
1) The compiler will generate an instruction in the program to
take the appropriate format control action
2) The program will perform an action such as moving the cursor
to the beginning of the next line
3) Format control characters are not displayed on the screen but
instead cause some format control action to occur
Example 1: \n causes the program to move the cursor to the start of the next line, the program does NOT actually print the characters \n on the screen
Example 2: The line
printf ("Move the cursor to the next line\n");
displays the following output on the screen:
Move the cursor to the next line
_
Example 3: The line
printf ("Enter distance in miles> ");
would display the text:
Enter the distance in miles>
on the screen leaving the cursor at the end of the line
Form: printf
(format string, output list);
§ The output list consists of a list of variables or values that will replace the corresponding format specifiers or placeholders in the format string. The format specifiers or placeholders all begin with the symbol %
§ The variable(s) and value(s) correspond positionally to the format specifiers in the format string
§ The first variable or value in the output list replaces the first format specifier in the format string, the second variable or value in the output list replaces the second format specifier in the format string, etc.
Example 1: The line
printf
("int: %d double: %f char: %c\n", 1, 1.0, 'A');
would display the text:
int:
1 double: 1.0 char: A
on the screen and move the cursor to the start of the next line
The value 1 would replace the %d format specifier, the value 1.0 would replace the %f format specifier and the value A would replace the %c format specifier in the format string
Example 2: The lines
double miles;
miles
= 10.0;
printf ("The distance in miles is
%f\n", miles);
would display the text:
The
distance in miles is 10.0
on the screen and put the cursor at the beginning of the next line.
The value of the variable miles would replace the %f format specifier in the format string. There must be as many variable(s) and value(s) in the output
list as there are format specifiers in the format string.
2. Formatting output
§ Format specifiers can have modifiers to control the total number of columns and decimal places displayed
§ Format modifiers have the form field_width.decimal_places where field_width is the total number of columns displayed and decimal_places is the number of decimal places displayed for real numbers
The decimal point itself counts as 1 in determining the total field width
Example 1: The line
printf ("%6.2", 4.9653);
will display the value 4.9653 in 6 columns with 2 decimal
places and 1 decimal point as ##4.97 for a total of 6 columns
Note that real values are rounded to the number of decimal places specified
Other Examples: Sample output using format modifiers
printf ("%.2f",
4.9653);
will display 4.9653 rounded to 2 decimal places as 4.97
printf ("%.1f",
4.9653);
will display 4.9653 rounded to 1 decimal place as 5.0
printf ("%6d", 25);
will display 25 in 6 columns as ####25
printf ("%6.1f",
25.0);
will display 25.0 in 6 columns with 1 decimal place and the
decimal point as ##25.0
3. scanf - Input text from the user
Form: scanf
(format string, input list);
The
input list consists of a list of variables that will get values of the type
that correspond positionally to the format specifiers in the format string.
The first variable in the input list gets a value of the
type specified by the first format specifier in the format string, the second
variable in the input list gets a value of the type specified by the second
format specifier in the format string, etc.
Example 1: Consider the input lines
double miles;
printf ("Enter the
number of miles> ");
scanf ("%lf",
&miles);
The value input by the user is interpreted as a real number because of the %lf format specifier and stored in the "address of" or "location of" the variable miles
Example 2: The lines
int integer_value;
double double_value;
printf ("Enter an integer value and a double value> ");
scanf ("%d %lf", &integer_value, &double_value);
would
get two numeric values from the user, the first numeric value would be stored as an integer value in the
location in memory associated with the variable integer_value, the second numeric value would be stored as a real
value in the location in memory associated with the variable double_value.
The
first value input by the user is interpreted as an integer number because of
the %d format specifier and stored in the "address of" or
"location of" the variable
integer_value, the second value input by the user is interpreted as a real number because of the %lf format specifier and stored in the "address of" or "location of"
the variable double_value.
There
must be as many variable(s) and value(s) in the output list as there are format
specifiers in the format string
Example 3: Reading multiple data items with the same scanf function call
-- For each data item to be read in there must be a format specifier and a corresponding variable address or location in memory to store the input value
-- The first value read in is interpreted based upon the first format specifier in the format string and stored in memory cell specified by first variable in the input list. The second value read in is interpreted based upon the second format specifier in the format string and stored in the location in memory of the second variable in the input list, etc.
Consider the following lines of code:
printf ("Enter hours and rate >");
scanf ("%lf%lf", &hours, &rate);
The first value read in is interpreted as a real number and stored in the location in memory of the variable hours, the second value read in is interpreted as a real number and stored in the location in memory of the variable rate.
NOTE: The values that are entered (read or scanned in) must be separated by at least one space between them.
Example 4: The lines
char
first, second;
printf ("Enter your
two initials >");
scanf ("%c%c",
&first, &second);
would
require that you enter two characters one after the other, with at least one
space between them..
Example 5: The lines
printf ("Enter your two initials >");
scanf (" %c %c", &first, &second);
would require that there be at least one blank space between the characters.
4. Important notes and reminders on previous material …
a. Literal text consists of any characters or strings of characters that are NOT themselves format control characters or are preceded by format control characters.
b. Literal text in a printf function call is interpreted as the actual text contained in the format string which is not interpreted in any special way by the compiler.
c. Format control characters (starting with a backslash \) are interpreted action characters and cause the program to perform an action such as moving the cursor to the start of the next line or moving the cursor to a new tab position.
\n - Move the cursor to the beginning of a new line
\t - Move the cursor 1 tab position in the current line
d. Format specifiers consist of a combination of characters that begin with the % character followed by lf, f, d or c. These combinations of characters may be thought of as placeholders for the value of a variable or constant of the specified type in the format string:
%lf - Placeholder for a long double value in the format string
%f - Placeholder for a double value in the format string
%d - Placeholder for an integer value in the format string
%c - Placeholder for a character value in the format string
~~~~~~~~ The material below will be moved to another lecture set ~~~~~~~~~~
a) Programs can read input from files and write output to files in addition
to reading input from the keyboard and writing output to the screen
1) Files must be opened using the fopen function before they can be read
from or written to
2) There are special versions of the printf and scanf functions used to
read input from files and write output to files
The file input and output function names are similar to the input
and output functions described above in Section 4, "Calls to the
input and output library functions", but begin with the letter "f"
fprintf - print information to a file (output)
fscanf - read information from a file (input)
3) Files must be closed using the fclose function in order to save any
changes to the file
1. fopen - Open a file for reading or writing
Form: fopen (file name, mode);
a) The file name and mode are both enclosed by double quotes ""
b) File names may be any valid file name that can exist under the
operating system and can include path information:
"myfile.dat"
"/users/home/input.txt"
"c:output.txt"
"../program.inp"
If the path information is not specified then the file location is
assumed to be the directory where the program was run from which
is known as the working directory
c) Modes can be "r", "w" or "a"
1) "r" - Open the named file for reading only from the beginning
of the file, the named file must exist in order to be
opened successfully, the contents of the file can not
be changed
2) "w" - Open the named file for writing from the beginning of
the file, the named file will be created if it doesn't
exist, if it does exist then the original contents of
the file will be overwritten regardless of whether any
file operations are performed or not
3) "a" - Open the named file for writing from the end of the file,
the named file will be created if it doesn't exist, if
it does exist then the original contents of the file will
not be changed, all write operations are "appended" to
the end of the file
2) fopen will return a FILE pointer to the named file if the file was
opened successfully otherwise fopen will return an empty or NULL
pointer to indicate the file was not opened successfully:
/* Declare the file pointer file_ptr */
FILE *file_ptr;
/* Open the file name "myfile.inp" in the current directory */
/* for reading only and assign the pointer associated with */
/* the file to file_ptr */
file_ptr = fopen ("myfile.inp", "r");
If the file is NOT opened successfully then the file pointer will
be empty or NULL and you can NOT use the file pointer in calls to
fprintf, fscanf or fclose or the program will abort!
2. fclose - Close a file to save any changes to the file
Form: fclose (file pointer);
The file pointer must NOT be empty or NULL and must have been
assigned using a call to fopen as described in Section 5b, "fopen
- Open a file for reading or writing" above!
2) fclose will close the file associated with the file pointer and save any changes to the file
/* Declare the file pointer file_ptr */
FILE *file_ptr;
/* Open the file name "myfile.out" in the current directory */
/* for writing and assign the pointer associated with the */
/* file to file_ptr */
file_ptr = fopen ("myfile.out", "w");
/* Print the statement "File is open" to the file associated */
/* with file_ptr */
fprintf (file_ptr, "File is open\n");
/* Close the file associated with file_ptr */
fclose (file_ptr);
Note that you can NOT use the file pointer once the file has been
closed or the program will abort because the file pointer is no
longer associated with an open file!
3. fprintf - Output text to a file
Form:
fprintf works the same way as printf in terms of the format string and optional
output list as described in Section 4a, "printf - Output text to the
user" above
2) Calls to fprintf MUST also include a file pointer associated with
the file where the output will be written to as the first argument:
fprintf (file pointer, format string);
fprintf (file pointer, format string, output list);
Note that the file pointer used in the call to fprintf must have
been assigned using a call to fopen as described in Section 5b,
"fopen - Open a file for reading or writing" above!
/* Declare an integer variable for input from the user */
int integer_value;
/* Declare the file pointer file_ptr to associate with the file */
FILE *file_ptr;
/* Open the file name "myfile.out" in the current directory */
/* for writing and assign the pointer associated with the */
/* file to file_ptr */
file_ptr = fopen ("myfile.out", "w");
/* Get an integer value from the user and store the value in */
/* the variable integer_value */
printf ("Enter an integer value > ");
scanf ("%d", &integer_value);
/* Print the value entered by the user to the file associated */
/* with file_ptr */
fprintf (file_ptr, "The user entered the value %d\n", integer_value);
/* Close the file associated with file_ptr */
fclose (file_ptr);
4. fscanf - Input text from a file
Form: fscanf works the same way as scanf in terms of the format string and input list as described in Section 4b, "scanf - Input text from the user" above
2) Calls to fscanf MUST also include a file pointer associated with
the file where the input will be read from as the first argument:
fscanf (file pointer, format string, input list);
Note that the file pointer used in the call to fscanf must have
been assigned using a call to fopen as described in Section 5b,
"fopen - Open a file for reading or writing" above!
/* Declare an integer variable for input from the file */
int integer_value;
/* Declare the file pointer file_ptr to associate with the file */
FILE *file_ptr;
/* Open the file name "myfile.inp" in the current directory */
/* for reading and assign the pointer associated with the */
/* file to file_ptr */
file_ptr = fopen ("myfile.inp", "r");
/* Read an integer value from the file associated with file_ptr */
fscanf (file_ptr, "%d", &integer_value);
/* Print the value read from the file to the screen */
printf ("The value read from the file is %d\n", integer_value);
/* Close the file associated with file_ptr */
fclose (file_ptr);
5. Standard File Pointers
1) C provides 3 Standard File Pointers that are automatically opened
when the program starts
a) stdin - "Standard Input" associated with the keyboard
b) stdout - "Standard Output" associated with the screen
c) stderr - "Standard Error" associated wiht the screen
The keyboard and screen are actually considered "files" that are read
from and written to in the same way that a file on disk is
stdin, stdout and stderr are NOT the names of files that are created
on the disk but rather they are file pointers that are associated
with the keyboard and screen which are I/O devices in the same way
that a file on disk is considered an I/O device
2) The Standard File Pointers are constant and can NOT be changed by
the program
3) fprintf and fscanf can be used with the Standard File Pointers so
that they behave identically to printf and scanf
a) printf is a special console version of fprintf that automatically
writes to the stdout file pointer which is the screen
/* The following two statements are equivalent! */
printf ( "Display a message on the screen\n");
fprintf (stdout, "Display a message on the screen\n");
printf writes information to the screen automatically
fprintf writes information to the screen when used with the stdout
file pointer which is associated with the screen!
b) scanf is a special console version of fscanf that automatically
reads from the stdin file pointer which is the keyboard
/* Declare an integer variable to get input from the keyboard */
int integer_value;
/* The following two statements are equivalent! */
scanf ( "%d", &integer_value);
fscanf (stdin, "%d", &integer_value);
scanf reads information from the keyboard automatically
fscanf reads information from the keyboard when used with the
stdin file pointer which is associated with the keyboard!