C语言小练习(五)
? 忘掉那些“不可能”的借口吧,去坚持一个“可能”的理由,请给时间一点时间,让开始开始,只要肯努力,总会成功的!
Day05
? 选择题
?1、如下程序的功能是( )
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
char ch[80] = "123abcdEFG*&";
int j;
puts(ch);
for (j = 0; ch[j] != ''; j++)
if (ch[j] >= 'A' && ch[j] <= 'Z')
ch[j] = ch[j] + 'e' - 'E';
puts(ch);
return 0;
}
A: 测字符数组ch的长度
B: 将数字字符串ch转换成十进制数
C: 将字符数组ch中的小写字母转换成大写
D: 将字符数组ch中的大写字母转换成小写
?答案:D
?答题思路:本题我们需要熟悉ASCII码表
以及puts()函数
的使用。
?对于ASCII码表
,如下图所示:
我们发现大写字母A的ASCII码值
为65,而a的ASCII码值
为97,
结论:小写字母的ASCII码值
比大写字母的ASCII码值
大32.
✅对于puts()函数
,通过网站查询,我们发现它可以直接打印出字符串,并自动添加一个回车。
通过下面的这一句代码,我们能够读懂它的意思就是将大写字母转变成小写字母。
if (ch[j] >= 'A' && ch[j] <= 'Z') ch[j] = ch[j] + 'e' - 'E';
✅自测运行结果如下:
?2、对于代码段,下面描述正确的是( )
t=0;
while(printf("*"))
{
t++;
if (t<3)
break;
}
A: 其中循环控制表达式与0等价 B: 其中循环控制表达式与’0’等价
C: 其中循环控制表达式是不合法的 D: 以上说法都不对
?答案:B
?答题思路:因print(“*”)函数
调用的返回值是字符串中字符的个数,即为1。所以while
后面的条件恒为真,所以循环控制表达式与'0'
是等
价的(字符'0'不是0
)。
?3、以下程序运行时,若输入 1abcedf2df<回车> 输出结果是( )
#include <stdio.h>
int main()
{
char ch;
while ((ch = getchar()) != 'n')
{
if (ch % 2 != 0 && (ch >= 'a' && ch <= 'z'))
ch = ch - 'a' + 'A';
putchar(ch);
}
printf("n");
return 0;
}
A: 1abcedf2df B: 1ABCEDF2DF C: 1AbCEdf2df D: 1aBceDF2DF
?答案:C
?答题思路:本题能够看懂那段if语句
,知道一些常见字符的ASCII码值,就能解出此题。
if (ch % 2 != 0 && (ch >= 'a' && ch <= 'z'))
ch = ch - 'a' + 'A';
?该语句表达的含义是判断该字符的
ACSII码值
是不是奇数,如果是将小写字母转为大写字母。
✅运行结果如下:
?4、下列条件语句中,功能与其他语句不同的是( )
A: if(a) printf("%dn",x); else printf("%dn",y);
B: if(a==0) printf("%dn",y); else printf("%dn",x);
C: if (a!=0) printf("%dn",x); else printf("%dn",y);
D: if(a==0) printf("%dn",x); else printf("%dn",y);
?答案:D
?答题思路:D选项与众不同,其他都是a==0
时输出y
,a!=0
时输出x
.
?5、我们知道C语言的 break 语句只能跳出离它最近的一层循环,可是有时候我们需要跳出多层循环,下列跳出多层循环的做法正确的是【多选】( )
A: 将程序写成函数用return结束函数,便可跳出循环
B: 修改外层循环条件例如
for( int i = 0 ; i < MAX1 ; i ++ )
{
for( int j = 0 ; j < MAX2 ; j ++ )
{
if( condition )
{
i = MAX1;
break;
}
}
}
C: 在外层循环设置判断条件例如
for( ; symbol != 1 && condition2 ; )
{
for( ; symbol != 1 && condition3 ; )
{
if( condition1 )
symbol = 1 ;
}
}
D: 在外层循环后面加入break例如
for( ; condition2 ; )
{
for( ; condition3 ; )
{
if( condition1 )
symbol = 1 ;
} if(
symbol == 1 )
break ;
}
?答案:ABCD
?答题思路:此题旨在整理跳出多层循环的方法,每个选项都是正确的,代码为伪代码,condition
代表逻辑表达式.
?6、以下叙述中正确的是( )
A: 只能在循环体内和switch语句体内使用break语句
B: 当break出现在循环体中的switch语句体内时,其作用是跳出该switch语句体,并中止循环体的执行
C: continue语句的作用是:在执行完本次循环体中剩余语句后,中止循环
D: 在while语句和do-while语句中无法使用continue语句
?答案:A
?答题思路:break
语句通常用在循环语句和switch
语句中。当break用于switch
语句中时,可使程序跳出switch
而执行switch
以后的语
句;当break
语句用于do-while、for、while
循环语句中时,可使程序终止循环而执行循环后面的语句,即满足条件时便跳出循环。continue
语句的作用是跳过循环体中剩余的语句而强行执行下一次循环。B、C和D三个选项中均有错误。因此A选项正确。
?7、下列 for 循环的次数为( )
for(int i = 0 ; i || i++ < 5;);
A: 0 B: 5 C: 1 D: 无限
?答案:D
?答题思路:逻辑或运算如果前表达式为真,后表达式不计算,第一次循环时i为0,执行i++
,第二次循环时i为1,是个真值,不再执行i++
,也就死循环了。
?8、以下描述中正确的是( )
A: 由于do-while循环中循环体语句只能是一条可执行语句,所以循环体内不能使用复合语句
B: do-while循环由do开始,用while结束,在while(表达式)后面不能写分号
C: 在do-while循环体中,不一定要有能使while后面表达式的值变为零(“假”)的操作
D: do-while循环中,根据情况可以省略while
?答案:C
?答题思路:do-while循环中的循环体通常都是复合语句代码块,A错误,while(表达式)后面要写分号,B错误,while不能省,D错误
?9、设函数 fun 和实参数组的说明是如下形式,则对函数的调用语句中,正确的是( )
void fun(char ch,float x[]);
float a[10];
A: fun(“asd” , a[]); B: fun(‘x’ , A); C: fun(‘68’ , 2.8); D: fun(32 , a);
?答案:D
?答题思路:A选项数组传参只需要写数组名
就行,a[]
时错误的,B选项第二个参数写成了大写,错了。C选项第二个参数是浮点数,但是fun函数
的第二参数是数组不匹配,fun函数
参数x
需要传一个数组或者float *指针
,只有D选项的形式是正确的。
?10、在c语言中,一个函数不写返回值类型,默认的返回类型是( )
A: int B: char C: void D: 都不是
?答案:D
?答题思路:一个函数不写返回值类型,默认的返回类型是int,但不提倡这么做!
?11、以下对C语言函数的有关描述中,正确的有【多选】( )
A: 在C语言中,一个函数一般由两个部分组成,它们是函数首部和函数体
B: 函数的实参和形参可以是相同的名字
C: 在main()中定义的变量都可以在其它被调函数中直接使用
D: 在C程序中,函数调用不能出现在表达式语句中
?答案:AB
?答题思路:主函数中定义的局部变量只在主函数中有效,因为主函数也是一个函数,它与其他函数是平行关系,C错误;当函数有返回值时,可以出现在表达式中,D错误
?12、在C语言中,以下正确的说法是( )
A: 实参和与其对应的形参各占用独立的存储单元
B: 实参和与其对应的形参共占用一个存储单元
C: 只有当实参和与其对应的形参同名时才共占用存储单元
D: 形参是虚拟的,不占用存储单元
?答案:A
?答题思路:在调用函数的时候,真实传递给函数的是实参,函数定义部分函数名后的参数是形参。形参和实参的名字是可以相同的,在函数调用的时候,形参是实参的一份临时拷贝,分别占用不同的内存空间,所以A正确,B错误,即使形参和实参的名字相同,也是占用不同的内存空间,所以B错误;函数如果不被调用时,函数的形参是形式上存在的,但是函数在被调用的时候,形参是要分配内存空间的,所以D错误。
?13、在上下文及头文件均正常的情况下,下列代码的输出是( )(注: print 已经声明过)
#include <stdio.h>
int main()
{
char str[] = "Geneius";
print(str);
return 0;
}
print(char* s)
{
if (*s)
{
print(++s);
printf("%c", *s);
}
}
A: suiene B: neius C: run-time error D: suieneG
?答案:A
?答题思路:代码实现了递归倒序打印字符串的功能,但是++s
使得s
的值发生了变化,回不到'G'
的位置上,故而没有打印'G'
✅运行结果如下:
?14、对于函数 void f(int x); ,下面调用正确的是( )
A: int y=f(9); B: f(9); C: f(f(9)); D: x=f();
?答案:B
?答题思路:函数f
是没有返回值的,不能给int类型
变量赋值,故A错误,同时需要一个整型参数,C中f(9)
不能作为f
的参数,也是错的,D
选项没有传参,也不能接收返回值也是错误的。
?15、给定 fun 函数如下,那么 fun(10) 的输出结果是( )
int fun(int x)
{
return (x==1) ? 1 : (x + fun(x-1));
}
A: 0 B: 10 C: 55 D: 3628800
?答案:C
?答题思路:?条件操作符:表达式1 ?表达式2:表达式3
✅唯一 一个三目操作符。
?表达式1为真,表达式2的结果为整个表达式的结果,表达式3不算.
?表达式1为假,表达式3的结果为整个表达式的结果,表达式2不算。
本题的解题流程如下:
?16、如下程序的运行结果是( )
char c[5]={'a', 'b', '', 'c', ''};
printf("%s", c);
A: ‘a’ ‘b’ B: abc C: ab c D: ab
?答案:D
?答题思路:字符串的结束标志是''
,而''的ASCII值是0
,而c[2]
被初始化为0
,就相当于是''
,故字符串打印的内容只有"ab"
.
?17、若有定义: int a[2][3]; ,以下选项中对 a 数组元素正确引用的是( )
A: a[2][0] B: a[2][3] C: a[0][3] D: a[1>2][1]
?答案:D
?答题思路:本题主要考虑数组越界访问的情况,二维数组的行和列都是从0开始的,对于a
数组来说,行下标最大是1
,列下标最大是2
,D选项中1>2表达式的值是0
,是正确的,其他选项行和列都可能存在越界,A是行越界,B是行和列都越界,C是列越界。
?18、在下面的字符数组定义中,哪一个有语法错误( )
A: char a[20]=“abcdefg”; B: char a[]=“x+y=5.”; C: char a[15]; D: char a[10]=‘5’;
?答案:D
?答题思路:D中的’5’是一个字符常量,不能给字符型数组a初始化.
?19、下列定义数组的语句中正确的是【多选】( )
A.#define size 10 char str1[size], str2[size+2];
B: char str[]; C: int num[‘10’]; D: int n=5; int a[n][n+2];
?答案:AC
?答题思路:A选项:宏替换,没问题;B选项:非法定义,一维数组必须定义数组元素个数;C选项:字符’0’,转换成十进制为48,所以该选项最终为int num[48];D选项:错误,数组定义下角标不能为变量,注:C99标准中支持了使用变量,这里不做特殊考虑。
?20、已知 i,j 都是整型变量,下列表达式中,与下标引用 X[i][j] 不等效的是【多选】( )
A: *(X[i]+j) B: *(X+i)[j] C: *(X+i+j) D: *(*(X+i)+j)
?答案:BC
?答题思路:本题考查的是二维数组的元素访问,A选项是正确的,X[i]
就是第i
行的数组名,数组名表示首元素的地址,X[i]
表示第i行的第一个元素的地址,+j
后就是第i行下标为j
的元素的地址,整体解引用就是X[i][j]
,A正确。B选项因为[]的优先级高于*,所以代码相当于**((x+i)+j)
,X+i+j后就越界了,并不代表X[i][j]
,所以错误。C选项也明显不对,X是二维数组的数组名,数组名相当于第一行的地址,X+i+j
,跳过了i+j
行,就越界了,C错误。D选项是标准的指针形式访问二位数组的一个元素。
?本题还需要注意操作符的优先级:
操作符 | 描述 | 结合性 | 是否控制求值顺序 |
---|---|---|---|
() | 聚组 | / | 否 |
() | 函数调用 | 左结合性 | 否 |
[ ] | 下标引用 | 左结合性 | 否 |
. | 访问结构成员 | 左结合性 | 否 |
-> | 访问结构指针成员 | 左结合性 | 否 |
++ | 后缀自增 | 左结合性 | 否 |
- - | 后缀自减 | 左结合性 | 否 |
! | 逻辑反 | 右结合性 | 否 |
~ | 按位取反 | 右结合性 | 否 |
+ | 单目,表示正值 | 左结合性 | 否 |
- | 单目,表示负值 | 右结合性 | 否 |
++ | 前缀自增 | 右结合性 | 否 |
- - | 前缀自减 | 右结合性 | 否 |
* | 间接访问 | 右结合性 | 否 |
& | 取地址 | 右结合性 | 否 |
sizeof | 取其长度,以字节表示 | 右结合性 | 否 |
(类型) | 类型转换 | 右结合性 | 否 |
* | 乘法 | 左结合性 | 否 |
/ | 除法 | 左结合性 | 否 |
% | 整数取模 | 左结合性 | 否 |
+ | 加法 | 左结合性 | 否 |
- | 减法 | 左结合性 | 否 |
<< | 左移位 | 左结合性 | 否 |
>> | 右移位 | 左结合性 | 否 |
> | 大于 | 左结合性 | 否 |
>= | 大于等于 | 左结合性 | 否 |
< | 小于 | 左结合性 | 否 |
<= | 小于等于 | 左结合性 | 否 |
== | 等于 | 左结合性 | 否 |
!= | 不等于 | 左结合性 | 否 |
& | 位与 | 左结合性 | 否 |
^ | 位异或 | 左结合性 | 否 |
I | 位或 | 左结合性 | |
&& | 逻辑与 | 左结合性 | 是 |
II | 逻辑或 | 左结合性 | 是 |
?: | 条件操作符 | 右结合性 | 是 |
= | 赋值 | 左结合性 | 否 |
+= | 以…加 | 右结合性 | 否 |
-= | 以…减 | 右结合性 | 否 |
*= | 以…乘 | 右结合性 | 否 |
/= | 以…除 | 右结合性 | 否 |
%= | 以…取模 | 右结合性 | 否 |
<<= | 以…左移 | 右结合性 | 否 |
>>= | 以…右移 | 右结合性 | 否 |
&= | 以…与 | 右结合性 | 否 |
^= | 以…异或 | 右结合性 | 否 |
I= | 以…或 | 右结合性 | 否 |
, | 逗号 | 左结合性 | 是 |
好啦,第五天的练习到这里就结束啦!后期会继续更新C语言的小练笔,欢迎大家持续关注、点赞和评论!❤️❤️❤️