第四章 循环结构程序设计
1.选择题
(1)下述循环体语句的循环次数为(A)。
int x = -1;
do
{x = x * x;} while (!x);
A. 1次
B. 2次
C. 无限次
D. 有语法错误
第一次循环中,执行循环体语句,x = 1。!x为假,不符合循环条件,循环结束。因此选择A。
(2)在下列选项中,没有构成死循环的程序段是(C)。
A.
int i = 100;
while(1)
{i = i % 100 + 1;
if(i > 100) break;
}
B.
for(;;);
C.
int k = 1000;
do {++k;} while (k >= 10000);
D.
int s = 36;
while (s);--s;
A中,初次循环后,i的值为1,此后每经循环i值加1直至100,再如初次循环得1,故该程序死循环, A错误;B中,无初值,无判断条件,循环变量无变化,无终止语句,死循环,B错误;C中,初次循环,k值为1001,不符合循环条件,循环结束,非死循环,故C正确;D中,“--s”并未被包含在while循环中,只有在测试条件后的单独语句才是循环部分,而第二行的首个“ ; ”已将while结束,故D错误。选择C。
(3)下面程序输出结果是(B)。
#include<stdio.h>
int main(void)
{ int k=0; char c='A';
do
{ switch( c++ )
{ case 'A': k++; break;
case 'B': k--;
case 'C': k += 2; break;
case 'D': k = k % 2; continue;
case 'E': k = k * 10; break;
default: k = k / 3;
}
k++;
}while(c < 'G');
printf("k=%d\n",k);
return 0;
}
A.k=3
B.k=4
C.k=2
D.k=0
switch中c,k的值依次为'B',1;'C',1;'C',3;'D',6;'E',1;'F',10;'G',3。后经k++,循环结束,k为4,故B正确。
(4)程序段“int num=0; while(num<=2) printf("%d,",num++);”的运行结果是(C)。
A.0,1, B.1,2, C.0,1,2, D.1,2,3,
程序段中的printf属于while语句,num++先参与运算后自增,故输出依次为“0,”、“1,”、“2,”,故C正确。
(5)下面程序段的运行结果为(A)。
int a = 1, b = 2, c = 2, t;
while(a < b < c) {t = a; a = b; b = t; c--;}
printf("%d,%d,%d", a, b, c);
A.1,2,0
B.2,1,0
C.1,2,1
D.2,1,1
关系运算符结合方向从左至右,a < b < c实为(a < b)< c,(1) < 2,因此表达式为真,循环语句执行,a、b、c 值分别为 2、1、1,(0) < 1,再次执行,故a、b、c值为 1,2,0,故A正确。
(6)设有以下语句:
int x = 3;
do
{
printf("%d\n", x -= 2);
} while (!(--x));
该程序段的执行结果为(B)。
A.显示1 B.显示1和-2 C.显示0 D.是死循环
首次执行后,显示 1,在判断语句中(--x)值为0,(!(--x)) 即 (!0),值为真,再次执行显示 -2,(!(--x))值为假,循环结束,故B正确。
(7)下面有关for循环的正确描述是(D)。
A.for循环只能用于循环次数已经确定的情况
B.for是先执行循环体语句,后判断表达式
C.在for循环中,不能用break语句跳出循环体
D.for循环的循环体语句中,可以包含多条语句,但必须用花括号括起来
A中,for循环语句仅通常应用于循环次数已知的场景,故A错误;B中,for先判断表达式,后执行循环体语句,故B错误;C中,for循环可以用break语句跳出循环体;D,正确。故选择D。
(8)执行下面的程序后,a的值为(B)。
#include<stdio.h>
int main(void)
{ int a, b;
for(a = 1, b = 1; a <= 100; a++)
{ if (b >= 20) break;
if (b % 3 == 1)
{b += 3; continue; }
b -= 5;
}
return 0;
}
A.7
B.8
C.9
D.10
程序重复 b += 3 直到 b 值为22,此时已经过7次循环,a 值为 8,于 if (b >= 20) break; 处跳出循环,故选择B。
(9)以下叙述正确的是(D)。
A.不能使用do-while语句构成的循环
B.do-while语句构成的循环必须用break语句才能退出
C.do-while语句构成的循环,当while语句中的表达式值为非零时结束循环
D.do-while语句构成的循环,当while语句中的表达式值为零时结束循环
A中,错误;B中,使用return也可退出,B错误;C中,do-while语句构成的循环,当while语句中的表达式值为零时结束循环,故C错误,D正确。选择D。
(10)以下叙述正确的是(B)。
A.continue语句的作用是结束整个循环的执行
B.只能在循环体内和switch语句体内使用break语句
C.在循环体内使用break语句或continue语句的作用相同
D.从多层循环嵌套中退出,只能使用goto语句
A中,continue只结束本次循环,并不跳出循环;B中,正确;C中,break语句终止整个循环的执行,不同于continue,C错误;D中,return语句、利用异常等都可从多层循环嵌套中退出,D错误。选择B。
2.填空题
(1)break语句只能用于 循环 语句和 switch 语句中。
(2)下列for循环语句执行的次数是 4 。
for(x = 0, y = 0; (y = 123)&&(x < 4); x++);
x从0开始,执行x++直至x > 4,历经4次
(3)当运行以下程序时,从键盘键入right?,则下面程序运行结果是 sjhiu 。
#include<stdio.h>
int main(void)
{
char c;
while((c = getchar()) != '?')
putchar(++c);
return 0;
}
非 '?' 字符都变为对应ACSII值加1的字符,直至取到 '?' 结束。
(4)下列程序的运行结果是 x=1,y=20 。
#include<stdio.h>
int main(void)
{
int i,x,y;
i = x = y = 0;
do{ ++i;
if(i % 2 != 0)
{
x = x + i;
i++;
}
y = y + i++;
} while (i <= 7);
printf("x=%d,y=%d\n", x, y);
return 0;
}
循环中 i,x,y 依次为 3, 1, 2; 5, 1, 6;7, 1, 12;9, 1, 20。此时循环结束。
(5)执行下列程序段后的输出是 02 。
x = 0;
while (x < 3)
for(; x < 4; x++)
{
printf("%d", x++);
if (x < 3) continue;
else break;
printf("%d", x);
}
在 printf("%d", x++); 处输出 0,第二次for循环中,同一位置输出 2,此后x值为3,else break; 处退出for循环,此时已经不符合while的循环条件,程序结束。
(6)设定义“int k=1,n=163;”,执行下面程序段后,k的值是 18 。
do
{
k *= n % 10;
n /= 10;
} while (n);
循环中,k、n的值依次为3、16;18、1;18、0。n为0时退出循环。
(7)以下程序的运行结果是 1 。
#include <stdio.h>
int main(void)
{ int y = 10;
do {y--;} while (--y);
printf("%d\n",++y);
}
(--y)值为0时退出循环,此时 ++y 值为 1。
(8)以下程序的运行结果是 s=7 。
#include <stdio.h>
int main(void)
{
int s = 0, k;
for(k = 7; k >= 0; k--)
{ switch(k)
{ case 1: case 4:
case 7: s++; break;
case 2: case 3: case 6: break;
case 0: case 5: s+=2; break;
}
}
printf( “s=%d \n”,s );
return 0;
}
switch语句中,若没有break语句,则不经比较判断,继续执行下一个case分支。循环中s、k值依次为1、6;1、5;3、4;4、3;4、2;4、1;5、0;7、-1。
(9)下列程序的功能为:将从键盘输入的一组字符统计出大写字母的个数m和小写字母的个数 n,并输出m、n中的较大数。程序下划线处分别填入 c=getchar() 、n:m 。
#include<stdio.h>
int main(void)
{ int m = 0, n = 0;
char c;
while((___________) !='\n')
{ if(c >= 'A'&&c <= 'Z') m++;
if(c >= 'a'&&c <= 'z') n++;
}
printf("%d\n", m<n?__________);
return 0;
}
while循环负责统计个数,第一处下划线意为读取字符至 c 。m和n的比较在条件表达式进行,第二处下划线意为条件表达式在m、n两种大小情况下的取值。
(10)下列程序的功能为:求1~100以内所有能被13整除的数的累加和,当累加和超出100时停止累加。程序下划线处分别填入 i % 13 == 0 、break 。
#include <stdio.h>
int main(void)
{ int i, sum = 0;
for ( i=1; i<100; i++ )
{ if (_________) sum += i;
if (sum > 100) ________;
}
printf( “i=%d, sum=%d\n”, i, sum);
return 0;
}
第一处下划线意为判断 i 是否可被 13 整除。第二处下划线意为累加和 sum 超出 100 时停止累加的语句。
3.编程题
(1)从键盘上输入若干字符,以按Enter键结束,统计其中字符'A'或'a'的个数。
#include<stdio.h>
int main(void)
{
char ch;
int sum = 0;
while ((ch = getchar()) != '\n')//读取字符,直至换行
{
if (ch == 'A' || ch == 'a')
{
sum++;//ch若取到的'A'或'a',sum计数加 1
}
}
printf("sum=%d\n", sum);//输出结果
return 0;
}
(2)利用
的前100项之积计算π的值。
#include<stdio.h>
int main(void)
{
double pi = 2;//提前将题目等式的分母进行处理
for (int i = 2; i < 101; i += 2)//利用每两项的规律
{
pi *= (double)i * i / (i * i - 1);//计算每两项进行累乘
}
printf("pi = %f", pi);//运行结果为 “pi = 3.126079”
return 0;
}
(3)用1元5角钱人民币兑换5分、2分和1分的硬币(每一种都要有)共100枚,问共有几种兑换方案?每种方案各换多少枚?
#include<stdio.h>
int main(void)
{
int res = 0;// res 记录方案的数量
for (int i = 1; i < 30; i++)// i 表示 5 分的数量,通过穷举计算方案数量
{
for (int j = 1; j < 75 && (i + j) < 100; j++)// j 表示 2 分的数量
{// (i + j) < 100 意在确保两种硬币数量和小于 100 枚
if (i * 5 + j * 2 + (100 - i - j) == 150 && (100 - i - j) != 0) {//确定 1 分数量并检查
res++;//方案数量累加
printf("第%d种:\tfive=%d\ttwo=%d\tone=%d\n", res, i, j, (100 - i - j));
/*运行结果
第1种: five = 1 two = 46 one = 53
第2种 : five = 2 two = 42 one = 56
第3种 : five = 3 two = 38 one = 59
第4种 : five = 4 two = 34 one = 62
第5种 : five = 5 two = 30 one = 65
第6种 : five = 6 two = 26 one = 68
第7种 : five = 7 two = 22 one = 71
第8种 : five = 8 two = 18 one = 74
第9种 : five = 9 two = 14 one = 77
第10种 : five = 10 two = 10 one = 80
第11种 : five = 11 two = 6 one = 83
第12种 : five = 12 two = 2 one = 86*/
}
}
}
return 0;
}
(4)鸡兔同笼,共有98个头,386只脚,编程求鸡、兔各多少只。
#include<stdio.h>
int main(void)
{
int head = 98, foot;//head 意为兔的数量
while (head > 0)
{
foot = head * 4 + (98 - head) * 2;//计算 head 只兔下,鸡兔脚的数量和
if (foot == 386)//符合要求则输出
{
printf("兔有: %d只\t鸡有: %d只\n", head, (98 - head));
//运行结果
//兔有: 95只 鸡有: 3只
break;//舍去不必要的计算
}
head--;
}
return 0;
}
(5)将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
#include<stdio.h>
int main()
{
int n, i;
printf("请输入整数:");
scanf("%d", &n);
printf("%d=", n);
for (i = 2; i < n + 1; i++)
{// i 作为可能的质因数
while (n % i == 0)
{
printf("%d", i);
n /= i;//对 n 分解
if (n != 1)
{//分解未完全结束时,每找到一个质因数添一个 *
printf("*");
}
}
}
return 0;
}
(6)一个数如果恰好等于它的因子之和,这个数就称为完数。例如,6=1+2+3。编程找出1000以内所有的完数。
#include<stdio.h>
int main()
{
int res = 0;//res 记录因数和
for (int i = 2; i < 1001; i++)//穷举2~1000
{
res = 0;
for (int j = 1; j < i; j++)
{
if (i % j == 0)
{//如果 j 为 i 的因数,则累加到 res
res += j;
}
}
if (res == i)
{//i 等于因数和则输出
printf("%d\n", res);
/*运行结果
6
28
496*/
}
}
return 0;
}
(7)打印出所有“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个水仙花数
#include<stdio.h>
int main()
{
int j, res = 0;
for (int i = 100; i < 1000; i++)
{
res = 0;//记录各位立方和
j = i;
while (j > 0)
{
res += (j % 10) * (j % 10) * (j % 10);//求得立方和累加
j /= 10;//处理 j,以求另一位
}
if (res == i)//检查是否为水仙花数
{
printf("%d\n", i);
/*运行结果
153
370
371
407*/
}
}
return 0;
}
(8)利用泰勒级数 计算 sin(x) 的值。
要求最后一项的绝对值小于,并统计出此时累加了多少项(x由键盘输入)。
#include <stdio.h>
#include <math.h>
int main(void)
{
int n = 1, count = 1;
float x;
double sum,term;
printf("Input x: "); //输入值为弧度
scanf("%f", &x);
sum = x;
term = x;
do
{
term = -term * x * x / ((n + 1) * (n + 2));
sum = sum + term;
n = n + 2;
count++;
} while (fabs(term) >= 1e-5);
printf("sin(x)=%.1f,count=%d\n", sum, count);
return 0;
}
(9)编写一个猜数游戏:任意设置一个整数,请用户从键盘上输入数据猜想设置的数是什么,告诉用户是猜大了还是小了。10次以内猜对,用户获胜;否则,告诉用户设置的数据是什么。
#include <stdio.h>
#include <time.h>
int main(void)
{
srand((unsigned)time(NULL));
int i, n;
int res = rand() % 100 + 1;//生成1~100的随机数
for (i = 0; i < 10; i++)
{//用循环限制次数
printf("输入1~100内的整数:");
scanf("%d", &n);
if (n > res)
{
printf("猜大了\n");
}
else if (n < res)
{
printf("猜小了\n");
}
else
{
printf("猜对了\n");
break;
}
}
if (i == 10)
{
printf("数字是%d", res);
}
return 0;
}
(10)编程输出以下图案。
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
#include <math.h>
#include <stdio.h>
int main(void)
{
int n;
for (int i = 1; i < 8; i++)
{//利用各行与中心行位置的不同而变化的规律
n = abs(4 - i);//n 意为离中心行的距离
for (int j = 0; j < n; j++)
{//距离为 n,需要 n 个空位
printf(" ");
}
for (int j = 0; j < 2 * (4 - n) - 1; j++)
{//距离为 n,需要 2 * (4 - n) - 1 个 *
printf("* ");
}
printf("\n");
}
return 0;
}
如有错误不足之处,恳请批评指正。
题目来源:C程序设计教程与实验(第3版) 吉顺如主编
答案参照微信公众号:程序设计及信息技术学习平台