Файл: Programming Microcontrollers in C, 2-nd edit (Ted Van Sickle, 2001).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 15.06.2025

Просмотров: 4040

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

38 Chapter 1 Introduction to C

guess = (i + (10000/i))/2;

}

This calculation is known as a Newton loop. It states that if i is a guess at the square root of 10000, then (i+(10000/i))/2 is a better guess. The loop will continue to execute until i is exactly equal to guess. At this time the compound statement will be skipped.

When the statement following the while is skipped, program control is passed to the statement

printf(“The square root of 10000 is %d\n”,guess);

This statement prints out the value of the last guess, which will be the square root of 10000.

The For Loop

Many times, a sequence of code like

statement1;

while(statement2)

{

.

.

.

statement3;

}

will be found. This exact sequence was seen in the above example. There is a shorthand version of this sequence that can be used. It is as follows:

for(statement1;statement2;statement3)

The for construct takes three arguments, each separated by semi­ colons. In operation, the for construct is compiled exactly the same as the above sequence. In other words, statement1 is executed followed by a standard while with statement2 as its argument. The compound statement that follows will have statement3 placed at its end, so that statement3 is executed just prior to completion of the statement following the while construct. The for construct can be used to write the above program in the following manner:

#include <stdio.h>

Program Flow and Control

39

int main(void)

{

int guess,i;

for(i=1,guess=5;i!=guess;)

{

i=guess;

guess=(i+(10000/i))/2;

}

printf(“The square root of 10000 = %d\n”,guess);

return 0;

}

Recall that the for allows three arguments. Not all arguments are necessary for proper execution of the for. In this case, only two arguments are included. The first argument is really two initializa­ tion arguments separated by a comma operator. When the comma operator is used, the statements separated by commas are each evalu­ ated until the semicolon is found. At this time, the initialization is terminated. By the way, the comma operator can be used in normal code sequences so that you can string several statements in a row without separating them with semicolons. The second argument of the for construct is i != guess. The for loop will execute so long as this expression is TRUE. Note that there is no third statement in the for invocation.

This argument is where you would normally place the change in i that is to take place at the end of each loop. In this case, the opera­ tion on i is i=guess. If this expression were used for the third argument, at the end of the first loop, the second argument would be FALSE, and execution of the calculation would be prematurely ter­ minated.

The Do/While Construct

Another looping structure is the do/while loop. Recall that the argument of a while statement is tested prior to executing the state­ ment following. If the argument of the while is FALSE to begin with, the statement following will never be executed. Sometimes, it is


40 Chapter 1 Introduction to C

desired to execute the statement at least once whether the argument is TRUE or not. In such a case, the argument should be tested at the end of the loop rather than at the beginning as with the while. The do/ while construct accomplishes this operation. The construction of a do-while loop is as follows

.

.

do

{

.

.

.

} while (expression);

.

The program will enter the do construct and execute the code that follows up to the while statement. At that time, the expression is evaluated. If it is TRUE, program control is returned to the statement following the do. Otherwise, if the expression evaluates to FALSE, control will pass to the statement following the while. Notice that there is a semicolon following the while(expression). This semi­ colon is necessary for correct operation of the do-while loop.

The following function converts the integer number n into the corresponding ASCII string. The function has two parts: the first part converts the number into an ASCII string, but the result is back­ ward in the array; the second part reverses the data in the array so that the result is correct.

/* convert a positive integer to an ASCII string; valid for positive numbers only */

void itoa(unsigned int n, char s[])

{

int i=0,j=0,temp;

/* convert the number to ASCII */

do

{

Program Flow and Control

41

s[i++] = ‘0’ + n % 10;

n/=10;

}while ( n != 0);

s[i]=0; /* make the array a string */

/* but it is backwards in the array — reverse t*/

i—–; /* don’t swap the NULL */ while( i > j)

{

temp = s[j]; s[j++] = s[i]; s[i--] = temp;

}

}

The function uses three integer variables. The variables i and j are both initialized to zero, and the variable temp does not need to be initialized. The first portion of the program contains a do-while loop. Within this loop, the number is converted into a string. The statement

s[i++] = ‘0’ + n % 10;

first calculates the value of the integer modulo 10. This value is the number of 1s in the number. Adding that value to the character ‘0’ will create the character that corresponds to the number of 1s. This value is stored in the location s[i] with i=0 and then i is incremented.

The second statement in the loop replaces n with n divided by 10. This code removes any 1s that were in the number originally, and now the original 10s are in the 1s position. Since this division is an integer division, if the result is between 0 and 1 it will be rounded to 0. Therefore, the test in the while argument allows the above two statements to repeat until the original number n is exhausted by re­ peated divisions by 10.

When the do-while loop is completed, s[i] will be the charac­ ter immediately following the string of characters. A string is created by placing a 0 or a null in this location of the array.


42 Chapter 1 Introduction to C

To reverse the data, the program starts by decrementing i so that s[i], the last entry in the array, is the most significant character in the number, and it must be placed in the first array location s[0]: . Likewise, the character in s[0] must be placed in s[i]: and so forth. The while loop that follows accomplishes this requirement.

EXERCISES

1.Write a program atoi(s[]) that starts with a character string and converts this string to an int. Assume that the string contains no sign.

2.Write a program that reads a text file one character at a time and counts the number of words in the file.

The If/Else Statement

The if/else statement has the general form

if(expression)

statement1; else

statement2;

If the logical evaluation of the expression that is the argument of the if is TRUE, statement1 will be executed. After statement1 is executed, program control will pass to the statement following statement2, and statement2 will not be executed. If the evalu­ ation of statement is FALSE, statement2 will be executed, and statement1 will be skipped. The else statement is not neces­ sary. If there is no else statement, the expression is evaluated. If it is TRUE, statement1 will be executed. Otherwise, statement1 will be skipped. The following program demonstrates the use of the if/else flow control method.

/* count number of digits and other characters in input */

#include <stdio.h>

int main(void)

Program Flow and Control

43

{

int c,nn,no; no=0;

nn=0;

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

if(c>=’0'&&c<=’9')

nn++;

else no++;

printf(“Digits=%d and other characters=%d\n”,nn,no); return 0;

}

The statement

int c,nn,no;

declares the three variables c, nn, and no to be integers. You may declare as many variables as you wish with a single declaration state­ ment. The next statements

no=0;

nn=0;

initialize the values of no and nn to 0. Variables declared with the above sequence of instructions are automatic variables. These vari­ ables are not initialized by the compiler, and the programmer must initialize them to a required value. Otherwise the variables will con­ tain garbage.

The code sequence

while((c = getchar()) !=EOF) if(c>=’0' && c<=’9')

nn++;

else

no++;

comprise the while and its following statement. The if portion of the statement tests the value of c and determines if it is a digit. A character constant is identified as a specific value by placing the char­ acter value in single quotes. Therefore, the expression c>=’0' determines if the character in the location c is greater than or equal


44 Chapter 1 Introduction to C

to the character 0. If it is, the result of this expression is TRUE. Oth­ erwise, the result is FALSE. The expression c<=’9' determines if the input character is less than or equal to the character 9. If both of these logical expressions are TRUE, then the AND of the two will be TRUE, and the statement nn++ will be executed to count the num­ bers found in the input stream. Program control will then skip to the end of the if statement and continue to execute the while loop. If, on the other hand, either of these expressions is FALSE, then the AND of the two results will be FALSE and the statement no++ will be executed. This statement keeps count of the number of characters that are not digits found in the input stream.

At the conclusion of the program, the getchar() will return an EOF character and the program will fall out of the while loop. It will then execute the following statement:

printf(“Digits=%d and other characters=%d\n”,nn,no);

The string contained within the double quotes in this argument causes a combination of text plus calculated values of variables to be printed out. Suppose that the program found 51 numbers and 488 other char­ acters. The printout from the program would then be:

Digits=51 and other characters=488

Each %d is associated with its corresponding argument and converted to a numerical value before it is sent to the screen.

The If-Else If Statement

Sometimes it is necessary to select among several alternatives. One of the methods that C offers is the if-else if sequence. Examine the following program that counts the number of occur­ rences of each vowel in an input. The program also counts all other characters found in the input.

/* Count the number of occurrences of each vowel found in an input and also count all other charac­ ters. */

#include <stdio.h>

int main(void)

Program Flow and Control

45

{

int na=0,ne=0,ni=0,no=0,nu=0; int nother=0,c;

while ((c=getchar())!=EOF) if(c==’A’ || c==’a’)

na=na+1;

else if(c==’E’ || c==’e’) ne=ne+1;

else if(c==’I’ || c==’i’) ni=ni+1;

else if(c==’O’ || c==’o’) no=no+1;

else if(c==’U’ || c==’u’) nu=nu+1;

else nother=nother+1;

printf( “As=%d, Es=%d, Is=%d, Os=%d, Us=%d and” “ Others=%d\n”,na,ne,ni,no,nu,nother);

return 0;

}

This program shows several new features of C. The first is found in the program lines

int na=0,ne=0,ni=0,no=0,nu=0; int nother=0,c;

When the variables na and so forth are defined, they are assigned initial values of 0. Such an initialization is always possible when variables are defined. The next statement of the program is

while ((c=getchar())!=EOF) if(c==’A’ || c==’a’)

na=na+1;

else if(c==’E’ || c==’e’) ne=ne+1;

else if(c==’I’ || c==’i’) ni=ni+1;

else if(c==’O’ || c==’o’) no=no+1;

else if(c==’U’ || c==’u’)


46 Chapter 1 Introduction to C

nu=nu+1; else

nother=nother+1;

This single statement has quite a few lines of code associated with it, and there are some new concepts here. First, the arguments of the ifs are combinations of two logical expressions. The expression

c==’A’ || c==’a’

says that if c is equal to uppercase a OR if c is equal to lowercase a the argument is TRUE. The vertical bars || are the logical opera­ tor OR.

The first if statement is evaluated. If its argument is TRUE, the statement following the if is executed and program control moves to the end of the if statements. Otherwise, the first else if state­ ment argument is evaluated. If this argument is TRUE, the following statement is executed and program control moves to the end of the if statements. This process is repeated until one of the arguments is found to be TRUE, or all of the else if statements are evaluated. At that time, the final statement following the else entry is evalu­ ated. The final else is not required.

In the above statement, please note that the while statement itself and all that follows it form a single statement to the compiler. Likewise, the combination of all of the if-if else constructs also form a single statement. Furthermore, each of the statements following either an if or an if else form single statements. The formatting of this statement helps you understand what is going on, but remember, the format of such a statement is completely up to the programmer. The language is completely free format. The while statement above and its statement following is indeed confusing to observe, and probably the one thing that the programmer can do to reduce the confusion is to block the statements following both the while and the if and else key words. In this case the while statement would look like

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

{

if(c==’A’ || c==’a’*

{

Program Flow and Control

47

na=na+1;

}

else if(c==’E’ || c==’e’)

{

ne=ne+1;

}

else if(c==’I’ || c==’i’)

{

ni=ni+1;

}

else if(c==’O’ || c==’o’)

{

no=no+1;

}

else if(c==’U’ || c==’u’)

{

nu=nu+1;

}

else

{

nother=nother+1;

}

}

This block of source code is longer than the original form, but it is exactly the same to the compiler. This code is indeed longer than the original form, but it is also much less open to misinterpretation and misunderstanding. Writing code that cannot be misinterpreted is as much the responsibility of the programmer as writing code that works. Therefore, when writing production code, you should seri­ ously aim to generate code that is not open to any misinterpretation, even though it will make your source code somewhat longer. Usu­ ally when you write code that is easy to maintain, it will not affect the size of your object code.

The printf function call

printf(“As=%d, Es=%d, Is=%d, Os=%d, Us=%d and” “ Others=%d\n”,na,ne,ni,no,nu,nother);