
❄专栏传送门:《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.1 题目1)
[1.2 题目2](#1.2 题目2)
[1.3 题目3](#1.3 题目3)
[1.4 题目4](#1.4 题目4)
[1.5 题目5](#1.5 题目5)
[2.1 至少是其他数字两倍的最大数](#2.1 至少是其他数字两倍的最大数)
[2.1.1 题目理解](#2.1.1 题目理解)
[2.1.2 思路](#2.1.2 思路)
[2.1.3 实现](#2.1.3 实现)
[2.2 两个数组的交集](#2.2 两个数组的交集)
[2.2.1 题目理解](#2.2.1 题目理解)
[2.2.2 思路](#2.2.2 思路)
[2.2.3 报错](#2.2.3 报错)
[2.2.4 实现](#2.2.4 实现)
正文
一、五道选择题
1.1 题目1
**题干:**以下叙述中正确的是( )
A. 只能在循环体内和switch语句体内使用break语句
B. 当break出现在循环体中的switch语句体内时,其作用是跳出该switch语句体,并中止循环体的执行
C. continue语句的作用是:在执行完本次循环体中剩余语句后,中止循环
D. 在while语句和do-while语句中无法使用continue语句
解析:答案是B选项。
只有B选项"当break出现在循环体中的switch语句体内时,其作用是跳出该switch语句体,并中止循环体的执行"的叙述是正确的。
1.2 题目2
**题干:**下列 for 循环的次数为( )
cpp
for(int i = 0 ; i || i++ < 5;);
A. 0 B. 5 C. 1 D. 无限
解析:答案是D选项。
循环条件为:i || i++ < 5;
1、第一次循环 :i = 0,条件为 0 || i++ < 5;
(1)先计算 i++ < 5 : i = 0 < 5 为真,然后i自增为1;
(2)条件变为0 || 真 = 真,进入循环体(空语句)。
2、第二次循环:i = 1,条件为 1 || i++ < 5;
(1)由于 || 的短路特性,第一个操作数i = 1为真,直接判定整个条件为真;
(2)i++ < 5 不会被执行,i保持为1。
3、后续所有循环 :i 始终为1(从未自增),条件1
||
...
永远为真。
因此,这是一个无限循环。
关键点:
1、|| 运算符的短路特性:当左边为真时,右边表达式不会执行;
2、i 初始化为0后,第一次循环后变为1,之后永远为1(因为i++ < 5;不再执行);
3、条件1 || ... 永远为真。
因此我们选择D选项.无限****。
1.3 题目3
**题干:**以下描述中正确的是( )
A. 由于do-while循环中循环体语句只能是一条可执行语句,所以循环体内不能使用复合语句
B. do-while循环由do开始,用while结束,在while(表达式)后面不能写分号
C. 在do-while循环体中,不一定要有能使while后面表达式的值变为零("假")的操作
D. do-while循环中,根据情况可以省略while
解析:答案是C选项。
A错误 :do-while循环体内可以使用复合语句(即用花括号{}括起来的多条语句);
B错误 :do-while循环在while(表达式)后面必须写分号 (这是语法要求);
C正确 :do-while循环体内不一定需要有能使表达式变为假的操作,循环可能通过break、return等其他方式终止,或者根本就是无限循环;
D错误 :while是do-while循环的语法组成部分,不能省略。
正确选项是C选项。
1.4 题目4
**题干:**设函数 fun 和实参数组的说明是如下形式,则对函数的调用语句中,正确的是( )
cpp
void fun(char ch,float x[]);
float a[10];
A. fun("asd" , a[]); B. fun('x' , A); C. fun('68' , 2.8); D. fun(32 , a);
解析:答案是D选项。
**函数声明为void fun(char ch,float x[]);,需要两个参数:一个char类型,一个float数组(实际传递的是数组首地址),**我们分别来看四个选项------
**A. fun("asd" , a[]); 错误:**第一个参数应为char(不能是字符串),第二个参数不应带 [ ];
B. fun('x' , A); 错误:x' 不是合法字符 (应为单引号括起的字符),A未定义 (应为数组a) ;
C. fun('68' , 2.8); 错误:68' 不是合法字符(应为 '68' ,但多字符常量非法),第二个参数应为数组地址而非浮点数;
D. fun(32 , a); 正确:32是int类型(可自动转换为char),a是float数组名(传递首地址,符合float x[]要求)。
1.5 题目5
**题干:**在c语言中,一个函数不写返回值类型,默认的返回类型是( )
A. int B. char C. void D.都不是
解析:答案是A选项。
在C语言中,如果一个函数没有明确声明返回类型,编译器默认其返回类型为int(这是传统C语言的规定,但现代C标准建议避免这种写法,因为C99及以上标准要求明确声明类型)。因此正确答案是****A. int。
选择题答案如下:
1.1 B
1.2 D
1.3 C
1.4 D
1.5 A
校对一下,大家都做对了吗?
二、两道算法题
2.1 至少是其他数字两倍的最大数
力扣题解链接:遍历数组找到最大值的下标解决
题目描述:

2.1.1 题目理解
在一个整数数组中,找到最大值并检查它是否至少是其他所有数字的两倍。如果是,返回最大值的下标;否则返回-1。
核心要点:
(1)数组中有唯一最大值;
(2)需要验证:最大值 ≥ 2 × 其他任意数字;
(3)注意边界情况(如只有一个元素)。
这道题是接口型的,下面是C语言的模版(如果是IO型就可以不用管它们了)------

2.1.2 思路
1、首先遍历数组找到最大值的下标;
2、再次遍历数组,检查最大值是否至少是其他每个数字的两倍;
3、如果所有其他数字都满足条件,返回最大值下标;否则返回-1。
2.1.3 实现
代码演示:
cpp
//C语言
int dominantIndex(int* nums, int numsSize) {
if (numsSize == 1) return 0; // 只有一个元素时直接返回下标0
int maxIndex = 0;
// 找到最大值的下标
for (int i = 1; i < numsSize; i++) {
if (nums[i] > nums[maxIndex]) {
maxIndex = i;
}
}
// 检查最大值是否至少是其他所有数字的两倍
for (int i = 0; i < numsSize; i++) {
if (i != maxIndex && nums[maxIndex] < 2 * nums[i]) {
return -1;
}
}
return maxIndex;
}
或者说这样的写法(更加好看)------
cpp
//C语言------自己实现
int dominantIndex(int* nums, int numsSize) {
if (numsSize == 0)
{
return 0;
}
int maxIndex = 0;
//找到下标
for (int i = 1; i < numsSize; i++)
{
if (nums[i] > nums[maxIndex])
{
maxIndex = i;
}
}
//确认是否至少是其他数字两倍的最大数
for (int i = 0; i < numsSize; i++)
{
if (i != maxIndex && nums[maxIndex] < 2 * nums[i])
{
return -1;
}
}
return maxIndex;
}
时间复杂度:O(n);
空间复杂度:O(1)。
我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样------

代码演示:
cpp
//C++实现
class Solution {
public:
int dominantIndex(vector<int>& nums) {
if (nums.size() == 1) return 0;
int maxIndex = 0;
for (int i = 1; i < nums.size(); i++)
{
if (nums[i] > nums[maxIndex])
{
maxIndex = i;
}
}
for (int i = 0; i < nums.size(); i++)
{
if (i != maxIndex && nums[maxIndex] < 2 * nums[i])
{
return -1;
}
}
return maxIndex;
}
};
时间复杂度: O(logn)****,空间复杂度: O(1)****。
我们目前要写出来C++的写法是非常考验前面C++的学习情况,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!
2.2 两个数组的交集
链接:349. 两个数组的交集
力扣题解链接:使用哈希数组解决【两个数组的交集的问题】
题目描述:

2.2.1 题目理解
我们简单理解一下:题目想表达的意思就是说给定两个数组,找出它们共有的元素(交集),返回的结果中元素唯一(去重)且顺序不限。
核心要点:
(1)输出结果需要去重;
(2)不考虑输出顺序;
(3)需要高效查找(推荐使用哈希表);
(4)注意空数组情况。
示例说明:
(1)[1,2,2,1] 和 [2,2] 的交集是 [2];
(2)[4,9,5] 和 [9,4,9,8,4] 的交集是 [9,4] 或 [4,9]。
2.2.2 思路
1、使用哈希数组标记nums1中出现的数字;
2、遍历nums2,检查数字是否在nums1中出现过;
3、如果出现过且尚未添加到结果中,则添加到结果数组;
4、避免重复添加:添加后将哈希值标记为2。
2.2.3 报错
这是博主写的一个失败案例,但博主觉得还可以抢救一下,这应该也是一种思路------
cpp
//C语言实现------自己的想法:失败了
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
if (nums1Size == 0 || nums2Size == 0)
{
*returnSize = 0;
return NULL;
}
int nums3;
int i, j;
while (nums1Size <= nums2Size)
{
if (nums1 == nums2)
{
nums3 = nums1 && nums2;
}
}
}
2.2.4 实现
这道题是接口型的,下面是C语言的模版(如果是IO型就可以不用管它们了)------

代码演示:
cpp
//C语言实现------哈希表
#include<stdio.h>
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
// 创建哈希表(简单版本,假设数字范围在0-1000)
int hash[1001] = { 0 };
int* result = (int*)malloc(sizeof(int) * (nums1Size < nums2Size ? nums1Size : nums2Size));
*returnSize = 0;
// 标记nums1中出现的数字
for (int i = 0; i < nums1Size; i++)
{
hash[nums1[i]] = 1;
}
// 检查nums2中的数字是否在nums1中出现过
for (int i = 0; i < nums2Size; i++)
{
if (hash[nums2[i]] == 1)
{
result[(*returnSize)++] = nums2[i];
hash[nums2[i]] = 2; // 标记为已添加,避免重复
}
}
return result;
}
时间复杂度 :O(m+n);
空间复杂度 :O(min(m+n))。
这个用到了哈希数组的知识,我们还没有介绍过哈希,因此博主还有这样的写法,不用哈希------
cpp
//C语言------不用哈希表,用了duplicate去重(AI提供了很大帮助)
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
if (nums1Size == 0 || nums2Size == 0)
{
*returnSize = 0;
return NULL;
}
int max_sameSize = nums1Size < nums2Size ? nums1Size : nums2Size;
int* result = (int*)malloc(sizeof(int) * max_sameSize);
*returnSize = 0;
//遍历nums1
for (int i = 0; i < nums1Size; i++)
{
//去重
int duplicate = 0;
for (int j = 0; j < *returnSize; j++)
{
if (result[j] == nums1[i])
{
duplicate = 1;
break;
}
}
if (duplicate)
{
continue;
}
//检查nums2
for (int k = 0; k < nums2Size; k++)
{
if (nums1[i] == nums2[k])
{
result[(*returnSize)++] = nums1[i];
break;
}
}
}
return result;
}
时间复杂度 :O(m*n);
空间复杂度 :O(min(m+n))。
我们用到了像三目表达式、duplicate查重等等。
我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样------

代码演示:
cpp
//用C++实现
#include <vector>
#include <unordered_set>
using namespace std;
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> set1(nums1.begin(), nums1.end());
unordered_set<int> result_set;
for (int num : nums2)
{
if (set1.find(num) != set1.end())
{
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
时间复杂度:O(m+n),空间复杂度: O(min(m+n))****。
我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!
结尾
本文内容到这里就全部结束了,希望大家练习一下这几道题目,这些基础题最好完全掌握!
往期回顾:
结语: 感谢大家的阅读,记得给博主"一键四连",感谢友友们的支持和鼓励!