C语言经典题目及解析(四)

目录

一、选择题

二、编程题


下面我们来继续练习一些C语言编程题。

一、选择题

1.设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是()

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循环,其中第一项初始化表达式只执行一次,因此 ch只从输入流中取一个字符,之后就不会再取字符,因此会死循环。

2.运行以下程序后,如果从键盘上输入 65 14<回车>  ,则输出结果是()

#include<stdio.h>

int main()
{
	int m, n;
	printf("Enter m,n;");
	scanf("%d%d", &m, &n);
	while (m != n)
	{
		while (m > n) m = m - n;
		while (n > m) n = n - m;
	}
	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时,循环结束。

3.若运行以下程序时,从键盘输入ADescriptor<回车>,则以下程序的运行结果是()

#include<stdio.h>
int main()
{
	char c;
	int v0 = 0, v1 = 0, v2 = 0;
	do
	{
		switch (c = getchar())
		{
		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=78       C: v0=1,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是相等的。

4.如下函数是求两个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

1.函数实参是int,形参用char不对,会发生截断丢失数据;2.min在for循环开始时更新为0,不再是两个形参中的较小值;3.判断是否整除的时候误将==写成=赋值运算符;4.函数最终要返回一个int值,返回值类型没问题,但是这里要强调一个选项中没写出的问题,如果是牛客网上的题,会报编译错误,说该函数不是在所有情况下都有返回值,只有在if条件成立的情
况下有返回值,一般在vs上这种情况能通过,编译器会给一个默认的返回值。

5.执行下面的程序段,语句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

二、编程题

1.leetcode题目    错误的集合

https://leetcode.cn/problems/set-mismatch/https://leetcode.cn/problems/set-mismatch/

答案及解析

使用标记的方式就可以找出重复的数字,数组中出现过哪个数字就把对应数字作为下标在对应位置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个整形空间,并初始化为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];//找到重复的数字
}
cur
arr[nums[i]] = 1; //将标记数组的对应数据位置1
old_sum += i + 1; // 1~n的求和
_
sum += nums[i]; //当前数组中的数据求和(多了一个重复的,少了一个丢失的)
}
ret[1] = old_sum - (cur
_
sum - ret[0]);//原始总和,减去去掉重复后的当前总和就是丢失的数字
free(arr);
return ret;

2.牛客网题目     密码检查

https://www.nowcoder.com/share/jump/1757729532837https://www.nowcoder.com/share/jump/1757729532837

答案及解析

这道题只需要将字符串从头到尾的每种字符(大写字符,小写字符,数字,其他字符)分别统计出来后。然后逐个判断是否符合条件即可。而条件的判断包含有:
长度不小于8
不能以数字开头
只能包含字母和数字
大小写和字符必须具备两种以上

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // 添加strlen头文件

int main()
{
    int n;
    while (scanf("%d", &n) == 1) { // 修复while循环条件
        for (int i = 0; i < n; i++) {
            char password[101] = { 0 };
            int upper = 0, lower = 0, digit = 0, other = 0;
            scanf("%100s", password); // 限制输入长度为100字符
            if (strlen(password) < 8) {
                printf("NO\n"); // 修正拼写错误
                continue;
            }
            if (password[0] >= '0' && password[0] <= '9') {
                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;
            }
            if ((upper > 0) + (lower > 0) + (digit > 0) < 2) {
                printf("NO\n");
                continue;
            }
            printf("YES\n");
        }
    }
    return 0;
}

本期C语言编程题就分享到这里,我们下期再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值