📄 chapter 6 flow of control -- valvano.htm
字号:
Statement</FONT></I></B></P>
<P><FONT face="Times New Roman,Times">Switch statements provide a non-iterative
choice between any number of paths based on specified conditions. They compare
an expression to a set of constant values. Selected statements are then executed
depending on which value, if any, matches the expression. Switch statements have
the form </FONT></P>
<UL>
<P><CODE>switch ( ExpressionList ) { Statement?...}</CODE></P></UL>
<P><FONT face="Times New Roman,Times">where ExpressionList is a list of one or
more expressions. Statement?... represents the statements to be selected for
execution. They are selected by means of case and default prefixes--special
labels that are used only within switch statements. These prefixes locate points
to which control jumps depending on the value of ExpressionList. They are to the
switch statement what ordinary labels are to the goto statement. They may occur
only within the braces that delimit the body of a switch statement. </FONT></P>
<P><FONT face="Times New Roman,Times">The case prefix has the form </FONT></P>
<UL>
<P><CODE>case ConstantExpression : </CODE></P></UL>
<P><FONT face="Times New Roman,Times">and the default prefix has the form
</FONT></P>
<UL>
<P><CODE>default: </CODE></P></UL>
<P><FONT face="Times New Roman,Times">The terminating colons are required; they
heighten the analogy to ordinary statement labels. Any expression involving only
numeric and character constants and operators is valid in the case prefix.
</FONT></P>
<P><FONT face="Times New Roman,Times">After evaluating ExpressionList, a search
is made for the first matching case prefix. Control then goes directly to that
point and proceeds normally from there. Other case prefixes and the default
prefix have no effect once a case has been selected; control flows through them
just as though they were not even there. If no matching case is found, control
goes to the default prefix, if there is one. In the absence of a default prefix,
the entire compound statement is ignored and control resumes with whatever
follows the switch statement. Only one default prefix may be used with each
switch.</FONT></P>
<P><FONT face="Times New Roman,Times">If it is not desirable to have control
proceed from the selected prefix all the way to the end of the switch block,
break statements may be used to exit the block. Break statements have the form
</FONT></P>
<UL>
<P><CODE>break; </CODE></P></UL>
<P><FONT face="Times New Roman,Times">Some examples may help clarify these
ideas. Assume Port A is specified as an output, and bits 3,2,1,0 are connected
to a stepper motor. The switch statement will first read Port A and the data
with 0x0F </FONT><CODE>(PORTA&0x0F)</CODE><FONT
face="Times New Roman,Times">. If the result is 5, then PortA is set to 6 and
control is passed to the end of the switch (because of the break). Similarly for
the other 3 possibilities</FONT></P>
<P><CODE>#define PORTA *(unsigned char volatile *)(0x0000)</CODE><FONT
face="Times New Roman,Times"><BR></FONT><CODE>void step(void){ /* turn stepper
motor one step */ <BR> switch (PORTA&0x0F)
{<BR> case
0x05:<BR> PORTA=0x06; // 6
follows
5;<BR> break;<BR> case
0x06:<BR> PORTA=0x0A; // 10
follows
6;<BR> break;<BR> case
0x0A:<BR> PORTA=0x09; // 9
follows
10;<BR> break;<BR> case
0x09:<BR> PORTA=0x05; // 5
follows
9;<BR> break;<BR> default:
<BR> PORTA=0x05; // start
at 5 <BR> }<BR>}</CODE></P>
<ADDRESS><FONT face="Times New Roman,Times">Listing 6.3: Example of the switch
statement.</FONT></ADDRESS>
<P>For more information on stepper motors, see Chapter 8 of <U>Embedded
Microcomputer Systems: Real Time Interfacing</U> by Jonathan W. Valvano. </P>
<P><FONT face="Times New Roman,Times">This next example shows that the multiple
tests can be performed for the same condition.</FONT></P>
<P><CODE>// ASCII to decimal digit conversion<BR>unsigned char convert(unsigned
char letter){ unsigned char digit; <BR> switch (letter)
{<BR> case
'A':<BR> case
'B':<BR> case
'C':<BR> case
'D':<BR> case
'E':<BR> case
'F':<BR> digit=letter+10-'A';
<BR> break;<BR> case
'a':<BR> case
'b':<BR> case
'c':<BR> case
'd':<BR> case
'e':<BR> case
'f':<BR> digit=letter+10-'a';
<BR> break;<BR> default:
<BR>
digit=letter-'0';<BR> }<BR> return digit;
} </CODE></P>
<ADDRESS><FONT face="Times New Roman,Times">Listing 6.4: Example of the switch
statement.</FONT></ADDRESS>
<P><FONT face="Times New Roman,Times">The body of the switch is not a normal
compound statement since local declarations are not allowed in it or in
subordinate blocks. This restriction enforces the C rule that a block containing
declarations must be entered through its leading brace. </FONT></P>
<P><B><I><FONT face=Helvetica,Arial><A name=WHILE></A>The While
Statement</FONT></I></B></P>
<P><FONT face="Times New Roman,Times">The while statement is one of three
statements that determine the repeated execution of a controlled statement. This
statement alone is sufficient for all loop control needs. The other two merely
provide an improved syntax and an execute-first feature. While statements have
the form </FONT></P>
<UL>
<P><CODE>while ( ExpressionList ) Statement</CODE></P></UL>
<P><FONT face="Times New Roman,Times">where ExpressionList is a list of one or
more expressions and Statement is an simple or compound statement. If more than
one expression is given, the right-most expression yields the value to be
tested. First, ExpressionList is evaluated. If it yields true (non-zero), then
Statement is executed and ExpressionList is evaluated again. As long as it
yields true, Statement executes repeatedly. When it yields false, Statement is
skipped, and control continues with whatever follows. </FONT></P>
<P><FONT face="Times New Roman,Times">In the example </FONT></P>
<UL>
<P><CODE>i = 5;<BR>while (i) array[--i] = 0;</CODE></P></UL>
<P><FONT face="Times New Roman,Times">elements 0 through 4 of array[ ] are set
to zero. First i is set to 5. Then as long as it is not zero, the assignment
statement is executed. With each execution i is decremented before being used as
a subscript. </FONT></P>
<P><FONT face="Times New Roman,Times">It is common to use the while statement ti
implement gadfly loops </FONT></P>
<P><FONT face="Courier,Courier New" size=2>#define RDRF 0x20 // Receive Data
Register Full Bit<BR>// Wait for new serial port input, return ASCII code for
key typed<BR>char
InChar(void){<BR></FONT><CODE> </CODE><FONT
face="Courier,Courier New" size=2>while ((SC0SR1 & RDRF) ==
0){};<BR></FONT><CODE> </CODE><FONT
face="Courier,Courier New" size=2>return(SC0DRL);}<BR>#define TDRE 0x80 //
Transmit Data Register Empty Bit<BR>// Wait for buffer to be empty, output ASCII
to serial port<BR>void OutChar(char
data){<BR></FONT><CODE> </CODE><FONT
face="Courier,Courier New" size=2>while ((SC0SR1 & TDRE) ==
0){};<BR></FONT><CODE> </CODE><FONT
face="Courier,Courier New" size=2>SC0DRL =
data;<BR>}</FONT><CODE> </CODE></P>
<ADDRESS><FONT face="Times New Roman,Times">Listing 6.5: Examples of the while
statement.</FONT></ADDRESS>
<P><FONT face="Times New Roman,Times">For more information on serial ports, see
Chapter 7 of <U>Embedded Microcomputer Systems: Real Time Interfacing</U> by
Jonathan W. Valvano. </FONT></P>
<P><FONT face="Times New Roman,Times">Continue and break statements are handy
for use with the while statement (also helpful for the <A
href="http://www.ece.utexas.edu/~valvano/embed/chap6/chap6.htm#DO">do</A> and <A
href="http://www.ece.utexas.edu/~valvano/embed/chap6/chap6.htm#FOR">for</A>
loops). The continue statement has the form </FONT></P>
<UL>
<P><CODE>continue; </CODE></P></UL>
<P><FONT face="Times New Roman,Times">It causes control to jump directly back to
the top of the loop for the next evaluation of the controlling expression. If
loop controlling statements are nested, then continue affects only the innermost
surrounding statement. That is, the innermost loop statement containing the
continue is the one that starts its next iteration. </FONT></P>
<P><FONT face="Times New Roman,Times">The break statement (described earlier)
may also be used to break out of loops. It causes control to pass on to whatever
follows the loop controlling statement. If while (or any loop or switch)
statements are nested, then break affects only the innermost statement
containing the break. That is, it exits only one level of nesting. </FONT></P>
<P> </P>
<P><B><I><FONT face=Helvetica,Arial><A name=FOR></A>The For
Statement</FONT></I></B></P>
<P><FONT face="Times New Roman,Times">The for statement also controls loops. It
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -