★★写在前面★★
本题库源自互联网,仅作为个人学习使用,记录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
答案解析:D中的for(ch=getchar();ch!=‘\n’;n++)循环,循环的初始值ch=getchar()只会在第一次进入循环的时候执行,之后都不会执行,因此D选项是一个死循环。
2、运行以下程序后,如果从键盘上输入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
答案解析:
将内外循环结合着一起看,如果m>n,或者m<n,那m必然不等于n
第一次循环:m=65>n=14为真,m=65-14=51; n>m为假;
第二次循环:m=51>n=14为真,m=51-14=37; n>m为假;
第三次循环:m=37>n=14为真,m=37-14=23; n>m为假;
第四次循环:m=23>n=14为真,m=23-14=9; n>m为假;
第五次循环:n=14>m=9为真,n=14-9=5;
第六次循环:m=9>n=5为真,m=9-5=4,n>m为假;
第七次循环:n=5>m=4为真,n=5-4=1;
第八次循环:m=4>n=1为真,m=4-1=3,n>m为假;
第九次循环:m=3>n=1为真,m=3-1=2,n>m为假;
第十次循环:m=2>n=1为真,m=2-1=1,n>m为假;
(m=1)!=(n=1)为假,循环结束,结果为打印1。
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=8 C: v0=11,v1=4,v2=11 D: v0=12,v1=4,v2=12
正确答案:D
答案解析:将字符ADescriptor\n分成元音和非元音两类:
元音字符:Aeio一共4个
非元音字符:Dscrptr\n一共8个
因为case语句中没有break语句,因此在遇到元音字符时要执行v1+=1;v0+=1;v2+=1;此时v0=4,v1=4,v2=4;在遇到非元音字符时,只需要要执行v0+=1;v2+=1;语句,所以v0和v2统计的是所有字符个数,v1统计元音字符个数,所以v0=12,v1=4,v2=12;
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
答案解析:
int gcd(char x,char y)
{
int min = x < y ? x : y; //正确的参数类型为(int x,int y);
for (min = 0; min > 0; min--) //循环变量min初值应该为min=x < y ? x : y;或者空语句
if (x % min = 0 && y % min = 0) //判断等于的符号应该为==
return min;
}
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
答案解析:
一是可以举例验证,请读者自行验证;
二是可以画图表示,内外循环条件判断都为真的时候,才执行state语句,因此我们可以将i看作二维数组的行,j看作列,如图:
右上角的有色矩形个数就是循环的次数,即:1+2+3+…n=(n+1)n/2;
二、编程题
1、集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另
外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
leetcode【题号:645. 错误的集合】
示例:
输入:nums = [1,2,2,4] 输入:nums = [1,1]
输出:[2,3] 输出:[1,2]
//一、自行测试,根据输入的数值输出重复出现两次的数字和缺少的数字
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 100
int main()
{
int arr[N] = {0};
int n = 0;
int i = 0;
int flag1 = 0;
int flag2 = 0;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
int* count = (int*)malloc(sizeof(int) * (n + 1));
int* mark = (int*)malloc(sizeof(int) * 2);
memset(count, 0, sizeof(int) * (n + 1));
for (i = 0; i < n; i++)
{
count[arr[i]]++;
}
for (i = 1; i <= n; i++)
{
if (flag1 && flag2)
break;
if (count[i] > 1)
{
mark[0] = i;
flag1 = 1;
}
if (count[i] ==0 )
{
mark[1] = i;
flag2 = 1;
}
}
printf("重复的数字是:%d,缺少的数字是:%d。\n", mark[0], mark[1]);
free(mark);
free(count);
return 0;
}
//二、Leetcode测试,根据输入的数值输出重复出现两次的数字和缺少的数字
int* findErrorNums(int* nums, int numsSize, int* returnSize) {
int* count = (int*)malloc(sizeof(int) * (numsSize + 1)), i, * ans = (int*)malloc(4 * 2), flag1 = 0, flag2 = 0;
memset(count, 0, sizeof(int) * (numsSize + 1));
*returnSize = 2;
for (i = 0; i < numsSize; i++)
count[nums[i]]++;
for (i = 1; i <= numsSize; i++)
{
if (flag1 && flag2)
break;
if (count[i] > 1)
{
ans[0] = i;
flag1 = 1;
}
if (count[i] == 0)
{
ans[1] = i;
flag2 = 1;
}
}
return ans;
}
代码思路:因为原数组是按照顺序排放,并且是从1开始,只有一个数字重复了一次,所以我们可以根据将数组元素作为已经初始化为0的计数数组下标,只不过这个计数数组的下标是从1开始的,因此在开辟内存空间的时候要注意要比原数组元素多开辟一个元素的空间,如果某个元素重复,则以该元素为下标的计数数组会自增1,例如原数组为arr[4]={1,2,2,4},计数数组count[5]={0,0,0,0,0},执行完一遍赋值循环语句count[arr[i]]后,count[0]仍然为0,因为原数组元素是从1开始,count[1]=1,count[2]=2,count[3]=0,count[4]=1,这下就可以判断出计数大于1的计数数组的下标为重复的那个元素,计数数为0的计数数组下标为缺少的那个元素,但这里是用遍历循环来判断的,所以找到后就可以终止循环了,我们可以用两个flag变量来控制循环的提前终止,首先赋初值两个flag为0,当两个元素都找到后,分别将两个flag赋值为1,只有当两个flag同时为1的时候,循环终止。
2、小明同学最近开发了一个网站,在用户注册账户的时候,需要设置账户的密码,为了加强账户的安全性,小明对密码强度有一定要求:
1. 密码只能由大写字母,小写字母,数字构成;
2. 密码不能以数字开头;
3. 密码中至少出现大写字母,小写字母和数字这三种字符类型中的两种;
4. 密码长度至少为8
现在小明受到了n 个密码,他想请你写程序判断这些密码中哪些是合适的,哪些是不合法的。
输入描述:输入一个数n ,接下来有n(n≤100) 行,每行一个字符串,表示一个密码,输入保证字符串中只出现大写
字母,小写字母和数字,字符串长度不超过100 。
输出描述:输入n 行,如果密码合法,输出YES ,不合法输出NO
牛客网【牛客网题号: OR141 密码检查】
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int Judge_password(char* arr,int sz)
{
char* pc = arr;
int i = 0;
int flag_upper = 0;
int flag_lower = 0;
int flag_number = 0;
//遍历数组
for (i = 0; i < sz; i++)
{
if (isdigit(arr[0]))//判断首字符是否是0
return 0;
//判断是否含有大小写字母和数字
if (isdigit(arr[i]))
flag_number = 1;
if (islower(arr[i]))
flag_lower = 1;
if (isupper(arr[i]))
flag_upper = 1;
//判断是否含有大小写字母和数字之外的字符
if (isalnum(arr[i]) == 0)
return 0;
}
//大小写字母和数字中至少包含两种
if (flag_upper + flag_lower + flag_number == 2)
return 1;
else
return 0;
}
int main()
{
char arr[100] = { 0 };
int i = 0;
int n = 0;
int sz = 0;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%s", arr);
sz = strlen(arr);
if (Judge_password(arr, sz)==1 && sz >= 8)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}