- •1 Introduction to C
- •1.1 Some Simple Programs
- •1.2 Names
- •1.3 Types and Type Declarations
- •1.4 Storage Classes, Linkage, and Scope
- •1.5 Character Constants
- •1.6 Arrays
- •1.7 Other types
- •1.8 Operators and Expressions
- •1.9 Increment and Decrement Operators
- •1.10 Precedence and Associativity
- •1.11 Program Flow and Control
- •1.12 Functions
- •1.13 Recursion
- •1.14 Summary
- •2 Advanced C Topics
- •2.1 Pointers
- •2.2 Multidimensional Arrays
- •2.3 Structures
- •2.4 More Structures
- •2.5 Input and Output
- •2.6 Memory Management
- •2.7 Miscellaneous Functions
- •2.8 Summary
- •3 What Are Microcontrollers?
- •3.1 Microcontroller Memory
- •3.3 Programming Microcontrollers
- •3.4 Coding Tips for Microcontrollers
- •4.1 Microcontroller Memory
- •4.2 Timers
- •4.4 Pulse Width Modulator System
- •4.5 Other Program Items
- •4.6 Summary
- •5.1 Header File
- •5.2 Sorting Programs
- •5.3 Data Compression
- •5.4 Timer Operations
- •5.5 Summary
- •6 Large Microcontrollers
- •6.3 A Pulse Width Modulation Program
- •6.4 Cosmic MC68HC16 Compiler
- •6.6 Digital Signal Processor Operations
- •6.7 Other MC68HC16 Considerations
- •7.1 Numeric Encoding
- •7.2 Numeric Decoding
- •7.3 Coding the alpha data
- •7.4 The Monitor Program
- •7.5 The SAVEIT() Routine
- •7.6 The printout() and the printafter() Functions
- •7.7 Reset
- •7.9 Putting It All Together
- •7.10 Summary
- •8 MCORE, a RISC Machine
- •8.1 Delay Routine
- •8.2 Delays Revisited
- •8.4 Handling Interrupts
- •8.5 A Clock Program
- •8.6 Keyboard
- •8.7 Integrating Keyboard and Clock
- •8.8 Adding a Display
- •8.9 Summary
18 Chapter 1 Introduction to C
evaluation—either TRUE or FALSE—will be assigned to the vari able c. This result is of course incorrect. To avoid this problem, use
(c = getchar()) != EOF
as the while argument. In this case, the parentheses group the c=getchar() expression and it will be completed prior to execu tion of the comparison. The variable c will have the correct value as returned from the input stream. If the above expression is logically true, then the value that was returned from the input stream is tested to determine if it is a new line character. If a new line character is found, the counter nl is incremented. Otherwise, the next character is read in and the sequence repeated until an EOF is returned from the getchar(). Whenever an assignment is executed inside of another expression, always enclose the complete assignment expres sion in parentheses.
The final statement in the program
printf(“The number of lines is %d\n”,nl);
prints out the number of new line characters detected in reading the input file.
Arrays
An array is a collection of like types of data that are stored in consecutive memory locations. An array is designated at declaration time by appending a pair of square brackets to the array name. If the size of the array is to be determined at the declaration, the square brackets can contain the number of elements in the array. Following are proper array declarations.
extern int a[]; long rd[100];
float temperatures[1000];
char st[]={“Make a character array”};
float pressure[]={ 1.1, 2.3, 3.9, 3.7, 2.5, 1.5, 0.4};
As you can see, the size of an array must be designated in some manner before you can use empty square brackets in the designation. In the first case above, the array a[] is defined in global memory, so all that is necessary for the compiler to know is that a[] is an array.
Arrays 19
The argument of an array is sometimes called its index. It is a num ber that selects a specific entry into an array. Array arguments start with zero always. Therefore, when an array of 100 elements is cre ated, these elements are accessed by using the arguments 0 to 99. The standard requires that the first element beyond the end of the array be accessible as an array entry. Attempts to access elements beyond that will give undefined results.
Arrays can be initialized at declaration. The initialization values must be enclosed in braces, and if there are several individual nu merical values, these values must be separated by commas. In the case of a string initialization, it is necessary to include the string in quotes and also enclose the string along with its quotation marks within the braces. In both of these cases, the size of the array is calculated at compile time, and it is unnecessary for the programmer to figure the size of the array.
A string is a special case of an array. Whenever a string is gener ated in C, an array of characters is created. The length of the array is one greater than the length of the string. The individual characters from the string are placed in the array entries. To be a proper C string, the array’s last character must be a zero or a null. All strings in C are null terminated. If you as a programmer create a string in your program, you must append a null on the end of the character array to be guaranteed that C will treat the array as a string.
If the programmer should specify an array size and then initial ize a portion of the array like
int time[6]={1,5,3,4};
the compiler will initialize the first four members of the array with the specified values and initialize the remainder of the array with zero values. This approach allows you to initialize any array with all zero values by
long ziggy[100]={0};
which will fill all of the elements of the array ziggy[] with zeros. C provides you with no array boundary checking. It is the programmer’s responsibility to guarantee that array arguments do
not violate the boundaries of the array.
20 Chapter 1 Introduction to C
Other types
There are mechanisms for creating other types in C. The three other types are enum, union, and struct. It is often quite conve nient to make use of the data types to accomplish things that are difficult with the normal types available. We will see how to use these types in this section.
The enum
The name enum is used in C in a manner similar to the #de fine preprocessor command. The enum statement
enum state { OUT, IN};
produces the same result as
#define OUT 0 #define IN 1
Here, the name state is called the tag name. In this case OUT will be given a value of 0 and IN a value 1. In the enum{} form, unless specifically assigned, the members will be given successively increas ing values and the first will be given a value 0. Values can be assigned by an enum{};
enum months {Jan =1,Feb, Mar, April, May, June, July, Aug, Sept, Oct, Nov, Dec};
will cause Jan to be 1, Feb 2, and so forth up to Dec which will be 12. Each member can be assigned a different value, but whenever the programmer assignments stop, the values assigned to the variables following will be successively increased. These values are, by de fault, of the int type. The name months in the above expression is called a tag name. An enum creates a new type and you might have several enums in your code that you would wish to create as in stances. The key word enum with its tag name identifies the specific enum when it is used as a type identifier in a definition statement.
Another example
enum (FALSE,TRUE,Sun=1,Mon, Tues,Wed,Thur,Fri,Sat);
Other Types |
21 |
|
|
will result in FALSE being 0, TRUE 1, Sun 1, Mon 2, and so forth to Sat 7. Note that it is not necessary to assign a tag name to an enum.
An enum is typed at declaration time. Therefore, the values cre ated by an enum are indeed numerical values. This differs from the #define because the statement
#define FALSE 0
will cause the character ‘0’ to be inserted into the source code when ever the label FALSE is encountered. As such, the #define construct is a character substitution technique or a macro expansion. The re sult of an enum is a numerical substitution. The #define construct, being a simple character substitution, has no typing attached to its arguments. Constants created by an enum are typed, and therefore, will avoid many of the potential hazards of dealing with untyped variables.
Let us examine how one might use a type created with an enum construct. The following enum defines two constants
enum direction {LEFT,RIGHT};
In a program, a definition statement
enum direction d;
will cause a variable d to be created. The acceptable values for d are the names LEFT and RIGHT. We know, of course, that the numerical value for LEFT is 0 and the value for RIGHT. Within your program, you can assign and test the value of d. For example,
if(d==LEFT)
do something
or
if(d==RIGHT)
do something else
or
d = RIGHT;
As stated earlier, the acceptable values for d are LEFT and RIGHT. There is no checking within the program to see if the programmer
22 Chapter 1 Introduction to C
has indeed kept the trust. Therefore, it is possible to assign any inte ger value to d, and the program will compile. It probably will not work correctly, however.
The Union
The union was invented when memory was very dear. The main purpose of the union was to allow the storing of several variables at a single memory location. A union has a tag name much the same as the enum above.
union several
{
long biggie; int middle_size;
char little,another_char; short little_bigger;
};
The union several contains several members. These members are not necessarily of the same type and there can be multiple in stances of the same type. To create an instance of such a union, you need a definition statement. This statement can be external or imme diately following the opening of a code block, and hence local. Such a statement might be
union several these;
This definition causes a union several named these to be cre ated with memory allocated. To access the members of the union, you can use the dot operator as
these.biggie = something;
or
another = these.another_char;
An interesting feature of a union. If you should check the size of a union, you would find that it is the size of the largest of its members. Whenever you access, either read or write, a union, the proper size data is written or read, and it overwrites any other data that might be found in the memory location. Therefore, you can use a union for storage of only one of its members at a time and writing
Other Types |
23 |
|
|
anything to the union destroys any data previously stored to the union.
The struct
Yet another type is the struct. The struct is a collection of things much like the array. In the case of the struct, there are two major differences. A struct can contain different types, and the struct itself is a first class type. An array must be a collection of like types, and an array is NOT a type, so the type-like things you can do with a struct are not available for an array.
You create a struct in much the same form as was seen with a union. You may use a tag name.
struct able
{
char a,b; int c,d;
};
This struct is made up of two characters and two integers. If you wish to define an instance of the struct, you should use
struct able here:
Access the members of the struct with the dot operator like
here.a = ‘a’; here.b = 16; here.c = 32000; here.d = -16500;
We will see more of struct in Chapter 2 where you will learn how to make use of the new types created by struct.
EXERCISES
1.Write a program that reads all of the characters from an input file and prints the characters on the screen. Use the getchar() func tion used earlier to read the inputs and the putchar(c) to print the results to the screen.
2.Modify the above program to count the number of characters in an input stream.
