🎈前言:
- 本专栏每篇练习将包括
5个选择题 + 2个编程题
,将涵盖C语言的不同方面,包括基础语法、数据类型、控制结构、数组、指针和函数等。通过练习,你将逐步掌握C语言的基础知识和常见问题,提高你的编程技巧和解决问题的能力。- 我希望这个博客能够为你提供有价值的练习资源,让你在实践中不断进步。同时,我们也鼓励你在练习过程中进行思考和创新,尝试使用不同的编程方法和技巧。
- 让我们一起挑战C语言练习题,攻克每一个难点,不断提升自己的编程技能!
在评论区分享你的练习心得和问题,与我们一起交流和成长。
🌴选择题
- 设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是( )
A: n=0;while(ch=getchar()!=‘\n’)n++;
B: n=0;while(getchar()!=‘\n’)n++;
C: for(n=0;getchar()!=‘\n’;n++);
D: n=0;for(ch=getchar();ch!=‘\n’;n++);
🔎正确答案:
D
【解析】:
对于for循环,其中
第一项初始化表达式只执行一次
,因此D选项中ch
只从输入流中取一个字符,之后就再不会取字符,因此会死循环。
- 运行以下程序后,如果从键盘上输入
65 14<回车>
,则输出结果为( )
int main() { int m, n; printf("Enter m,n;"); scanf("%d%d", &m, &n); while (m != n) //1 { while (m > n) m = m - n; //2 while (n > m) n = n - m; //3 } printf("m=%d\n", m); return 0; }
A: 3 B: 2 C: 1 D: 0
🔎正确答案:
C
【解析】:
此题技巧是耐心,考查
while
循环和循环嵌套的理解,初值m=65,n=14
;循环1
判断m!=n
为真,来到循环2
判断m>n
为真,执行m=m-n
;直到m=9,n=14
;循环2
结束来到循环3
判断n>m
为真,执行n=n-m
;直到m=9,n=5
;循环3
结束回到循环1
,如此往复直到m==n
时,循环结束。
- 若运行以下程序时,从键盘输入
ADescriptor<回车>
,则下面程序的运行结果是( )
#include <stdio.h> int main() { char c; int v0 = 0, v1 = 0, v2 = 0; do { switch (c = getchar()) //ADescriptor<回车> { case'a':case'A': case'e':case'E': case'i':case'I': case'o':case'O': case'u':case'U':v1 += 1; default:v0 += 1; v2 += 1; } } while (c != '\n'); printf("v0=%d,v1=%d,v2=%d\n", v0, v1, v2); return 0; }
A: v0=7,v1=4,v2=7 B: v0=8,v1=4,V2=8 C: v0=11,v1=4,v2=11 D:v0=12,v1=4,v2=12
🔎正确答案:
D
【解析】:
代码
switch
语句中没有break
,则每次找到入口进入后,顺序执行到代码块结束为止。例如当c
为'A'
时,从case 'A'
进入,先后执行v1+=1;v0+=1;v2+=1
;,而当c
为'p'
时,从default
进入,先后执行v0+=1;v2+=1;
,容易看出最终v0
和v2
是相等的。
- 如下函数是求两个
int
数字最大公约数的,指出其中存在的问题【多选】( )
int gcd(char x, char y) { int min = x < y ? x : y; for (min = 0; min > 0; min--) if (x% min = 0 && y % min = 0) return min; }
A: 参数类型不对 B: 循环变量min初值不对 C: 判断等于的符号不对 D: 返回类型不对
🔎正确答案:
ABC
【解析】:
- 函数实参是
int
,形参用char
不对,会发生截断丢失数据;min
在for
循环开始时更新为0
,不再是两个形参中的较小值;- 判断是否整除的时候误将
==
写成=
赋值运算符;- 函数最终要返回一个
int
值,返回值类型没问题,但是这里要强调一个选项中没写出的问题,如果是牛客网上的题,会报编译错误,说该函数不是在所有情况下都有返回值,只有在if
条件成立的情况下有返回值,一般在vs
上这种情况能通过,编译器会给一个默认的返回值。
- 执行下面的程序段,语句3的执行次数为( )
for (i = 0; i <= n - 1; i++) // (1) for (j = n; j > i; j--) // (2) state; // (3)
A: n(n+2)/2 B: (n-1)(n+2)/2 C: n(n+1)/2 D: (n-1)(n+2)
🔎正确答案:
C
【解析】:
外循环有
n
次,当i=0
,内循环为n
次,当i=1
,内循环为n-1
次,当i=2
时,内循环为n-2
次,以此类推,总次数为n+(n-1)+(n-2)+......+2+1
,就是个等差数列,等于n(n+1)/2
。
🌴编程题
📌错误的集合
【力扣链接:645. 错误的集合】
【题目信息】:
【答案解析】:
- 使用标记的方式就可以找出重复的数字,数组中出现过哪个数字就把对应数字作为下标在对应位置
1
,表示已经标记出现过,如果哪个数据对应位已经置1
,则表示就是重复的数字。有了重复的数字,拿[1, n]
的总和减去去掉重复数据的数组总和就是丢失的数据。 - 其实使用标记法时出现的数字对应位每次
++
,则最后出现0
次的就是丢失,出现2
次的就是重复的,这样的方式也可以,不过需要多次遍历。
int* findErrorNums(int* nums, int numsSize, int* returnSize) { *returnSize = 2; //遍历nums数组,将其中数据对应的位置1, 哪一位如果已经重置过则意味着数据重复了 int* arr = (int*)calloc(numsSize + 1, sizeof(int));//申请numsSize+1个整形空间,并初始化为0 int* ret = (int*)calloc(*returnSize, sizeof(int));//申请2个整形空间,并初始化为0 int cur_sum = 0, old_sum = 0; for (int i = 0; i < numsSize; i++) { if (arr[nums[i]] == 1) //这个数字在上边数组的对应位置已经置过1了,则重复 { ret[0] = nums[i]; //找到重复的数字 } arr[nums[i]] = 1; //将标记数组的对应数据位置1 old_sum += i + 1; // 1~n的求和 cur_sum += nums[i]; //当前数组中的数据求和(多了一个重复的,少了一个丢失的) } ret[1] = old_sum - (cur_sum - ret[0]);//原始总和,减去去掉重复后的当前总和就是丢失的数字 free(arr); //释放内存 return ret; }
【拓展】:calloc
函数
下面的实例演示了 calloc()
函数的用法。
#include <stdio.h> #include <stdlib.h> int main() { int i, n; int* a; printf("要输入的元素个数:"); scanf("%d", &n); a = (int*)calloc(n, sizeof(int)); printf("输入 %d 个数字:\n", n); for (i = 0; i < n; i++) { scanf("%d", &a[i]); } printf("输入的数字为:"); for (i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); free(a); // 释放内存 return(0); }
运行结果:
要输入的元素个数:3 输入 3 个数字: 22 55 14 输入的数字为:22 55 14
📌密码检查
【牛客网链接:OR141 密码检查】
【题目信息】:
【答案解析】:
- 这道题只需要将字符串从头到尾的每种字符(
大写字符
,小写字符
,数字
,其他字符
)分别统计出来后。然后逐个判断是否符合条件即可。而条件的判断包含有:
- 字符串密码长度不小于8
- 不能以数字开头
- 只能包含字母和数字
- 大小写和数字字符必须具备两种以上
#include <stdio.h> #include <string.h> int main() { int n; while (~scanf("%d", &n)) //多组输入 { for (int i = 0; i < n; i++) { char password[101] = { 0 }; int upper = 0, lower = 0, digit = 0, other = 0; scanf("%s", password);//捕捉输入的密码 if ( ( strlen(password) < 8 ) || (password[0] >= '0' && password[0] <= '9')) //密码长度小于8 or 密码以数字开头 { printf("NO\n"); continue; //直接跳出本次循环,执行下一次循环 } char* ptr = password; while (*ptr != '\0') //统计各种字符个数 { if (*ptr >= 'a' && *ptr <= 'z') lower++; //统计小写字母的个数 else if (*ptr >= 'A' && *ptr <= 'Z') upper++; //统计大写字母的个数 else if (*ptr >= '0' && *ptr <= '9') digit++; //统计数字的个数 else other++; //统计其他字符的个数 ptr++; } if (other > 0) // 有其他字符(注意:密码只能由数字和字母组成) { printf("NO\n"); continue; //直接跳出本次循环,执行下一次循环 } //大写,小写,数字,必须具有两种以上,而比较运算真则1,假则0 if ((upper > 0) + (lower > 0) + (digit > 0) < 2) // 密码只有一种字符 { printf("NO\n"); continue; //直接跳出本次循环,执行下一次循环 } printf("YES\n"); } } return 0; }
🔥今天的内容就到这里了,有什么问题的话欢迎大家在评论区讨论,也可以私信博主为你解答,如果觉得博主的文章还不错的话, 请👍三连支持一下博主哦🤞