当前位置: 首页 > news >正文

【C语言16天强化训练】从基础入门到进阶:Day 3


🔥个人主页:艾莉丝努力练剑

❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、洛谷刷题、C/C++基础知识知识强化补充、C/C++干货分享&学习过程记录

🍉学习方向:C/C++方向

⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平

前言:距离我们学完C语言已经过去一段时间了,在学习了初阶的数据结构之后,博主还要更新的内容就是【C语言16天强化训练】,之前博主更新过一个【C语言刷题12天IO强训】的专栏,那个只是从入门到进阶的IO模式真题的训练。【C语言16天强化训练】既有IO型,也有接口型。今天依然是训练五道选择题和两道编程算法题,希望大家能够有所收获!



目录

正文

一、五道选择题

1.1  题目1

1.2  题目2

1.3  题目3

1.4  题目4

1.5  题目5

二、两道算法题

2.1  记负均正

题目理解:

2.2  旋转数组的最小数字

题目理解:

结尾


正文

一、五道选择题

1.1  题目1

题干:已知函数的原型是:int fun(char b[10], int *a); ,假设定义:char c[10];int d; ,那么正确的调用语句是( )

A. fun(c,&d);     B. fun(c,d);     C. fun(&c,&d);     D. fun(&c,d);

解析:正确的调用语句是A. fun(c,&d);。我们先分析一下函数原型int fun(char b[10], int *a);表示函数fun的第一个参数是一个字符数组(或者说字符指针),第二个参数是一个整型指针。

继续分析函数原型:

(1)第一个参数char b[10]:可以直接传递字符数组c数组名(c会退化为指针);

(2)第二个参数int *a):需要传递一个整型变量的地址,因此d应该通过&d传递其地址。

这里我们定义的是char c[10];int d;,所以关键就在于——

1.数组作为参数char c[10] 作为参数时,实际传递的是char*(d退化为指针);

2.指针参数int*a 必须传入地址(如&d),不能直接传值(如d)。

补充:

这里唯一正确的调用方式是 A. fun(c, &d);

B选项是错误的,因为它没有传递指针给 int *a

1.2  题目2

题干:请问下列表达式哪些会被编译器禁止()【多选】

int a = 248, b = 4;
int const *c = 21;
const int *d = &a;
int *const e = &b;
int const * const f = &a;

A. *c = 32;     B. *d = 43     C. e=&a     D. f=0x321f

解析:题目问的是“哪些表达式会被编译器禁止”,即哪些操作是非法(违反const规则)的。

我们注意以下几点——

(1)const 在 * 左侧(如const int* 或 int const*):指向的值不可变,指针可变

(2)const 在 * 右侧(如 int *const):指针不可变,指向的值可变

(3)const 在 * 两侧(如int const *const):指针和指向的值均不可变

所有选项(A、B、C、D)均违反const规则,全部会被编译器禁止。若题目要求“多选”,应全选

我们再深挖一下选项看看——

问:为什么D选项有两个const,分别都禁止了什么?

1、第一个const(左侧的int const或const int)

禁止的操作不能通过指针 f 修改它指向的值(即 *f 是只读的)。

举个例子:

*f = 100;  // 非法!编译器会报错,因为 *f 是常量。

作用(限制)范围:限制的是指针解引用后的值(*f),与指针本身的存储无关。

2、第二个 const(右侧的*const)

禁止的操作不能修改指针 f 本身的值(即 f 不能指向其他地址)。

举个例子:

f = &b;    // 非法!编译器会报错,因为 f 是常量指针。
f = NULL;  // 非法!

作用(限制)范围:限制的是指针变量 f 存储的地址(指针自身的值)。

总结

声明形式禁止的操作允许的操作
int const *const f1. 修改 *f(值)
2. 修改 f(指针)
1. 读取 *f
2. 读取 f(地址)

补充:两个const共同确保了指针和指向的数据都不可变。

1.3  题目3

题干:以下程序的输出结果为( )

#include <stdio.h>
int i;
void prt()
{for (i = 5; i < 8; i++)printf("%c", '*');printf("\t");
} 
int main()
{for (i = 5; i <= 8; i++)prt();return 0;
}

A. ***      B. *** *** *** ***      C. *** ***      D. * * *

解析:注意这里i是一个全局变量,i是全局变量,在ptr() 和main() 中共享。

这里 ptr() 中的 for (i = 5; i < 8; i++)会执行 3 次循环(i = 5,6,7),每次打印一个' * ',因此输出 *** 。之后打印一个制表符 \t(tab)

main()函数中,for (i = 5; i <= 8; i++)会调用 ptr()  4 次(i = 5,6,7,8)。

每次调用ptr()的时候:i 被 ptr()  的 for 循环修改为 8(循环结束后i++使 i 变为8),然后回到main() 的for循环,i++使 i 变为 9,从而终止循环。

因此,只有第一次调用 ptr() 会正常输出*** ,后续调用因为 i 的全局性导致循环条件直接不满足,因而无输出。

实际输出***(仅第一次调用有效,其余调用因 i 的值被修改而无输出),答案是A选项

注意:这里的 * 紧密相连,中间是没有空格的。

1.4  题目4

题干:下面代码段的输出是( )

int main()
{int a=3;printf("%d\n",(a+=a-=a*a));return 0;
}

A. -6      B. 12      C. 0      D. -12

解析:题目是(a+=a-=a*a),计算过程如下:

a * a → 9

a -= 9 → 3 - 9 = -6

此时 a = -6,我们把-6代入到后面的赋值操作——

a += -6 → -6 + (-6) = -12

这样一来,答案就是选项D.  -12

1.5  题目5

题干:下列不能实现死循环的是( )

A. while(1){}     B. for(;1;){}     C. do{}while(1);     D. for(;0;){}

解析:如下所示——

A. while(1){} ——

1 是恒为真条件,因此这是一个典型的死循环,故能实现死循环。

B. for(;1;){} ——

for 循环的中间条件为 1(恒为真),相当于 while(1){} ,故能实现死循环。

C. do{}while(1); ——

do{}while(1); 的条件为 1(恒真),会无限循环,故能实现死循环。

D. for(;0;){} ——

for 循环的中间条件为 0(恒为假),循环体根本不会执行,不能实现死循环。

题目问的是“不能实现死循环”的选项,因此正确答案是D选项

选择题答案如下:

1.1  A

1.2  ABCD

1.3  A

1.4  D

1.5  D

校对一下,大家都做对了吗?

二、两道算法题

2.1  记负均正

题目链接:HJ97 记负均正

题目描述:

题目理解:

我们需要统计负整数的个数并计算正整数的平均值。

这道题也是IO型的,下面是C语言的模版(IO型就不用管它们了)——

代码演示:

#define  _CRT_SECURE_NO_WARNINGS  1
//C语言
#include <stdio.h>int main() 
{int n;scanf("%d", &n);  // 读取整数个数int negative_count = 0;  // 负整数计数器int positive_count = 0;  // 正整数计数器int positive_sum = 0;    // 正整数总和for (int i = 0; i < n; i++) {int num;scanf("%d", &num);  // 读取每个整数if (num < 0) {negative_count++;  // 统计负数}else if (num > 0) {positive_count++;  // 统计正数positive_sum += num;  // 累加正数}// 0不做处理}// 输出负整数个数printf("%d ", negative_count);// 计算并输出正整数的平均值if (positive_count > 0) {double average = (double)positive_sum / positive_count;printf("%.10lf\n", average);  // 输出10位小数保证精度}else {printf("0.0\n");  // 没有正整数时输出0.0}return 0;
}

这道题也是C语言中一道比较经典的算法题目。

时间复杂度O(n)

空间复杂度O(1)

我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——

//C++实现
#include <iostream>
#include <iomanip> // 用于控制输出精度
using namespace std;int main() 
{int n;cin >> n;  // 读取整数个数int negative_count = 0;  // 负整数计数器int positive_count = 0;  // 正整数计数器int positive_sum = 0;    // 正整数总和for (int i = 0; i < n; i++) {int num;cin >> num;  // 读取每个整数if (num < 0) {negative_count++;  // 统计负数}else if (num > 0) {positive_count++;  // 统计正数positive_sum += num;  // 累加正数}// 0不做处理}// 输出负整数个数cout << negative_count << " ";// 计算并输出正整数的平均值if (positive_count > 0) {double average = static_cast<double>(positive_sum) / positive_count;// 设置输出精度为10位小数cout << fixed << setprecision(10) << average << endl;}else {cout << "0.0" << endl;  // 没有正整数时输出0.0}return 0;
}

时间复杂度:O(n),空间复杂度:O(1)

这个目前要写出来非常考验C++的学习情况,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!

2.2  旋转数组的最小数字

题目链接:JZ11 旋转数组的最小数字

题目描述:

题目理解:

我们需要在旋转后的非降序数组中找到最小数字。由于题目要求时间复杂度为O(logn),我们使用二分查找算法来实现。

这道题是接口型的,下面是C语言的模版(IO型就不用管它们了)——

代码演示:

#define  _CRT_SECURE_NO_WARNINGS  1
//C语言
/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param nums int整型一维数组* @param numsLen int nums数组长度* @return int整型*/
int minNumberInRotateArray(int* nums, int numsLen)
{if (numsLen == 0) return 0;  // 处理空数组情况int left = 0;int right = numsLen - 1;while (left < right){int mid = left + (right - left) / 2;  // 防止溢出if (nums[mid] > nums[right]){// 最小值在右半部分left = mid + 1;}else if (nums[mid] < nums[right]){// 最小值在左半部分或就是midright = mid;}else{// 当nums[mid] == nums[right]时,无法判断,缩小右边界right--;}}return nums[left];
}

这道题是C语言中一道比较经典的题目。

当然博主还有一个更加简单的解法,这个解法大家理解起来就简单了——

我们如果学习了C++也可以尝试用C++实现一下——

//C++实现
class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param nums int整型vector* @return int整型*/int minNumberInRotateArray(vector<int>& nums) {// write code hereif (nums.empty()) return 0;  // 处理空数组情况int left = 0;int right = nums.size() - 1;while (left < right) {int mid = left + (right - left) / 2;  // 防止溢出if (nums[mid] > nums[right]) {// 最小值在右半部分left = mid + 1;} else if (nums[mid] < nums[right]) {// 最小值在左半部分或就是midright = mid;} else {// 当nums[mid] == nums[right]时,无法判断,缩小右边界right--;}}return nums[left];}
};

时间复杂度O(logn)

空间复杂度O(1)

目前要写出来C++的写法是比较考验前面C++的学习情况的,当然大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!


结尾

往期回顾:

【C语言16天强化训练】从基础入门到进阶:Day 2

【C语言16天强化训练】从基础入门到进阶:Day 1

结语:感谢大家的阅读,记得给博主“一键四连”,感谢友友们的支持和鼓励!

http://www.lryc.cn/news/626114.html

相关文章:

  • Vue 2 项目中快速集成 Jest 单元测试(超详细教程)
  • 【矢量数据】1:250w中国地质图地断层数据/岩性shp数据
  • EPM240T100I5N Altera FPGA MAX II CPLD
  • 无人机/航测/三维建模领域常见的“航线规划或建模方式
  • Everything 搜索工具下载安装使用教程(附安装包)Everything
  • 在 Python 中操作 Excel 文件的高效方案 —— Aspose.Cells for Python
  • mycat分库分表实验
  • [激光原理与应用-302]:光学设计 - 光学设计的流程、过程、方法、工具
  • mlir replace
  • C#传参调用外部exe
  • 线段树结合矩阵乘法优化动态规划
  • 福彩双色球第2025095期综合分析
  • C++排序算法学习笔记
  • AC 内容审计技术
  • 智慧水务流量在线监测系统解决方案
  • 项目过程管理的重点是什么
  • linux控制其他程序使用cpu低于50%——笔记
  • LangChain RAG 简述
  • [激光原理与应用-309]:光学设计 - 什么是光学系统装配图,其用途、主要内容、格式与示例?
  • 47 C++ STL模板库16-容器8-关联容器-集合(set)多重集合(multiset)
  • PyTorch数据处理工具箱(utils.data简介)
  • 设计模式笔记_行为型_解释器模式
  • 【Spring Boot把日志记录到文件里面】
  • 疯狂星期四文案网第44天运营日记
  • GPT-5论文写作全流程提示词库
  • MAC 设置输入法
  • 为 Time 类实现构造函数,默认初始化成 23:59:55,也可以指定时间,要求使用初始化参数列表:C++代码解释
  • linux服务器rsyslog进程启动失败分析
  • Python 项目里的数据预处理工作(数据清洗步骤应用)续篇
  • 3D检测笔记:MMDetection3d环境配置