选择题
(1)
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)
2、运行以下程序后,如果从键盘上输入 65 14<回车> ,则输出结果为( )
1. int main() 2. { 3. int m, n; 4. printf("Enter m,n;"); 5. scanf("%d%d", &m,&n); 6. while (m!=n) //1 7. { 8. while(m>n) m=m-n; //2 9. while(n>m) n=n-m; //3 10. } 11. printf("m=%d\n",m); 12. return 0; 13. }
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)
3、若运行以下程序时,从键盘输入 ADescriptor<回车> ,则下面程序的运行结果是( )
1. #include <stdio.h> 2. int main() 3. { 4. char c; 5. int v0=0,v1=0,v2=0; 6. do 7. { 8. switch(c=getchar()) 9. { 10. case'a':case'A': 11. case'e':case'E': 12. case'i':case'I': 13. case'o':case'O': 14. case'u':case'U':v1 += 1; 15. default:v0+= 1;v2+=1; 16. } 17. }while(c!='\n'); 18. printf("v0=%d,v1=%d,v2=%d\n",v0,v1,v2); 19. return 0; 20. }
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是相等的
(4)
4、如下函数是求两个int数字最大公约数的,指出其中存在的问题【多选】( )
1. int gcd(char x,char y) 2. { 3. int min = x < y ? x : y; 4. for (min = 0; min > 0; min--) 5. if (x % min = 0 && y % min = 0) 6. return min; 7. }
A: 参数类型不对 B: 循环变量min初值不对 C: 判断等于的符号不对 D: 返回类型不对
答案: A、B、C
解析
1.函数实参是int,形参用char不对,会发生截断丢失数据;
2.min在for循环开始时更新为0,不再是两个形参中的较小值;
3.判断是否整除的时候误将==写成=赋值运算符;
4.函数最终要返回一个int值,返回值类型没问题,但是这里要强调一个选项中没写出的问题,如果是牛客网上的题,会报编译错误,说该函数不是在所有情况下都有返回值,只有在if条件成立的情况下有返回值,一般在vs上这种情况能通过,编译器会给一个默认的返回值。
(5)
5、执行下面的程序段,语句3的执行次数为( )
1. for(i = 0; i <= n-1; i++) // (1) 2. for(j = n; j > i; j--) // (2) 3. 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
编程题
题一
集合 s包含从1到 n的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组nums代表了集合s发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例
解析
使用标记的方式就可以找出重复的数字,数组中出现过哪个数字就把对应数字作为下标在对应位置1,表示已经标记出现过,如果哪个数据对应位已经置1,则表示就是重复的数字。有了重复的数字,拿 [1, n] 的总和减去去掉重复数据的数组总和就是丢失的数据。 其实使用标记法时出现的数字对应位每次 ++ ,则最后出现0次的就是丢失,出现2次的就是重复的,这样的方式也可以,不过需要多次遍历。
代码实现
1. int* findErrorNums(int* nums, int numsSize, int* returnSize){ 2. *returnSize = 2; 3. //遍历nums数组,将其中数据对应的位置1, 哪一位如果已经重置过则意味着数据重复了 4. int *arr = (int *)calloc(numsSize + 1, sizeof(int));//申请numsSize个整形空间,并初始化为0 5. int *ret = (int *)calloc(*returnSize, sizeof(int));//申请2个整形空间,并初始化为0 6. int cur_sum = 0, old_sum = 0; 7. for (int i = 0; i < numsSize; i++) 8. { 9. if (arr[nums[i]] == 1) { //这个数字在上边数组的对应位置已经置过1了,则重复 10. ret[0] = nums[i];//找到重复的数字 11. } 12. arr[nums[i]] = 1; //将标记数组的对应数据位置1 13. old_sum += i + 1; // 1~n的求和 14. cur_sum += nums[i]; //当前数组中的数据求和(多了一个重复的,少了一个丢失的) 15. } 16. ret[1] = old_sum - (cur_sum - ret[0]); 17. //原始总和,减去去掉重复后的当前总和就是丢失的数字 18. free(arr); 19. return ret; 20. }
题二
描述
小明同学最近开发了一个网站,在用户注册账户的时候,需要设置账户的密码,为了加强账户的安全性,小明对密码强度有一定要求:
1. 密码只能由大写字母,小写字母,数字构成;
2. 密码不能以数字开头;
3. 密码中至少出现大写字母,小写字母和数字这三种字符类型中的两种;
4. 密码长度至少为8
现在小明受到了n个密码,他想请你写程序判断这些密码中哪些是合适的,哪些是不合法的。
输入描述:
输入一个数n,接下来有n(n≤100)行,每行一个字符串,表示一个密码,输入保证字符串中只出现大写字母,小写字母和数字,字符串长度不超过100。
输出描述:
输入n行,如果密码合法,输出YES,不合法输出NO
示例
解析
这道题只需要将字符串从头到尾的每种字符(大写字符,小写字符,数字,其他字符)分别统计出来后。然后逐个判断是否符合条件即可。而条件的判断包含有:
长度不小于8
不能以数字开头
只能包含字母和数字
大小写和字符必须具备两种以上
代码实现
1. #include <stdio.h> 2. int main() 3. { 4. int n; 5. while(~scanf("%d", &n)) { 6. for (int i = 0; i < n; i++) { 7. char password[101] = {0}; 8. int upper = 0, lower = 0, digit = 0, other = 0; 9. scanf("%s", password);//捕捉输入的密码 10. if (strlen(password) < 8) {//密码长度小于8 11. printf("NO\n"); 12. continue; 13. } if 14. (password[0] >= '0' && password[0] <= '9') {//密码以数字开头 15. printf("NO\n"); 16. continue; 17. } 18. char *ptr = password; 19. while(*ptr != '\0') { //统计各种字符个数 20. if (*ptr >= 'a' && *ptr <= 'z') lower++; 21. else if (*ptr >= 'A' && *ptr <= 'Z') upper++; 22. else if (*ptr >= '0' && *ptr <= '9') digit++; 23. else other++; 24. ptr++; 25. } if 26. (other > 0) { // 有其他字符(注意:密码只能由数字和字母组成) 27. printf("NO\n"); 28. continue; 29. } / 30. /大写,小写,数字,必须具有两种以上,而比较运算真则1,假则0 31. if ((upper>0) + (lower>0) + (digit>0) < 2) { // 密码只有一种字符 32. printf("NO\n"); 33. continue; 34. } 35. printf("YES\n"); 36. } 37. } r 38. eturn 0; 39. }
总结
关于今日练习讲解到这儿,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。