

🔥个人主页:@草莓熊Lotso
🎬作者简介:C++研发方向学习者
📖个人专栏:************************************************************************************************************************************************************************************************************************************************************《C语言》《数据结构与算法》《C++知识分享》《编程工具入门指南》****************************************************************************************************************************************************************************************************************************************************************
⭐️人生格言:生活是默默的坚持,毅力是永久的享受。
前言:我们距离学习完C语言已经很久了,在数据结构学完后,博主准备通过这16天的强化训练和大家一起回顾C语言的知识,今天依旧是五道选择和两道编程题,希望大家能有所收获。
目录
选择题:
1、指出下列代码的缺陷【多选】( )
A: for(int i = 0; i < 10;)这一行写错了 B: f是float型数据直接做相等判断有风险
C: f[++i]应该是f[i++] D: 没有缺陷
cpp
float f[10];
// 假设这里有对f进行初始化的代码
for (int i = 0; i < 10;)
{
if (f[++i] == 0)
break;
}
答案解析:
正确答案: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、请指出以下程序的错误【多选】( )
A: 1 B: 2 C: 3 D: 4
cpp
int main()
{
char* str = NULL;
GetMemory(&str, 80); //2
if (NULL != str)
{
strcpy(&str, "hello"); //3
printf(str); //4
}
return 0;
}
答案解析:
正确答案:AC
第1处两种情况之一成立都是要返回的,应该用或,此处用与错误。在语句GetMemory(&str,100);中传入str的地址,在语句char*str=NULL;中str初始化为空指针,但是str指针变量也有地址,所以参数char**p里面的p保存的是指针变量str的地址,所以调用GetMemory函数之后,动态开辟的空间的地址存放在了str中,在函数返回之后没有释放内存,但是这不会导致程序错误,只会导致内存泄漏。第3处用&str是错的,应该直接用str,是刚申请下来的空间首地址,可以用来接收字符串的copy。
3、请问下列代码的输出结果有可能是哪些【多选】( )
A: 2015,810 B: 50810,201 C: 810,2015 D:`20150,810
cpp
#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;
}
答案解析:
正确答案: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、下面这个程序执行后会有什么错误或者效果【多选】( )
A: 数组越界 B: 死循环 C: 栈溢出 D: 内存泄露
答案解析:
正确答案:AB
数组下标越界:数组大小255,但是当a[255]就是256个元素,导致越界了。死循环:这个是因为无符号字符型的变量大小在0-255之间,所以说i永远不可能大于255的,是个死循环。内存泄漏:创建的临时变量,在栈中,应该会由系统自动释放,所以应该是不存在内存泄漏的问题。栈溢出:属于缓冲区溢出的一种。栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围
5、请问下列程序的输出是多少( )
A: 2 B: 死循环 C: 173 D: 172
cpp
#include<stdio.h>
int main()
{
unsigned char i = 7;
int j = 0;
for (; i > 0; i -= 3)
{
++j;
}
printf("%d\n", j);
return 0;
}
答案解析:
正确答案: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.数对
题目链接: 数对_牛客题霸_牛客网
题目描述:

题目示例:

代码演示:
cpp
#include <stdio.h>
int main() {
int n=0;
int k=0;
scanf("%d%d",&n,&k);
int count=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i%j>=k)
{
count++;
}
}
}
printf("%d ",count);
}
更优解法:
cpp
#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;
}
题目解析:
当 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));
2.截取字符串
题目链接: 截取字符串_牛客题霸_牛客网
题目描述:

题目示例:

代码演示:
cpp
#include <stdio.h>
#include <string.h>
int main() {
char s[1000]={0};
int k=0;
scanf("%s%d",s,&k);
char d[1000]={0};
strncpy(d,s,k);
printf("%s",d);
}
题目解析:
- 通过
scanf
读取字符串和截取长度k
,利用strncpy
截取字符串前k
个字符并输出,实现题目要求的字符串截取功能
往期回 顾:
【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day12
【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day13
【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day14
【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day15
结语:本篇博客就到此结束了,C 语言的精髓在于对细节的掌控和对底层的理解,这需要持续实践。愿你带着这份训练中获得的思维与习惯,在编程路上走得更稳、更远。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。