代码
6.1 square.c
程序 显示平方表
现在编写一个程序来显示平方表。首先程序提示用户输入一个数 ,然后显示出 行的输出,每行包含一个1~n的数及其平方值。
This program prints a table of squares.
Enter number of entries in table: 5
1 1
2 4
3 9
4 16
5 25
把期望的平方数个数存储在变量n 中。程序需要用一个循环来重复显示数i 和它的平方值,循环从i 等于1开始。如果i 小于或等于n,那么循环将反复进行。需要保证的是每次执行循环时对i 值加1。可以使用while 语句编写循环。(坦白地说,现在没有其他更多的选择,因为while 语句是目前为止我们唯一掌握的循环类型。)下面是完成的程序。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n, i;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in table: ");
scanf("%d", &n);
i = 1;
while (i <= n) {
printf("%10d%10d\n", i, i * i);
i++;
}
return 0;
}
留意一下程序square.c 是如何把输出整齐地排成两列的。窍门是使用类似%10d 这样的转换说明代替%d ,并利用了printf 函数在指定宽度内将输出右对齐的特性。
6.1 sum.c
程序 数列求和
在下面这个用到while 语句的示例中,我们编写了一个程序对用户输入的整数数列进行求和计算。下面显示的是用户能看到的内容:
This program sums a series of integers.
Enter integers (0 to terminate): 8 23 71 5 0
The sum is: 107
很明显,程序需要一个循环来读入数(用scanf 函数)并将其累加。用n 表示当前读入的数,而sum 表示所有先前读入的数的总和,得到如下程序:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int n, sum = 0;
printf("This program sums a series of integer.\n");
printf("Enter integers (0 to terminate) : ");
scanf("%d", &n);
while (n != 0) {
sum += n;
scanf("%d", &n);
}
printf("The sum is: %d\n", sum);
return 0;
}
注意,条件n != 0 在数被读入后立即进行判断,这样可以尽快终止循环。此外,程序中用到了两个完全一样的scanf 函数调用,在使用while 循环时往往很难避免这种现象。
6.2 numdigit.c
程序 计算整数的位数
虽然C程序中while 语句的出现次数远远多于do 语句,但是后者对于至少需要执行一次的循环来说是非常方便的。为了说明这一点,现在编写一个程序计算用户输入的整数的位数:
Enter a nonnegative integer: 60
The number has 2 digit(s).
方法是把输入的整数反复除以10,直到结果变为0停止;除法的次数就是所求的位数。因为不知道到底需要多少次除法运算才能达到0,所以很明显程序需要某种循环。但是应该用while 语句还是do 语句呢?do 语句显然更合适,因为每个整数(包括0)都至少有一位数字。下面是程序。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int digits = 0, n;
printf("Enter a nonnegative integer: ");
scanf("%d", &n);
do {
n = n / 10;
digits++;
} while (n > 0);
printf("The number has %d digit(s).\n", digits);
return 0;
}
为了说明do 语句是正确的选择,下面观察一下如果用相似的while循环替换do 循环会发生什么:
while (n > 0) {
n /= 10;
digits++;
}
如果n 初始值为0,上述循环根本不会执行,程序将打印出
The number has 0 digit(s).
6.3 square2.c
程序square.c (➤6.1节)可以通过将while 循环转化为for 循环的方式进行改进。
/* Prints a table of squares using a for statement */
#include <stdio.h>
int main(void)
{
int i, n;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in table: ");
scanf("%d", &n);
for (i = 1; i <= n; i++)
printf("%10d%10d\n", i, i * i);
return 0;
}
利用这个程序可以说明关于for 语句的一个要点:C语言对控制循环行为的三个表达式没有加任何限制。虽然这些表达式通常对同一个变量进行初始化、判定和更新,但是没有要求它们之间以任何方式进行相互关联。看一下同一个程序的另一个版本。
square3.c
/* Prints a table of squares using an odd method */
#include <stdio.h>
int main(void)
{
int i, n, odd, square;
printf("This program prints a table of squares.\n");
printf("Enter number of entries in table: ");
scanf("%d", &n);
i = 1;
odd = 3;
for (square = 1; i <= n; odd += 2) {
printf("%10d%10d\n", i, square);
++i;
square += odd;
}
return 0;
}
这个程序中的for 语句初始化一个变量(square ),对另一个变量(i )进行判定,并且对第三个变量(odd )进行自增操作。变量i是要计算平方值的数,变量square 是变量i 的平方值,而变量odd是一个奇数,需要用它来和当前平方值相加以获得下一个平方值(允许程序不执行任何乘法操作而计算连续的平方值)。
for 语句这种极大的灵活性有时是十分有用的。后面我们将会发现for 语句在处理链表(➤17.5节)时非常有用。但是,for 语句很容易误用,所以请不要走极端。如果重新安排程序square3.c 的各部分内容,可以清楚地表明循环是由变量i 来控制的,这样程序中的for 循环就清楚多了。
6.4 checking.c
程序 账簿结算
许多简单的交互式程序都是基于菜单的:它们向用户显示可供选择的命令列表;一旦用户选择了某条命令,程序就执行相应的操作,然后提示用户输入下一条命令;这个过程一直会持续到用户选择“退出”或“停止”命令。这类程序的核心显然是循环。循环内将有语句提示用户输入命令,读命令,然后确定执行的操作:
for ( ; ; ) {
提示用户录入命令;
读入命令;
执行命令;
}
执行这个命令将需要switch 语句(或者级联式if 语句):
for ( ; ; ) {
提示用户录入命令;
读入命令;
switch(命令){
case 命令1:执行操作1; break;
case 命令2:执行操作2; break;
.
.
.
case 命令n:执行操作n; break;
default: 显示错误消息; break;
}
}
为了说明这种格式,开发一个程序用来维护账簿的余额。程序将为用户提供选择菜单:清空账户余额,往账户上存钱,从账户上取钱,显示当前余额,退出程序。选择项分别用整数0、1、2、3和4表示。程序会话类似这样:
*** ACME checkbook-balancing program ***
Commands: 0=clear, 1=credit, 2=debit, 3=balance, 4=exit
Enter command: 1
Enter amount of credit: 1042.56
Enter command: 2
Enter amount of debit: 133.79
Enter command: 1
Enter amount of credit: 1754.32
Enter command: 2
Enter amount of debit: 1400
Enter command: 2
Enter amount of debit: 68
Enter command: 2
Enter amount of debit: 50
Enter command: 3
Current balance: $1145.09
Enter command: 4
当用户录入命令4(即退出)时,程序需要从switch 语句以及外围的循环中退出。break 语句不可能做到,同时我们又不想使用goto语句。因此,决定采用return 语句,这条语句将可以使程序终止并且返回操作系统。
/* Balances a checkbook */
#include <stdio.h>
int main(void)
{
int cmd;
float balance = 0.0f, credit, debit;
printf("*** ACME checkbook-balancing program ***\n");
printf("Commands: 0=clear, 1=credit, 2=debit, ");
printf("3=balance, 4=exit\n\n");
for (;;) {
printf("Enter command: ");
scanf("%d", &cmd);
switch (cmd) {
case 0:
balance = 0.0f;
break;
case 1:
printf("Enter amount of credit: ");
scanf("%f", &credit);
balance += credit;
break;
case 2:
printf("Enter amount of debit: ");
scanf("%f", &debit);
balance -= debit;
break;
case