国庆练习(Day23)
练习一
数据类型与作用域练习
-
选择题
1.1、以下选项中,不能作为合法常量的是 __________
A)1.234e04 B)1.234e0.4
C)1.234e+4 D)1.234e0
解析:
A)1.234e04
这是合法的科学计数法表示,指数部分是 04,可以写作 1.234 × 10^4。
合法
B)1.234e0.4
指数部分 0.4 不是一个合法的整数,科学计数法中的指数部分必须是整数。
不合法
C)1.234e+4
这是合法的科学计数法表示,指数部分是 +4,可以写作 1.234 × 10^4。
合法
D)1.234e0
这是合法的科学计数法表示,指数部分是 0,可以写作 1.234 × 10^0,即 1.234。
合法
解答:
B
1.2、以下定义变量并初始化错误的是_____________。
A) char c1 = ‘H’ ;
B) char c1 = 99 ;
C) char c1 = ‘2’;
D) char c1 = 09 ;
解析:
A) char c1 = 'H';
'H' 是一个合法的字符常量,单引号括起来的字符会存储其对应的 ASCII 码(72)。
正确
B) char c1 = 99;
99 是一个合法的整数,代表字符 'c' 的 ASCII 码(99 对应字符 'c')。
正确
C) char c1 = '2';
'2' 是合法的字符常量,其 ASCII 码是 50。
正确
D) char c1 = 09;
这个赋值是非法的,因为前导 0 表示八进制数,而八进制数中的每一位应在 0 到 7 之间。09 不符合八进制格式,因此不合法。
错误
解答:
D
1.3、以下定义变量及初始化错误的是__________。
A) int a=3,b;
B) int a, b=3;
C) int a, b, c=d=3;
D) int a=3, b=3;
解析:
A) int a=3, b;
这是合法的变量声明和初始化。a 被初始化为 3,b 被声明但未初始化。
正确
B) int a, b=3;
这是合法的变量声明和初始化。a 被声明但未初始化,b 被初始化为 3。
正确
C) int a, b, c=d=3;
这是不合法的。虽然 d=3 是正确的赋值操作,但 d 在这里没有事先声明。C 语言中要求所有变量在使用前必须声明。
错误
D) int a=3, b=3;
这是合法的变量声明和初始化。a 和 b 都被声明且初始化为 3。
正确
解答:
C
1.4、设有如下程序:( )
#include "stdio.h"
int main()
{
int a, b;
a = 077;
b= a/5;
printf( "%d %d \n" , a , b);
}
A) 77, 15.2
B) 77, 15
C) 63, 12.2
D) 63, 12
解析:
a = 077;
077 是八进制数,转换为十进制是 63。所以 a 的值是 63。
b = a / 5;
a 是 63,所以 63 / 5 进行整数除法,结果是 12。小数部分 0.6 会被丢弃。
printf("%d %d\n", a, b);
输出 a 和 b 的值,即 63 和 12。
解答:
D
1.5、有以下程序
main()
{ int m,n,p;
scanf("m=%dn=%dp=%d",&m,&n,&p);
printf("%d%d%d\n",m,n,p);
}
若想从键盘上输入数据,使变量m中的值为123,n中的值为456,p中的值为789,则正确的输入是 _______
A)m=123n=456p=789
B)m=123 n=456 p=789
C)m=123,n=456,p=789
D)123 456 789
解析:
A) m=123n=456p=789
正确。该选项严格符合 scanf 中指定的格式 "m=%dn=%dp=%d",所以能够正确读取 m=123, n=456, p=789。
B) m=123 n=456 p=789
错误。虽然输入了正确的数值,但由于多余的空格,不能匹配 scanf 格式。
C) m=123,n=456,p=789
错误。该选项使用了逗号 , 分隔变量,格式与 scanf 中的格式 "m=%dn=%dp=%d" 不匹配。
D) 123 456 789
错误。该选项完全忽略了 m=, n=, p=,格式不符合 scanf 中的要求。
解答:
A
1.6、以下程序的正确结果是________
#include<stdio.h>
void num()
{
extern int x,y;
int a=15,b=10;
x=a-b;
y=a+b;
}
int x, y;
int main()
{
int a=7,b=5;
x=a+b;
y=a-b;
num();
printf("%d,%d\n",x,y);
}
A) 12,2 B) 不确定 C) 5,25 D) 1,12
解析:
全局变量:
int x, y; 定义了两个全局变量 x 和 y,它们在整个程序中可见。
main() 函数:
int a=7, b=5; 定义了局部变量 a 和 b,它们只在 main() 函数内有效。
x = a + b; 将 x 赋值为 7 + 5 = 12。
y = a - b; 将 y 赋值为 7 - 5 = 2。
3. num() 函数:
extern int x, y; 声明了全局变量 x 和 y,使得 num() 函数可以访问并修改全局变量。
在 num() 函数中,局部变量 a=15,b=10:
x = a - b; 将全局变量 x 赋值为 15 - 10 = 5。
y = a + b; 将全局变量 y 赋值为 15 + 10 = 25。
解答:
C
1.7 有以下程序
#include <stdio.h>
int fun( )
{
static int x=1;
x*=2;
return x;
}
int main( )
{
int i, s=1;
s*= fun();
s*=fun();
s*=fun();
printf("%d\n",s);
}
程序运行后的输出结果是
A)8 B)16 C)32 D)64
解析:
第一次调用 fun():
x 是一个静态局部变量,初始值为 1,然后执行 x *= 2;,结果是 x = 1 * 2 = 2。
返回 2,s *= fun();,此时 s = 1 * 2 = 2。
第二次调用 fun():
因为 x 是静态变量,上次调用 fun() 后 x 的值已经是 2。
执行 x *= 2;,结果是 x = 2 * 2 = 4。
返回 4,s *= fun();,此时 s = 2 * 4 = 8。
第三次调用 fun():
上次调用 fun() 后,x 的值是 4。
执行 x *= 2;,结果是 x = 4 * 2 = 8。
返回 8,s *= fun();,此时 s = 8 * 8 = 64。
解答:
D
2、填空题
2.1、以下程序运行时若从键盘输入:10 20 30<回车>。输出结果是
#include <stdio.h>
main()
{ int i=0,j=0,k=0;
scanf("%d%*d%d",&i,&j,&k); // %*d 表示跳过某个输入的内容,使下一个输入的内容复制给紧接着的变量,表示此数据不读入
printf("%d%d%d\n",i,j,k);
}
解析:
第一个 %d 读取 10,赋值给 i,此时 i = 10。
%*d 跳过 20,不做任何处理。
第二个 %d 读取 30,赋值给 j,此时 j = 30。
k 没有被赋值,依然保持初始化值 0。
解答:
10 30 0
2.2、以下程序运行的结果是___________。
main( )
{
int a=1, b=2, c=3;
++a; //a=a+1
c+=++b;
{
int b=4, c;
c=b*3;
a+=c;
printf(“first: %d,%d,%d\n”, a,b,c);
a+=c;
printf(“second: %d,%d,%d\n”, a,b,c);
}
printf(“third: %d,%d,%d\n”, a,b,c);
}
解析:
全局部分的变量初始化与操作:
int a = 1, b = 2, c = 3;
初始化 a = 1, b = 2, c = 3。
++a;
前置自增,a = 1 + 1 = 2。
c += ++b;
首先 ++b 自增,b = 2 + 1 = 3,然后 c += b,即 c = 3 + 3 = 6。
2. 进入内部代码块:
在 main() 函数内定义了一个新的代码块 {...},在这个块中重新定义了变量 b 和 c。
int b = 4, c;
新的局部变量 b 被初始化为 4,此时这个 b 和外部的 b 是不同的。
新的局部变量 c 未初始化。
c = b * 3;
计算 c = 4 * 3 = 12。
a += c;
此时 a 仍然是外部变量,a = 2 + 12 = 14。
printf("first: %d,%d,%d\n", a, b, c);
输出:a = 14,局部变量 b = 4,局部变量 c = 12。
输出结果:first: 14,4,12。
a += c;
再次对外部变量 a 进行操作,a = 14 + 12 = 26。
printf("second: %d,%d,%d\n", a, b, c);
输出:a = 26,局部变量 b = 4,局部变量 c = 12。
输出结果:second: 26,4,12。
3. 退出内部代码块后:
此时局部变量 b 和 c 作用域结束,外部的 b 和 c 恢复。
外部变量 b = 3,c = 6。
printf("third: %d,%d,%d\n", a, b, c);
输出:a = 26,外部变量 b = 3,外部变量 c = 6。
输出结果:third: 26,3,6。
解答:
first: 14,4,12
second: 26,4,12
third: 26,3,6
3、编程题
3.1、 编写程序,用getchar函数读入两个字符给变量c1、c2,然后分别用putchar函数和printf函数输出这两个字符,并思考一下以下问题
(1)变量c1、c2应定义为字符型或整型?还是二者皆可
(2)要求输出c1和c2值的ASCII码,应如何处理?用putchar函数还是printf函数?
(3)整型变量与字符型变量是否在任何情况下都可以互相替换?
代码解答:
#include <stdio.h>
int main() {
char c1, c2;
// 使用 getchar() 函数读入两个字符
c1 = getchar();
c2 = getchar();
// 用 putchar() 函数输出这两个字符
putchar(c1);
putchar('\n');
putchar(c2);
putchar('\n');
// 用 printf() 函数输出这两个字符
printf("Character 1: %c\n", c1);
printf("Character 2: %c\n", c2);
// 输出这两个字符的 ASCII 码值
printf("ASCII of c1: %d\n", c1);
printf("ASCII of c2: %d\n", c2);
return 0;
}
问题解惑:
问题1:
两者皆可
当定义为 字符型 (char) 时:变量保存的是字符本身,但实际上字符在内存中是用 ASCII 码(一个整数)表示的。
当定义为 整型 (int) 时:变量保存字符的 ASCII 码,同样可以正确工作,并且兼容 getchar() 的返回值(因为 getchar() 返回 int)。
问题2:
应使用 printf() 函数
putchar() 只输出单个字符,不直接支持输出整型或 ASCII 码值。
如果要输出 ASCII 码,需要使用 printf("%d", c1);,因为 %d 可以输出整数,字符型变量可以隐式转换为它们的 ASCII 码进行输出。
问题3:
不可以在任何情况下互相替换:
在某些情况下,整型和字符型变量可以互换(例如 char c = 65; 可以赋值一个整数给字符型,表示 ASCII 码对应的字符 'A'),但这种行为依赖于 ASCII 编码。
整型变量 可以存储更大的数值,而 字符型变量 通常只占用 1 个字节,范围一般为 -128 到 127 或 0 到 255(取决于是否为有符号类型),因此不能表示所有可能的整型数值。
在处理输入输出时,使用 char 更合适,因为我们期望处理的是字符而不是整数。
4、分析题
4.1、使列举static关键字的几个作用
解答:
隐藏
在我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,也就是说其他文件可以看到写同名的函数,如果加了static,那么其他文件就不能同名函数或者变量;(对于函数来讲,static的作用仅限隐藏)
保持变量内容的长久
Static修饰的变量会存储到静态数据区,静态块会在程序刚开始是完成初始化,也是唯一的一次初始化;
静态存储区,共有两种变量,全局变量和static变量
默认初始化为0
全局变量也具有这个属性,因为静态数据区中所有的字节默认值都是0x00
练习二
运算符
-
选择题
1.1、若有以下程序
main()
{ char a='1',b='2';
printf("%c,",b++);
printf("%d\n",b-a); }
程序运行后的输出结果是
A)3,2 B)50,2
C)2,2 D)2,50
解析:
变量初始化:
a 被赋值为字符 '1',其 ASCII 值为 49。
b 被赋值为字符 '2',其 ASCII 值为 50。
第一行输出:
printf("%c,", b++);
这行代码输出 b 当前的值(字符 '2'),然后执行 b++。所以,输出为 b 的当前值:
输出: 2,
然后 b 的值自增,b 现在变为 51(因为 b 的新值为字符 '2' 的 ASCII 值加 1,即 50 + 1)。
第二行输出:
printf("%d\n", b - a);
此时 b 的值为 51,a 的值为 49。
计算 b - a:51 - 49 = 2。
输出: 2
解答:
C
1.2、有以下程序
main()
{
int a,b,d=25;
a=d/10%9;b=a&&(-1);
printf("%d,%d\n",a,b);
}
程序运行后的输出结果是 ______________
A)6,1 B)2,1C)6,0 D)2,0
解析:
变量初始化:
d 被赋值为 25。
计算 a:
a = d / 10 % 9;
首先计算 d / 10:25 / 10 的结果为 2(整除,取整)。
然后计算 2 % 9:2 % 9 的结果是 2(因为 2 小于 9,所以余数为 2)。
所以,a = 2。
计算 b:
b = a && (-1);
这里使用了逻辑与运算符 &&。在 C 语言中,逻辑与运算符的结果只有在两个操作数都为真时才为真(即非零值)。
a 的值为 2(非零值,逻辑上为真)。
-1 也是非零值(逻辑上也为真)。
因此,a && (-1) 的结果为 1(真)。
输出结果:
printf("%d,%d\n", a, b); 输出 a 和 b 的值。
a = 2,b = 1,所以输出为 2,1
解答:
B
1.3、若整型变量a、b、c、d中的值依次为:1、4、3、2。则条件表达式a<b?a:c<d?c:d的值 __________
A)1 B)2 c)3 D)4
解析:
外层条件:a < b
1 < 4 为真,因此外层条件为真。
因此,整个表达式的值将是外层条件为真时的结果,即 a 的值。
计算结果:
外层条件为真,所以:
a < b ? a : c < d ? c : d 的结果为 a 的值,即 1。
解答:
A
1.4、若给定条件表达式(m)?(a++): (a--),则其中表达式m 。
A. 和(m= =0)等价 B. 和(m= =1)等价
C. 和(m!=0)等价 D. 和(m!=1)等价
解析:
选项 A: 和 (m == 0) 等价
当 m == 0 时,条件为假,因此执行 a--。这与原表达式不等价。
结论: 不正确。
选项 B: 和 (m == 1) 等价
当 m == 1 时,条件为真,因此执行 a++。这只适用于 m 等于 1 的情况,不能涵盖其他非零值。
结论: 不正确。
选项 C: 和 (m != 0) 等价
当 m 不等于 0 时,条件为真,执行 a++。这与原表达式相同。
这表明条件 m 的所有非零值都将导致执行 a++。
结论: 正确。
选项 D: 和 (m != 1) 等价
当 m 不等于 1 时,条件可能为真或假,取决于 m 的其他值(如 m = 2 时条件为真,但 m = 0 时条件为假)。因此,这并不等价于原条件。
结论: 不正确。
解答:
C
1.5、以下选项中,当x为大于1的奇数时,值为0的表达式____________
A. x%2==1 B. x/2 C. x%2!=0 D. x%2==0
解析:
选项 A: x % 2 == 1
对于任何奇数 x,x % 2 的结果都是 1。
因此,x % 2 == 1 为真,这个表达式的值为 1,而不是 0。
不正确。
选项 B: x / 2
这是一个整数除法操作,x 是奇数,x / 2 的结果将是一个整数。
对于任何大于 1 的奇数,x / 2 的值将是大于 0 的整数。
不正确。
选项 C: x % 2 != 0
对于任何奇数 x,x % 2 的结果都是 1,因此 x % 2 != 0 为真。
这个表达式的值也是 1,而不是 0。
不正确。
选项 D: x % 2 == 0
对于任何奇数 x,x % 2 的结果都是 1,因此 x % 2 == 0 为假。
这个表达式的值为 0。
正确
解答:
D
1.6 有如下程序段,输出结果为________
int i = 1;
int j = i++;
if( (i>j++) || (i++ == j) ) i+=j;printf(“%d\n” , i );
A. 2 B. 3 C. 4 D. 5
解析:
第一部分条件 i > j++:
i 当前为 2,j 当前为 1。
2 > 1 为真,因此 j 变为 2(因为 j++ 是后缀运算符)。
因为逻辑或 (||) 的短路特性,第二部分条件不会被计算。
执行 i += j:
此时,j 现在是 2,所以 i += j 变为 i = 2 + 2,即 i 变为 4。
解答:
C
1.7设 int a=12; 表达式a+=a-=a*=a的值是__________。
A 12 B 144 C 0 D 132
解析:
a *= a
a *= a 相当于 a = a * a。
此时,a = 12 * 12 = 144。
a -= a
接下来计算 a -= a,此时 a 的值为 144。
a -= a 相当于 a = a - a。
此时,a = 144 - 144 = 0。
a += a
然后计算 a += a,此时 a 的值为 0。
a += a 相当于 a = a + a。
此时,a = 0 + 0 = 0。
解答:
C
1.8若整型变量a、b、c、d中的值依次为:1、4、3、2。则条件表达式a>b?a:c<d?c:d的值 ___________
A)1 B)2 c)3 D)4
解析:
判断 a > b:
1 > 4 为假,所以我们将进入 : 后面的部分,即 c < d ? c : d。
判断 c < d:
3 < 2 为假,所以我们将进入 : 后面的部分,即 d。
最终结果:
因此整个表达式的值为 d 的值,即 2。
解答:
B
1.9 有以下程序
main()
{ int i=1,j=2,k=3;
if(i++==1&&(++j==3||k++==3))
printf("%d %d %d\n",i,j,k);
}
程序运行后的输出结果是 __________
A)1 2 3 B)2 3 4
C)2 2 3 D)2 3 3
解析:
条件判断
i++ == 1:
i++ 是后缀自增,首先返回 i 的值(即 1),然后 i 增加到 2。
所以 i++ == 1 的结果为 true(即 1 == 1)。
由于第一个条件为真,继续判断 (++j == 3 || k++ == 3):
计算 ++j == 3:
j 从 2 增加到 3,所以 ++j 的值为 3,++j == 3 结果为 true。
由于这是一个逻辑或 (||) 的条件,如果第一个条件为真,第二个条件就不会被计算。因此 k++ 不会被执行,k 的值仍然为 3。
输出:
现在,i = 2(因为之前自增了),j = 3(因为进行了自增),k = 3(因为 k++ 没有被执行)。
所以,printf("%d %d %d\n", i, j, k); 输出为 2 3 3。
解答:
D
2、填空题
2.1设a=12,n=5,则计算了表达式a%=(n%=2)后,a的值为______,计算了表达式a+=a-=a*=a后,a的值为______
解析:
计算 n %= 2:
n %= 2 相当于 n = n % 2,即 n = 5 % 2。
5 % 2 = 1,所以现在 n = 1。
计算 a %= n:
接下来计算 a %= n,即 a = 12 % 1。
12 % 1 = 0,所以 a 的值更新为 0。
计算表达式 a += a -= a *= a
此时的 a 和 n 的值为:
a = 0
n = 1
计算 a *= a:
a *= a 相当于 a = a * a,即 0 * 0。
所以 a = 0。
计算 a -= a:
a -= a 相当于 a = a - a,即 0 - 0。
所以 a = 0。
计算 a += a:
a += a 相当于 a = a + a,即 0 + 0。
所以 a = 0。
解答:
0 0
2.2 设x=2.5,a=7,y=4.7,则x+a%3*(int)(x+y)%2/4的值为_____。
解析:
1. 计算 (int)(x + y):
先计算 x + y:
x + y = 2.5 + 4.7 = 7.2
然后取整:
(int)(x + y) = (int)(7.2) = 7
2. 计算 a % 3:
a % 3 = 7 % 3 = 1(因为 7 除以 3 的余数是 1)
3. 计算 1 * (int)(x + y):
1 * 7 = 7
4. 计算 7 % 2:
7 % 2 = 1(因为 7 除以 2 的余数是 1)
5. 计算 1 / 4:
1 / 4 = 0.25(这是一个浮点数运算)
6. 最后,计算 x + 0.25:
x + 0.25 = 2.5 + 0.25 = 2.75
解答:
2.75
2.3 设a=2,b=3,x=3.5,y=2.5,则(float)(a+b)/2+(int)x%(int)y的值为______。
解析:
1. 计算 (a+b)(a+b):
a+b=2+3=5
2. 计算 (float)(a+b)/2(float)(a+b)/2:
(float)(5)/2=5.0/2=2.5
3. 计算 (int)x(int)x 和 (int)y(int)y:
(int)x=(int)(3.5)=3
(int)y=(int)(2.5)=2
4. 计算 (int)x%(int)y(int)x%(int)y:
3%2=1
5. 组合所有部分:
现在将上述结果相加:
2.5+1=3.5
解答:
3.5
2.4以下程序运行后的输出结果是__________
main()
{
int a,b,c
a=10;b=20;c=(a%b<1)||(a/b>1);
printf("%d %d %d\n",a,b,c);
}
解析:
算 a % b < 1:
a % b 相当于 10 % 20,结果为 10。
因此 10 < 1 为 假(0)。
计算 a / b > 1:
a / b 相当于 10 / 20,结果为 0.5(在整型运算中为 0)。
因此 0 > 1 为 假(0)。
将两个条件结合:
(a % b < 1) || (a / b > 1) 变为 假 || 假,结果为 假(0)。
printf("%d %d %d\n", a, b, c); 会输出 10 20 0。
解答:
10 20 0
2.5以下程序运行时若从键盘输入:B33<回车>.输出结果是
#include "stdio.h"
main()
{
char a;int b;
a=getchar();scanf("%d",&b);
a = a - 'A' + '0';
b = b * 2;
printf("%c %c\n",a,b);
}
解析:
a = getchar();
getchar() 读取第一个字符 'B'。
此时 a = 'B'。
scanf("%d", &b);
scanf 从输入中读取整数。由于我们输入的是 B33,scanf 会读取 33(第一个字符B会被忽略)。
此时 b = 33。
a = a - 'A' + '0';
计算 a 的值:
'B' - 'A' 结果为 1(因为 'B' 的 ASCII 值是 66,而 'A' 的 ASCII 值是 65)。
然后 1 + '0'(即 1 + 48)将得到字符 '1'。
此时 a = '1'。
b = b * 2;
将 b 的值乘以 2:
b = 33 * 2 = 66。
printf("%c %c\n", a, b);
printf 输出两个字符:
a 的值是 '1'。
b 的值是 66,对应的字符是 'B'(ASCII 值 66 对应的字符为 'B')。
输出结果为:1 B。
解答:
1 B
2.6设a、b、c均为int型变量且a=7.5, b=2,c=3.6, 则表达式a>b && c>a || a<b && !c>b 的值是 。
解析:
计算 a>b:
7>2 为 真(true,即 1)。
计算 c>a:
3>7 为 假(false,即 0)。
所以,第一部分 a>b && c>a 为:
1 && 0=0(false)。
计算 a<ba<b:
7<2 为 假(false,即 0)。
计算 !c>b!c>b:
!c表示 c 的布尔值取反,c 的值是 3(非零为真),所以 !c 为 假(false,即 0)。
所以 !c>b 为:
0>2 为 假(false,即 0)。
所以,第二部分 a<b && !c>b为:
0 && 0=0(false)。
现在将两部分结合起来:
0∣∣0=0 (假)
解答:
0
2.7设a、b、c均为int型变量且a=6, b=4,c=2, 则表达式!(a-b)+c-1 && b+c/2的值是 。
解析:
我们需要计算:
!(a−b)+c−1&&b+2c
计算 a−b:
a−b=6−4=2
计算 !(a−b):
!(2) 为 假(false,即 0),因为 2 是非零的。
计算 !(a−b)+c−1:
现在可以计算:
0+c−1=0+2−1=1
计算 b+c/2:
先计算 c/2:
c/2=1
然后计算:
b+c/2=4+1=5
组合所有部分:
现在将两部分结合起来,检查最终的逻辑运算:
1 && 5=1
解答:
1
2.8设a、b均为int型变量且a=2, b=4, 则表达式!(x=a) || (y=b) && 0的值是 。
解析:
因为&&左边为0,有因为&&两边都为1整体才为1,所以表达式整体的值为0
解答:
0
2.9设a、b、c均为int型变量且a=1, b=4,c=3, 则表达式!(a<b) || !c && 1的值是 。
解析:
计算 a<b:
1<4 为 真(true,即 1)。
计算 !(a<b):
因此 !(1<4) 为 假(false,即 0)。
4. 计算 !c:
c=3,所以 !c为 假(false,即 0),因为 3 是非零的。
5. 计算 !c && 1:
因此 0 && 1 为 假(false,即 0)。
6. 结合所有部分:
现在将两部分结合起来:
!(a < b) || (!c && 1) = 0 || 0
计算逻辑或运算:
由于左侧和右侧都是 假,最终结果为 假(false,即 0)。
解答:
0
2.10 若有条件“2<x<3或x<-10”,其对应的C语言表达式是
解答:
((2 < x) && (x < 3)) || (x < -10)
3、编程题
3.1、 编写程序,从标准输入读取字符,并把它们写到标准的输出中。除了大写字母变换成小写字母外,所有字符的输出形式与它们的输入形式相同。
代码解答:
#include <stdio.h>
int main() {
int ch; // 用于存储读取的字符
// 从标准输入读取字符,直到遇到EOF(通常是 Ctrl+D 或 Ctrl+Z)
while ((ch = getchar()) != EOF) {
// 判断是否是大写字母
if (ch >= 'A' && ch <= 'Z') {
// 转换为小写字母
ch += ('a' - 'A');
}
// 输出字符
putchar(ch);
}
return 0;
}
4、分析题
4.1、 思考一下,有两个整形变量a与b,如何在不使用第3个变量的情况下,实现a与b变量值的交换
解答:
方法一:
#include <stdio.h>
int main() {
int a = 5;
int b = 10;
// 打印交换前的值
printf("Before swapping: a = %d, b = %d\n", a, b);
// 交换
a = a + b; // 将 a 的值设置为 a + b
b = a - b; // 将 b 的值设置为原来的 a
a = a - b; // 将 a 的值设置为原来的 b
// 打印交换后的值
printf("After swapping: a = %d, b = %d\n", a, b);
return 0;
}
方法二:
#include <stdio.h>
int main() {
int a = 5;
int b = 10;
// 打印交换前的值
printf("Before swapping: a = %d, b = %d\n", a, b);
// 交换
a = a ^ b; // 将 a 的值设置为 a 和 b 的异或
b = a ^ b; // 将 b 的值设置为原来的 a
a = a ^ b; // 将 a 的值设置为原来的 b
// 打印交换后的值
printf("After swapping: a = %d, b = %d\n", a, b);
return 0;
}
练习三
分支、循环练习
-
选择题
1.1、以下程序的输出结果是________。
main()
{
int k1=1,k2=2,k3=3,x=15;
if(!k1) x--;
else if(k2)
if(k3) x=4;
else x=3;
printf(“x=%d\n”,x);
}
A x=4 B x=15 C x=14 D x=3
解析:
if (!k1):
!k1 计算为 !1,即 0(假),所以这个条件不满足,跳过这个代码块。
else if (k2):
k2 的值是 2(真),所以进入这个代码块。
在这个代码块中,继续检查 if (k3):
k3 的值是 3(真),所以执行 x = 4。
此时 x 的值从 15 改为 4。
解答:
A
1.2、有以下程序,while循环执行________次。
int main()
{
int k=2;
while(k=1)
printf(“%d”,k);
k--;
printf(“\n”);
}
A) 无限次 B) 2 C) 1 D) 0
解析:
while (k = 1) 这个条件是一个赋值,而不是比较。
这意味着 k 会被赋值为 1,并且表达式的值为 1(真)。
因此,while 循环将进入无限循环,因为 k 永远会被赋值为 1,而不是改变为 0(假)。
解答:
A
1.3、有以下程序
int main()
{
int a=1,b;
for(b=1;b<=10;b++)
{
if(a>=8) break;
if(a%2==1) { a+=5; continue;}
a-=3;
}
printf("%d\n",b);
}
程序运行后的输出结果是
A)3 B)4 C)5 D)6
解析:
初始值:
a = 1
b 从 1 开始循环
第一次循环 (b = 1):
a = 1, a % 2 == 1 为真(1 是奇数)。
执行 a += 5;,此时 a = 1 + 5 = 6。
执行 continue;,跳过后面的代码,进入下一次循环。
第二次循环 (b = 2):
a = 6, a % 2 == 1 为假(6 是偶数)。
检查 if (a >= 8) 为假。
执行 a -= 3;,此时 a = 6 - 3 = 3。
第三次循环 (b = 3):
a = 3, a % 2 == 1 为真(3 是奇数)。
执行 a += 5;,此时 a = 3 + 5 = 8。
执行 continue;,跳过后面的代码,进入下一次循环。
第四次循环 (b = 4):
a = 8, 检查 if (a >= 8) 为真。
执行 break;,退出循环。
解答:
B
1.4、有以下程序
#include <sthio.h>
int main()
{
int s=0,n;
for (n=0;n<3;n++) 0 1 2
{
switch(s)
{ case 0:
case 1:s+=1;
case 2:s+=2;break;
case 3:s+3;
case 4:s+=4;
}
printf((“%d\n”,s);
}
}
程序运行后的结果是
A)1,2,4 B) 3,10,10 C) 3,6,10 D) 3, 7, 7
解析:
第一次循环s=0
进入case=0因为没有break进入case1
s=1因为还是没有break进入case2
s=3
打印s的值
第二次循环
s=3进入case3
s+3的值不变
然后进入case4
s=7
打印s的值
第三次循环s=7不进入case
直接打印s的值
最终的值为3,7,7
解答:
D
1.5、有以下程序
#include<stdio.h>
int main()
{int a=1,b=0;
if(-a) b++;
else if(a=0)b+=2; else b+=3;
printf("%d\n",b);
)
程序运行后的输出结果是( )。
A)0 B)1 C)2 D)3
解析:
int a = 1, b = 0; 初始化变量 a 和 b。
if (-a),-a 计算为 -1,在 C 语言中,非零值都被视为真。因此条件为真,执行 b++,使 b 从 0 增加到 1。
else if 和 else 分支由于上面的条件已经为真而不会执行。
解答:
B
1.6有以下程序
#include<stdio.h>
int main()
{
int a=7;
while(a--);
printf("%d\n",a);
}
程序运行后的输出结果是( )。
A)-1 B)0 C)1 D)7
解析:
int a = 7; 初始化变量 a,值为 7。
while (a--); 这是一个空循环体。每次循环,a 的值会递减,直到 a == 0,然后循环继续,直到 a == -1,此时条件 a-- 为假,循环退出。也就是说,循环结束时 a = -1。
printf("%d\n", a); 打印的是循环结束后的 a 的值,即 -1。
输出
因此,程序运行后,a 的值为 -1。
解答:
A
2、填空题
2.1、以下程序运行结果是( )。
#include<stdio.h>
int main()
{
int x=2,y=-1,z=2;
if(x<y)
if(y<0) z=0;
else z+=1;
printf("%d\n",z);
}
解析:
int x = 2, y = -1, z = 2; 初始化 x,y 和 z。
if (x < y),即 2 < -1,这个条件为 false,因此不执行后面的 if-else 结构。
由于第一个 if 语句的条件为 false,else 部分不会被执行(注意缩进,else 是与外层的 if 配对的)。
程序跳过整个 if-else 结构,直接执行 printf("%d\n", z);,此时 z 的值仍然是初始值 2。
解答:
2
2.2以下程序的执行结果是( )。
#include<stdio.h>
int main()
{
int a,b,c,d,x;
a=c=0;
b=1;
d=19;
if(a) d=d-10;
if(!c)
x=15;
else
x=25;
d++ ;
printf("d=%d\n",d);
}
解析:
a = c = 0; 将 a 和 c 初始化为 0,b = 1;,d = 19;。
if (a):a 是 0,因此条件为 false,不执行 d = d - 10,d 依然保持 19。
if (!c):c 是 0,!c 为 true,因此 x = 15。
d++:对 d 进行自增操作,d 从 19 变为 20。
解答:
20
2.3以下程序的执行结果是( )。
#include<stdio.h>
int main()
{
int x=1,y=0;
switch(x)
{
case 1:
switch(y)
{
case 0:printf("first\n");break;
case 1:printf("second\n");break;
}
case 2:printf("third\n");
}
}
解析:
int x = 1, y = 0; 初始化了 x 和 y 的值。
外层 switch(x) 中,x = 1,因此进入 case 1。
在 case 1 内,有一个内层 switch(y),其中 y = 0,因此匹配到 case 0,输出 "first",然后通过 break 跳出内层 switch。
外层 switch 没有 break,所以会继续执行 case 2 的代码,输出 "third"。
解答:
first,third
2.4以下程序在输入5,2之后的执行结果是( )。
#include<stdio.h>
int main()
{
int s,t,a,b;
scanf("%d,%d",&a,&b);
s=1;
t=1;
if(a>0) s=s+1;
if(a>b) t=s+t;
else if(a==b)
t=5;
else
t=2*s;
printf("s=%d,t=%d\n",s,t);
}
解析:
程序首先读取输入的两个数:a = 5,b = 2。
初始化 s = 1 和 t = 1。
if (a > 0),a = 5,条件为真,因此执行 s = s + 1,此时 s = 2。
if (a > b),a = 5,b = 2,条件为真,因此执行 t = s + t,此时 t = 2 + 1 = 3。
其他条件 a == b 和 a < b 都不会被执行。
解答:
2,3
2.5以下程序的执行结果是( )。
#include<stdio.h>
int main()
{
int a=2,b=7,c=5;
switch(a>0)
{
case 1:
switch(b<0)
{
case 1:printf("@");break;
case 2:printf("!");break;
}
case 0:
switch(c==5)
{
case 0:printf("*");break;
case 1:printf("#");break;
case 2:printf("$");break;
}
default:printf("&");
}
printf("\n");
}
解析:
switch(a > 0) 中,a = 2,所以 a > 0 为真,进入 case 1。
在 case 1 中,有一个嵌套的 switch(b < 0),其中 b = 7,b < 0 为 false,没有匹配到任何 case,因此什么都不输出。
外层 switch 没有 break,因此继续执行 case 0 的代码。
在 case 0 中,switch(c == 5),其中 c = 5,所以 c == 5 为真,进入 case 1,输出 "#"。
由于外层 switch 没有 break,还会执行 default,输出 "&"。
解答:
#&
2.6 以下程序运行结果是( )。
#include <stdio.h>
int main()
{
int x,y=1;
if(y!=0) x=5;
printf("\t%d\n" ,x);
if(y==0) x=4;
else x=5;
printf("\t%d\n" ,x);
x=1;
if(y<0)
if(y>0) x=4;
else x=5;
printf("\t%d\n" ,x);
}
解析:
第一次判断 if (y != 0) 为真,x = 5,输出 5。
第二次判断 if (y == 0) 为假,进入 else 分支,x 再次被赋值为 5,输出 5。
第三次由于 if (y < 0) 为假,嵌套的条件语句都不执行,x 保持为 1,输出 1。
解答:
5
5
1
2.7 以下程序的运行结果是( )
#include<stdio.h>
int main()
{
int x , y=-2, z=0;
if ((z=y)<0) x=4;
else if (y==0)
x=5;
else
x=6;
printf("\t%d\t%d\n" ,x, z);
if(z=(y==0))
x=5;
x=4;
printf("\t%d\t%d\n" ,x,z);
if(x=z=y) x=4;
printf("\t%d\t%d\n" ,x,z);
}
解析:
第一个 if 语句,z = y = -2,z < 0 为真,因此 x = 4,输出 4 -2。
第二个 if 语句,y == 0 为假,因此 z = 0,x = 4,输出 4 0。
第三个 if 语句,x = z = y = -2,x 被赋值为 4,输出 4 -2
解答:
4 -2
4 0
4 -2
3、编程题
3.1编写程序实现:服装店经营套服,也单件出售,若买的不少于50套,每套80元;不足50套的每套90元;只买上衣每件60元;只买裤子每条45元。输入所买上衣c和裤子t的件数,计算应付款m。
代码解答:
#include <stdio.h>
int main() {
int c, t; // c: 上衣件数, t: 裤子件数
int m; // 应付款金额
// 输入上衣和裤子的数量
printf("请输入购买的上衣数量: ");
scanf("%d", &c);
printf("请输入购买的裤子数量: ");
scanf("%d", &t);
// 计算应付款
if (c + t >= 50) { // 如果总共购买的套服数量不少于50
m = (c + t) * 80; // 每套80元
} else { // 如果总共购买的套服数量不足50
m = (c + t) * 90; // 每套90元
}
// 如果只买上衣
if (t == 0 && c > 0) {
m = c * 60; // 每件上衣60元
}
// 如果只买裤子
if (c == 0 && t > 0) {
m = t * 45; // 每条裤子45元
}
// 输出应付款金额
printf("应付款金额为: %d 元\n", m);
return 0;
}
4、思考题
4.1 下面是C语言中两种if语句判断方式。请问哪种写法更好?为什么?
int n;
if (n == 10) // 第一种判断方式
if (10 == n) // 第二种判断方式
解答:
第二种,可以避免代码书写错误
4.2 思考一下,计算1+2+3+……+100的和,最优化的算法是? 编程实现
代码解答:
#include <stdio.h>
int main() {
int n = 100; // 计算的上限
int sum = n * (n + 1) / 2; // 使用公式计算1到100的和
printf("1 + 2 + 3 + ... + 100 的和是: %d\n", sum);
return 0;
}
4.3 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?
解答:
while循环:
#include <stdio.h>
int main() {
while (1) { // 条件始终为真
// 执行的代码
printf("这是一条死循环\n");
}
return 0; // 这行代码实际上不会被执行
}
for循环:
#include <stdio.h>
int main() {
for (;;) { // 不设置任何条件,形成无限循环
// 执行的代码
printf("这是一条死循环\n");
}
return 0; // 这行代码实际上不会被执行
}
do while 循环:
#include <stdio.h>
int main() {
do {
// 执行的代码
printf("这是一条死循环\n");
} while (1); // 条件始终为真
return 0; // 这行代码实际上不会被执行
}