C How to Program
李思
Chapter 4 C Program Control
C 程序控制
Outline
3 4.1 引言 (Introduction)
4.2 循环的基本原理 (The Essentials of Repetition)
4.3 计数控制的循环 (Counter-Controlled Repetition)
4.4 for 循环语句
(The for Repetition Statement)
4.5 for 循环语句 : 注意事项
(The for Statement: Notes and Observations)
4.6 应用 for 循环语句的例子
(Examples Using the for Statement)
4.7 switch 多重选择语句
(The switch Multiple-Selection Statement)
4.8 do…while 循环语句
(The do…while Repetition Statement)
4.9 break 和 continue 语句
(The break and continue Statements)
4.10 逻辑运算 (Logical Operators)
4.11 区分相等运算符 (==) 和赋值运算符 (=)
Confusing Equality (==) and Assignment (=) Operators
4.12 结构化程序设计总结
Structured Programming Summary
学习目标 (Objectives)
4
• 在本章中,读者将学习以下内容 In this
chapter, you will learn:
– 使用 for 和 do…while 循环语句来重复执行某些语句 To be
able to use the for and do…while repetition statements.
– 使用 switch 选择语句实现多重选择 To understand multiple
selection using the switch selection statement.
– 使用 break 和 continue 语句来改变控制流 To be able to use the
break and continue program control statements
– 使用逻辑运算 To be able to use the logical operators.
5 4.1 Introduction
本章将介绍 (This chapter introduces)
另外两个循环语句 (Additional repetition control structures)
for
Do…while
Switch 多重选择语句( switch multiple selection statement )
Break 语句( break statement )
用于即时退出某个控制语句 (Used for exiting immediately and rapidly from certain cont
rol structures)
Continue 语句 (continue statement)
用于跳过循环体中的剩余语句,开始下一轮循环处理。 (Used for skipping the remainder of
the body of a repetition structure and proceeding with the next iteration of the loo
p)
6 4.2 The Essentials of Repetition
循环 (Loop)
在循环继续条件为真时,计算机重复执行一组计算机指令。 (Group of instructions com
puter executes repeatedly while loop-continuation condition remains true)
计数控制的循环 (Counter-controlled repetition)
确定性循环:明确地知道循环将要被执行的次数 (Definite repetition: know how many
times loop will execute)
控制变量记录当前已循环的次数 (Control variable used to count repetitions)
标记控制的循环 (Sentinel-controlled repetition)
不确定性循环 (Indefinite repetition)
循环次数事先是未知的 (Used when number of repetitions not known)
标记值表示“数据结束” (Sentinel value indicates "end of data")
7 4.3 Essentials of Counter-Controlled R
epetition
计数控制的循环需要 (Counter-controlled repetition requires)
定义控制变量 ( 或循环计数器 ) 的变量名 (The name of a control variable (or loo
p counter))
给控制变量赋初值 (The initial value of the control variable)
定义每次循环后控制变量的增量值 / 减量值。 (An increment (or decrement) by whi
ch the control variable is modified each time through the loop)
测试控制变量是否满足循环终值条件(即判断循环是否还要继续) (A condition that
tests for the final value of the control variable (i.e., whether looping sh
ould continue))
4.3 Essentials of Counter-Controlled R
8
epetition
Example:
int counter = 1; // initialization
while ( counter <= 10 ) { // repetition condition
printf( "%d\n", counter );
++counter; // increment
}
The statement
int counter = 1;
控制变量命名为 counter (Names counter)
定义为一个整数型 (Defines it to be an integer)
要求系统为它预留出存储一个整数所需的空间 (Reserves space for it in memory)
初值设为 1 (Sets it to an initial value of 1)
1 /* Fig. 4.1: fig04_01.c
2 Counter-controlled repetition */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int counter = 1; /* initialization */
9
10 while ( counter <= 10 ) { /* repetition condition */
11 printf ( "%d\n", counter ); /* display counter */
12 ++counter; /* increment */
13 } /* end while */
14
15 return 0; /* indicate program ended successfully */
16
17 } /* end function main */
1
2
3
4
5
6
7
8
9
10
10 4.3 Essentials of Counter-Controlled R
epetition
压缩代码 (Condensed code)
为了使程序更加简洁 (C Programmers would make the program more concise)
Initialize counter to 0
while ( ++counter <= 10 )
printf( “%d\n, counter );
1 /* Fig. 4.2: fig04_02.c
2 Counter-controlled repetition with the for statement */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int counter; /* define counter */
9
10 /* initialization, repetition condition, and increment
11 are all included in the for statement header. */
12 for ( counter = 1; counter <= 10; counter++ ) {
13 printf( "%d\n", counter );
14 } /* end for */
15
16 return 0; /* indicate program ended successfully */
17
18 } /* end function main */
12 4.4 The for Repetition Statement
13 4.4 The for Repetition Statement
For 循环的格式 (Format when using for loops)
for ( initialization; loop Continuation Test; increment )
statement
Example:
for( int counter = 1; counter <= 10; counter++ )
printf( "%d\n", counter );
No semicolon (;) after
打印 1 到 10 (Prints the integers from one to ten)
last expression
14 4.4 The for Repetition Statement
for 循环可以表示成 while 语句 ( for loops can usually be rewritten as
while loops):
initialization;
while ( loopContinuationTest ) {
statement;
increment;
}
初始化表达式和增量表达式 (Initialization and increment)
用逗号分隔 (Can be comma-separated lists)
Example:
for (int i = 0, j = 0; j + i <= 10; j++, i++)
printf( "%d\n", j + i );
4.5 The for Statement : Notes and Observa
15
tions
算术表达式 (Arithmetic expressions)
初始化、循环继续条件及增量操作可以包含算术表达式 (Initialization, loop-continuati
on, and increment can contain arithmetic expressions.)
If x equals 2 and y equals 10
for ( j = x; j <= 4 * x * y; j += y / x )
is equivalent to
for ( j = 2; j <= 80; j += 5 )
for 语句注意事项 (Notes about the for statement):
增量值可以是负数 ("Increment" may be negative (decrement))
如果循环继续条件被初始化为假 (If the loop continuation condition is initially fa
lse)
循环体不执行 (The body of the for statement is not performed)
计算机将执行程序中紧随 for 语句之后的那条语句。 (Control proceeds with the next statement
after the for statement)
循环控制变量 (Control variable)
打印输出或应用于循环体的计算中,但不是必需的 (Often printed or used inside for body, but
not necessary)
4.5 The for Statement : Notes and Obs
ervations
Establish initial
value of control
variable
counter
counter = 1
true
counter <= 10 printf( "%d", counter ); counter++
Increment
the control
Determine if final false Body of loop variable
value of control (this may be many
variable has been statements)
reached
16
1 /* Fig. 4.5: fig04_05.c
2 Summation with for */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int sum = 0; /* initialize sum */
9 int number; /* number to be added to sum */
10
11 for ( number = 2; number <= 100; number += 2 ) {
12 sum += number; /* add number to sum */
13 } /* end for */
14
15 printf( "Sum is %d\n", sum ); /* output sum */
16
17 return 0; /* indicate program ended successfully */
18
19 } /* end function main */
Sum is 2550
1 /* Fig. 4.6: fig04_06.c
2 Calculating compound interest */
3 #include <stdio.h>
4 #include <math.h>
5
6 /* function main begins program execution */
7 int main()
8 {
9 double amount; /* amount on deposit */
10 double principal = 1000.0; /* starting principal */
11 double rate = .05; /* interest rate */
12 int year; /* year counter */
13
Year Amount on deposit
14 /* output table column head */
15 printf( "%4s%21s\n", "Year", "Amount on deposit" );
1 1050.00
16 2 1102.50
17 /* calculate amount on deposit for each of ten years */ 3 1157.63
18 for ( year = 1; year <= 10; year++ ) { 4 1215.51
19
5 1276.28
20 /* calculate new amount for specified year */
21 amount = principal * pow( 1.0 + rate, year );
6 1340.10
22 7 1407.10
23 /* output one table row */ 8 1477.46
24 printf( "%4d%21.2f\n", year, amount ); 9 1551.33
25 } /* end for */
10 1628.89
26
27 return 0; /* indicate program ended successfully */
28
29 } /* end function main */
19 4.7 The switch Multiple-Selection St
atement
switch
通过测试某个变量或表达式的值与事先指定的一组整形常量中的一个是否相等,然后执行不同的操作 (Useful when
a variable or expression is tested for all the values it can assume and different actions are taken)
格式 Format
由一系列 case 从句和一个可选的 default 从句组成。 (Series of case labels and an optional default c
ase)
switch ( value ){
case '1':
actions
case '2':
actions
default:
actions
}
break; exits from statement
4.7 The switch Multiple-Selection Statement
Switch 流程图 (Flowchart of the switch statement)
case a true case a action(s) break
false
case b true case b action(s) break
false
.
.
.
case z
true case z action(s) break
false
default action(s)
1 /* Fig. 4.7: fig04_07.c
2 Counting letter grades */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int grade; /* one grade */
9 int aCount = 0; /* number of As */
10 int bCount = 0; /* number of Bs */
11 int cCount = 0; /* number of Cs */
12 int dCount = 0; /* number of Ds */
13 int fCount = 0; /* number of Fs */
14
15 printf( "Enter the letter grades.\n" );
16 printf( "Enter the EOF character to end input.\n" );
17
18 /* loop until user types end-of-file key sequence */
19 while ( ( grade = getchar() ) != EOF ) {
20
21 /* determine which grade was input */
22 switch ( grade ) { /* switch nested in while */
23
24 case 'A': /* grade was uppercase A */
25 case 'a': /* or lowercase a */
26 ++aCount; /* increment aCount */
27 break; /* necessary to exit switch */
28
29 case 'B': /* grade was uppercase B */
30 case 'b': /* or lowercase b */
31 ++bCount; /* increment bCount */
32 break; /* exit switch */
33
34 case 'C': /* grade was uppercase C */
35 case 'c': /* or lowercase c */
36 ++cCount; /* increment cCount */
37 break; /* exit switch */
38
39 case 'D': /* grade was uppercase D */
40 case 'd': /* or lowercase d */
41 ++dCount; /* increment dCount */
42 break; /* exit switch */
43
44 case 'F': /* grade was uppercase F */
45 case 'f': /* or lowercase f */
46 ++fCount; /* increment fCount */
47 break; /* exit switch */
48
49 case '\n': /* ignore newlines, */
50 case '\t': /* tabs, */
51 case ' ': /* and spaces in input */
52 break; /* exit switch */
53
54 default: /* catch all other characters */
Enter the letter grades.
55 printf( "Incorrect letter grade entered." ); Enter the EOF character to end input.
56 printf( " Enter a new grade.\n" ); a
57 break; /* optional; will exit switch anyway */ b
c
58 } /* end switch */
C
59 A
60 } /* end while */ d
61 f
C
62 /* output summary of results */
E
63 printf( "\nTotals for each letter grade are:\n" ); Incorrect letter grade entered. Enter a new grade.
64 printf( "A: %d\n", aCount ); /* display number of A grades */ D
65 printf( "B: %d\n", bCount ); /* display number of B grades */ A
b
66 printf( "C: %d\n", cCount ); /* display number of C grades */
^Z
67 printf( "D: %d\n", dCount ); /* display number of D grades */
68 printf( "F: %d\n", fCount ); /* display number of F grades */ Totals for each letter grade are:
69 A: 3
B: 2
70 return 0; /* indicate program ended successfully */
C: 3
71 D: 2
72 } /* end function main */ F: 1
24 4.8 The do…while Repetition Stateme
nt
do..while 循环语句 (The do…while repetition statement)
与 while 语句相似 (Similar to the while structure)
首先进行循环继续条件的测试,根据测试结果决定是否继续下一轮循环。 (Condition for
repetition tested after the body of the loop is performed)
循环语句中的循环体至少会被执行一次 (All actions are performed at least once)
Format:
do {
statement;
} while ( condition );
25 4.8 The do…while Repetition Stateme
nt
Example (letting counter = 1):
do {
printf( "%d ", counter );
} while (++counter <= 10);
打印数字 1 到 10 的程序。 (Prints the integers from 1 to 10)
26 4.8 The do…while Repetition Stateme
nt
do…while 循环流程图 (Flowchart of the do…while repetition statemen
t)
action(s)
true
condition
false
1 /* Fig. 4.9: fig04_09.c
2 Using the do/while repetition statement */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int counter = 1; /* initialize counter */
9
10 do {
11 printf( "%d ", counter ); /* display counter */
12 } while ( ++counter <= 10 ); /* end do...while */
13
14 return 0; /* indicate program ended successfully */
15
16 } /* end function main */
1 2 3 4 5 6 7 8 9 10
28 4.9 The break and continue Statemen
ts
break
在 while 、 for 、 do…while 或者 switch 语句中,执行 break 语句将导致程序立即从这
些语句中退出。 (Causes immediate exit from a while, for, do…while or
switch statement)
执行紧跟这些语句之后的下一条语句。 (Program execution continues with the first
statement after the structure)
Break 常用于 (Common uses of the break statement)
提前退出循环 (Escape early from a loop)
跳过 switch 多重选择结构中的剩余语句 (Skip the remainder of a switch statement)
1 /* Fig. 4.11: fig04_11.c
2 Using the break statement in a for statement */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int x; /* counter */
9
10 /* loop 10 times */
11 for ( x = 1; x <= 10; x++ ) {
12
13 /* if x is 5, terminate loop */
14 if ( x == 5 ) {
15 break; /* break loop only if x is 5 */
16 } /* end if */
17
18 printf( "%d ", x ); /* display value of x */
19 } /* end for */
20
21 printf( "\nBroke out of loop at x == %d\n", x );
22
23 return 0; /* indicate program ended successfully */
24
25 } /* end function main */
1 2 3 4
Broke out of loop at x == 5
30 4.9 The break and continue Statemen
ts
continue
在 while 、 for 、 do…while 循环结构中, continue 语句将使控制流略过循环体中的剩
余语句 Skips the remaining statements in the body of a while, for or do
…while statement
重新开始新一轮循环 Proceeds with the next iteration of the loop
while and do…while
执行 continue 语句后,将立即进行循环继续条件的测试 Loop-continuation test is evaluat
ed immediately after the continue statement is executed
for
执行 continue 语句后,将会立即执行增量表达式,然后再进行循环继续条件的测试。 Increment
expression is executed, then the loop-continuation test is evaluated
1 /* Fig. 4.12: fig04_12.c
2 Using the continue statement in a for statement */
3 #include <stdio.h>
4
5 /* function main begins program execution */
6 int main()
7 {
8 int x; /* counter */
9
10 /* loop 10 times */
11 for ( x = 1; x <= 10; x++ ) {
12
13 /* if x is 5, continue with next iteration of loop */
14 if ( x == 5 ) {
15 continue; /* skip remaining code in loop body */
16 } /* end if */
17
18 printf( "%d ", x ); /* display value of x */
19 } /* end for */
20
21 printf( "\nUsed continue to skip printing the value 5\n" );
22
23 return 0; /* indicate program ended successfully */
24
25 } /* end function main */
1 2 3 4 6 7 8 9 10
Used continue to skip printing the value 5
32 4.10 Logical Operators
&& ( logical AND )
当且仅当体中的两个条件都为真时,返回真 Returns true if both conditions are true
|| ( logical OR )
有一个或两个为真时,返回真 Returns true if either of its conditions are true
! ( logical NOT, logical negation )
翻转一个条件的值 Reverses the truth/falsity of its condition
一元的逻辑非运算符只需一个条件作为它的操作数 Unary operator, has one operand
常用于循环条件 Useful as conditions in loops
ExpressionResult
true && false false
true || false true
!false true
33 4.10 Logical Operators
expression1 expression2 expression1 && expression2
0 0 0
0 nonzero 0
nonzero 0 0
nonzero nonzero 1
Fig. 4.13 Truth table for the && (logical AND) operator.
expression1 expression2 expression1 || expression2
0 0 0
0 nonzero 1
nonzero 0 1
nonzero nonzero 1
Fig. 4.14 Truth table for the logical OR (||) operator.
expression ! expression
0 1
nonzero 0
Fig. 4.15 Truth table for operator ! (logical negation).
34 4.10 Logical Operators
Operators Associativity Type
++ -- + - ! (type) right to left unary
* / % left to right multiplicative
+ - left to right additive
< <= > >= left to right relational
== != left to right equality
&& left to right logical AND
|| left to right logical OR
?: right to left conditional
= += -= *= /= %= right to left assignment
, left to right comma
Fig. 4.16 Operator precedence and associativity.
35 4.11 Confusing Equality (==) and Ass
ignment (=) Operators
Dangerous error
不会引起语法错误 (Does not ordinarily cause syntax errors)
任何一个可产生数值的表达式都可以用在任何一个控制语句的判断部分 (Any expression
that produces a value can be used in control structures )
非 0 为真, 0 为假 (Nonzero values are true, zero values are false)
Example using ==:
if ( payCode == 4 )
printf( "You get a bonus!\n" );
Checks payCode, if it is 4 then a bonus is awarded
36 4.11 Confusing Equality (==) and Ass
ignment (=) Operators
Example, replacing == with =:
if ( payCode = 4 )
printf( "You get a bonus!\n" );
This sets payCode to 4
4 is nonzero, so expression is true, and bonus awarded no matter what the payCo
de was
Logic error, not a syntax error
37 4.11 Confusing Equality (==) and Ass
ignment (=) Operators
左值 lvalues
只能出现在赋值运算符的左边 Expressions that can appear on the left side of an equation
值可以被改变,例如变量名 Their values can be changed, such as variable names
x = 4;
右值 rvalues
只能出现在赋值运算符的右边 Expressions that can only appear on the right side of an equation
常量,例如数字 Constants, such as numbers
Cannot write 4 = x;
Must write x = 4;
左值可以用做右值,但右值不能用做左值 。 lvalues can be used as rvalues, but not vice versa
y = x;
4.12 Structured-Programming Summary
Selection
if statement if…else statement
(single selection) (double selection)
T F T
Se q u e n c e F
switch statement
(multiple selection)
T break
F
T break
. F
. .
. .
.
T break
38
39 4.12 Structured-Programming Summary
Repetition
while statement do…while statement for statement
T
F T
T
F
F
40 4.12 Structured-Programming Summary
结构化程序设计 Structured programming
相比于非结构化,更易于理解、测试、调试及修改 Easier than unstructured programs to underst
and, test, debug and, modify programs
构建结构化程序的规则 Rules for structured programming
Rules developed by programming community
Only single-entry/single-exit control structures are used
Rules:
1. 从最简单的流程图开始 (Begin with the “simplest flowchart”)
2. 任何一个矩形可以用两个顺序的矩形来替换 (Stacking rule: Any rectangle (action) can be replaced by
two rectangles (actions) in sequence)
3. 任何一个矩形可以用任何一个控制语句来替换 (Nesting rule: Any rectangle (action) can be replaced by
any control structure (sequence, if, if…else, switch, while, do…while or for))
4. 规则 2 和 3 可以根据编写者的意图反复应用并可以按照任意顺序应用 (Rules 2 and 3 can be applied in any
order and multiple times)
41
4.12 Structured-Programming Summary
Rule 2 - Any rectangle can be
Rule 1 - Begin with the
replaced by two rectangles in
simplest flowchart
sequence
Rule 2 Rule 2 Rule 2
.
.
.
4.12 Structured-Programming Summary
42
Rule 3 - Replace any rectangle with a control structure
Rule 3
Rule 3
Rule 3
4.12 Structured-Programming Summary
St a c ke d b u ild in g b lo c ks Ne ste d b u ild in g b lo c ks
O v e rla p p in g b u ild in g b lo c ks
(Ille g a l in s tru c ture d p ro g ra ms)
44 4.12 Structured-Programming Summary
Figure 4.23 An unstructured flowchart.
45 4.12 Structured-Programming Summary
如下三种控制结构就可以开发出任意复杂的程序 (All programs can be broken d
own into 3 controls)
顺序 Sequence – handled automatically by compiler
选择 Selection – if, if…else or switch
循环 Repetition – while, do…while or for
上述控制语句的组合方式有两种 (Can only be combined in two ways)
嵌套 Nesting (rule 3)
堆叠 Stacking (rule 2)
if 语句可以实现任何形式的选择功能, while 语句可以实现任何形式的循环功能 (Any s
election can be rewritten as an if statement, and any repetition can be rewri
tten as a while statement)