【暑期每日一练】 Epilogue

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 【暑期每日一练】 Epilogue

选择题

(1)

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: 没有缺陷

答案:C

解析:

一般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)

2、请指出以下程序的错误【多选】( )

void GetMemory(char **p, int num)
{
  if(NULL == p && num <= 0)//1
    return;
  *p = (char*)malloc(num);
  return;
} 
int main()
{
  char *str = NULL;
  GetMemory(&str, 80); //2
  if(NULL != str)
  {
    strcpy(&str, "hello"); //3
    printf(str); //4
  }
  return 0;
}

A: 1 B: 2 C: 3 D: 4

答案:A、C

解析:

第1处两种情况之一成立都是要返回的,应该用或,此处用与错误。在语句GetMemory(&str,100);中传入str的地址,在语句

char*str=NULL;中str初始化为空指针,但是str指针变量也有地址,所以参数char**p里面的p保存的是指针变量str的地址,

所以调用GetMemory函数之后,动态开辟的空间的地址存放在了str中,在函数返回之后没有释放内存,但是这不会导致程序错误,只会导致内存泄漏。第3处用&str是错的,应该直接用str,是刚申请下来的空间首地址,可以用来接收字符串的copy

(3)

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

答案:A、C

解析:

对于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)

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: 内存泄露

答案:A、B

解析:

数组下标越界:数组大小255,但是当a[255]就是256个元素,导致越界了。死循环:这个是因为无符号字符型的变量大小在0-255之间,所以说i永远不可能大于255的,是个死循环。内存泄漏:创建的临时变量,在栈中,应该会由系统自动释放,所以应该是不存在内存泄漏的问题。栈溢出:属于缓冲区溢出的一种。栈溢出是由于C语言系列没有

(5)

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次

编程题

题一

描述

牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。

但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。

牛牛希望你能帮他计算一共有多少个可能的数对。

输入描述:

输入包括两个正整数n,k(1 <= n <= 10^5, 0 <= k <= n - 1)。

输出描述:

对于每个测试用例, 输出一个正整数表示可能的数对数量。

示例:

解析:

暴力破解:将 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;
}

题二

描述

输入一个字符串和一个整数 k ,截取字符串的前k个字符并输出

数据范围:字符串长度满足

1≤n≤1000 , 1≤k≤n

输入描述:

1.输入待截取的字符串

2.输入一个正整数k,代表截取的长度

输出描述:

截取后的字符串

示例:

解析:

截取字符串前 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;
}

总结

关于今日练习讲解到这儿,暑期每日一练系列也就结束了,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。也可以订阅该专栏!祝大家暑期快乐。

相关文章
|
12月前
【暑期每日一练】 day14
【暑期每日一练】 day14
|
12月前
|
存储 人工智能 C语言
【暑期每日一练】 day9
【暑期每日一练】 day9
|
12月前
【暑期每日一练】 day10
【暑期每日一练】 day10
|
12月前
|
存储 大数据 Serverless
【暑期每日一练】 day7
【暑期每日一练】 day7
|
12月前
|
Serverless C语言
【暑期每日一练】 day8
【暑期每日一练】 day8
|
12月前
|
C语言
【暑期每日一练】 day11
【暑期每日一练】 day11
|
12月前
|
存储 人工智能 安全
【暑期每日一练】 day15
【暑期每日一练】 day15
|
12月前
|
C语言
【暑期每日一练】 day6
【暑期每日一练】 day6
|
12月前
|
编译器 C语言
【暑期每日一练】 day12
【暑期每日一练】 day12
|
10月前
|
存储 算法 调度
【软考备战·希赛网每日一练】2023年4月17日
SCAN调度算法 也叫 “电梯”算法,磁头固定从外向内然后从内向外沿柱面运动。如此往复,遇到所请求的柱面时立即为其服务。 CSCAN(单向扫描)调度算法,它的磁头是单向移动的,当磁头从内向外移动到最外面时,磁头放到最内,然后再从内向外扫描。
43 0