Файл: Programming Microcontrollers in C, 2-nd edit (Ted Van Sickle, 2001).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 4029
Скачиваний: 1
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
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.