一、选择题
1、指出下列代码的缺陷【多选】( )
float f[10]; // 假设这里有对f进行初始化的代码 for(int i = 0; i < 10;) { if(f[++i] == 0) break; }
A: for(int i = 0; i < 10;)这一行写错了
B: f是float型数据直接做相等判断有风险
C: f[++i]应该是f[i++]
D: 没有缺陷
答案解析
正确答案: BC
一般 float 型只能精确到小数后六位(即 1e-6 ),将 float 型数据的绝对值与 1e-6 比较,来判断是否相等(为零)。 float 的精度误差在1e-6 ; double 精度误差在 1e-15 ;所以要判断一个 float 型数: if(fabs(f)<1e-6) ;要判断一个 double 型数:if(fabs(f)<1e-15) ;若满足,则为零。考虑 B 选项是对的。若要判断 float a,b 是否相等,要看 if(fabs(a-b)<1e- 6)是否为真。 C 选项,考虑的是数组越界问题
2、请指出以下程序的错误【多选】()
void GetMemory(char **p, int num) { if(NULL == p && num <= 0)//1 return; *p = (char*)malloc(num); return; } in t main() { char *str = NULL; GetMemory(&str, 80); //2 if(NULL != str) { strcpy(&str, "hello"); //3 printf(str); //4 } r eturn 0; }
A: 1
B: 2
C: 3
D: 4
答案解析
正确答案: AC
第 1 处两种情况之一成立都是要返回的,应该用或,此处用与错误。在语句 GetMemory(&str,100); 中传入 str 的地址,在语句char*str=NULL; 中 str 初始化为空指针,但是 str 指针变量也有地址,所以参数 char**p 里面的 p 保存的是指针变量 str 的地址,所以调用GetMemory 函数之后,动态开辟的空间的地址存放在了 str 中,在函数返回之后没有释放内存,但是这不会导致程序错误,只会导致内存泄漏。第3 处用 &str 是错的,应该直接用 str ,是刚申请下来的空间首地址,可以用来接收字符串的copy。
3、请问下列代码的输出结果有可能是哪些【多选】( )
#include <stdio.h> typedef union { int a; struct { short b; short c; }; }X; int main() { X x; x.a = 0x20150810; printf("%x,%x\n", x.b, x.c); return 0; }
A: 2015,810
B: 50810,201
C: 810,2015
D:`20150,810
答案解析
正确答案: AC
对于 0x20150810如果按照大端模式存储:从低地址到高地址:20 15 08 10 输出从低地址到高地址: 20 15 08 10 如果按照小端模式存储:从低地址到高地址:10 08 15 20 输出从高地址到低地址: 08 10 20 15 此数以int 类型赋值给联合体 x.a ,而以结构成员 b 和 c 分开访问,分别拿到低地址的 2 个字节和高地址的 2 个字节,大端下是2015和 810 ,小端下是 810 和 2015
4、下面这个程序执行后会有什么错误或者效果【多选】()
#define MAX 255 int main() { unsigned char A[MAX], i; for(i = 0; i <= MAX; i++) A[i] = i; return 0; }
A: 数组越界
B: 死循环
C: 栈溢出
D: 内存泄露
答案解析
正确答案: AB
数组下标越界:数组大小 255 ,但是当 a[255] 就是 256 个元素,导致越界了。死循环:这个是因为无符号字符型的变量大小在0-255之间,所以说 i 永远不可能大于 255 的,是个死循环。内存泄漏:创建的临时变量,在栈中,应该会由系统自动释放,所以应该是不存在内存泄漏的问题。栈溢出:属于缓冲区溢出的一种。栈溢出是由于C 语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围
5、请问下列程序的输出是多少( )
#include<stdio.h> int main() { unsigned char i = 7; int j = 0; for(;i > 0;i -= 3) { ++j; } printf("%d\n", j); return 0; }
A: 2
B: 死循环
C: 173
D: 172
答案解析
正确答案: C
本题就是找规律,计算什么时候能遇到 0
unsigned char 8 位数据位,范围在 0-255 ,所以 -2 (11111110)时,变成 254 ;同理 -1 (
11111111 )时,变成 255 ;最后减到0 时,不满足循环条件, for 停止。刚好 173 次。
7 4 1 ==> 共 (7-1)/3+1=3 次 (1-3=-2,即 254 ,继续循环)
254 251 ... 5 2 ==> 共 (254-2)/3+1=85 次(2-3=-1,即 255 ,继续循环)
255 252 ... 6 3 ==> 共 (255-5)/3+1=85 次( 3-3=0 ,退出循环) 所以总共 173 次
二、编程题
1:WY49 数对
描述
牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。
但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。
牛牛希望你能帮他计算一共有多少个可能的数对。
输入描述
输入包括两个正整数n,k(1 <= n <= 10^5, 0 <= k <= n - 1)。
输出描述
对于每个测试用例, 输出一个正整数表示可能的数对数量。
示例1
输入:5 2
输出:7
说明:满足条件的数对有(2,3),(2,4),(2,5),(3,4),(3,5),(4,5),(5,3)
【答案解析】
暴力破解:将 x 和 y 分别遍历 [1, n] ,进行判断当 x % y > k 时统计计数 count++ 即可 , 但是这样的话当 n 的值非常大的时候循环次数将非常恐怖,需要循环 n^2 次。
更优解法: 假设输入 n=10 , k=3 ;
当 y <=k 时,意味着任何数字取模 y 的结果都在 [0, k-1] 之间,都是不符合条件的。
当 y = k+1=4 时, x 符合条件的数字有 3,7
当 y = k+2=5 时, x 符合条件的数字有 3,4,8,9
当 y = k+3=6 时, x 符合条件的数字有 3,4,5,9,10
当 y = k+n 时,
x 小于 y 当前值,且符合条件的数字数量是: y-k 个,
x 大于 y 当前值,小于 2*y 的数据中,且符合条件的数字数量是: y-k 个
从上一步能看出来,在 y 的整数倍区间内, x 符合条件的数量就是 (n / y) * (y - k) 个
n / y 表示有多少个完整的 0 ~ y 区间, y - k 表示有每个区间内有多少个符合条件的数字
最后还要考虑的是 6... 往后这种超出倍数区间超过 n 的部分的统计
n % y 就是多出完整区间部分的数字个数,其中 k 以下的不用考虑,则符合条件的是 n % y - (k-1) 个
这里需要注意的是类似于 9 这种超出完整区间的数字个数 本就小于 k 的情况,则为 0
最终公式: (n / y) * (y - k) + ((n % y < k) ? 0, (n % y - k + 1));
#include <stdio.h> int main() { long n, k; while (~scanf("%ld %ld", &n, &k)) { if (k == 0) { printf("%ld\n", n * n);//任意数对的取模结果都是大于等于0的 continue; } long count = 0; for (long y = k + 1; y <= n; y++) { count += ((n / y) * (y - k)) + ((n % y < k) ? 0 : (n % y - k + 1)); } printf("%ld\n", count); } return 0; }
2:HJ46 截取字符串
描述
输入一个字符串和一个整数 k ,截取字符串的前k个字符并输出
本题输入含有多组数据
数据范围:字符串长度满足 1 \le n \le 100 \1≤n≤100 , 1 \le k \le n \1≤k≤n
输入描述
1.输入待截取的字符串
2.输入一个正整数k,代表截取的长度
输出描述
截取后的字符串
示例1
输入:
abABCcDEF
6
输出:
abABCc
示例2
输入:
ffIKEHauv
1
bdxPKBhih
6
输出:
f
bdxPKB
【答案解析】
截取字符串前 n 个字符,只需要将数组 n 下标位置的数据替换为字符串结尾标志即可
#include <stdio.h> int main() { char str[101]; while (scanf("%s", str) > 0) { int n; scanf("%d", &n); str[n] = '\0'; printf("%s\n", str); } return 0; }