详细介绍:C++基础知识编程第十六课

C++ 编程第十六课:一维数组可拓展知识点(找最值、排序与查找)


课程导航

  1. 为什么要学数组拓展操作? (从 “基础遍历” 到 “实用处理” 的升级)
  1. 数组找最值:找出最大 / 最小值 (核心逻辑与实战案例)
  1. 数组简单排序:冒泡排序与选择排序 (入门级排序算法,易懂好上手)
  1. 数组按值查找:找到元素对应的下标 (精确查找与模糊判断)
  1. 综合案例:结合多操作处理数组数据 (解决复杂实际问题)
  1. ⚠️ 拓展操作常见错误 (避坑指南,避免逻辑漏洞)
  1. 下节预告:do-while 循环详解(先执行后判断的循环新方式)

1. 为什么要学数组拓展操作?—— 从 “能用” 到 “好用”

之前我们学会了数组的遍历和动态赋值,能实现 “存储数据” 和 “逐个访问数据”,但实际场景中,我们需要对数组数据做更多 “深度处理”:

  • 统计学生成绩时,需要 “找出最高分” 来确定满分人数;
  • 整理商品价格时,需要 “按价格从低到高排序”,方便用户查看;
  • 管理员工编号时,需要 “根据编号查找对应员工的信息”。

这些场景都需要数组的 “拓展操作”—— 找最值、排序、查找。学会这些操作,才能让数组从 “单纯的存储容器” 变成 “能解决实际问题的工具”,真正发挥数组的价值。


2. 数组找最值:找出最大 / 最小值

数组找最值的核心逻辑是 “假设一个初始最值,再遍历数组逐个对比更新”,就像 “选班长时,先暂定一个候选人,再和其他人对比,更优秀的人成为新候选人”。

(1)核心步骤(以找最大值为例)

  1. 假设初始最大值:把数组第一个元素(arr[0])当作初始最大值(maxVal);
  1. 遍历数组对比:从第二个元素(arr[1])开始,逐个和maxVal对比;
  1. 更新最大值:如果当前元素比maxVal大,就把maxVal更新为当前元素;
  1. 遍历结束:maxVal就是数组的最大值。

找最小值的逻辑完全相同,只是初始值设为arr[0],对比时找 “更小的元素”。

(2)代码实现:找数组的最大值和最小值

需求:定义一个 int 数组,找出数组中的最大值和最小值,并输出。

#include 
using namespace std;
int main() {
    int numbers[] = {15, 7, 22, 9, 30, 5};
    int length = sizeof(numbers) / sizeof(int);
    // 1. 假设初始最值(数组第一个元素)
    int maxVal = numbers[0];
    int minVal = numbers[0];
    // 2. 遍历数组(从第二个元素开始,下标1)
    for (int i = 1; i < length; i++) {
        // 更新最大值
        if (numbers[i] > maxVal) {
            maxVal = numbers[i];
        }
        // 更新最小值
        if (numbers[i] < minVal) {
            minVal = numbers[i];
        }
    }
    // 3. 输出结果
    cout << "数组中的最大值:" << maxVal << endl; // 输出30
    cout << "数组中的最小值:" << minVal << endl; // 输出5
    return 0;
    }

(3)实战案例:结合动态赋值找最值

需求:让用户输入 8 个整数,动态存入数组后,找出其中的最大值。

#include 
using namespace std;
int main() {
    const int SIZE = 8;
    int arr[SIZE];
    // 1. 动态赋值:用户输入8个整数
    cout << "请输入8个整数:" << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << "第" << (i + 1) << "个整数:";
        cin >> arr[i];
    }
    // 2. 找最大值
    int maxVal = arr[0];
    for (int i = 1; i < SIZE; i++) {
        if (arr[i] > maxVal) {
        maxVal = arr[i];
        }
    }
    cout << "你输入的8个整数中,最大值是:" << maxVal << endl;
    return 0;
}

运行场景:

请输入8个整数:

第1个整数:12

第2个整数:45

第3个整数:23

第4个整数:56

第5个整数:7

第6个整数:34

第7个整数:67

第8个整数:28

你输入的8个整数中,最大值是:67


3. ⚡ 数组简单排序:冒泡排序与选择排序

排序是 “将数组元素按一定顺序(从小到大 / 从大到小)重新排列”,是数组最常用的操作之一。这里我们讲解两种入门级排序算法:冒泡排序和选择排序,逻辑简单,适合新手掌握。

(1)冒泡排序:“相邻元素对比,大的往后沉”

核心逻辑:像 “水泡从水底往上冒” 一样,每次遍历数组时,让相邻的两个元素对比,把较大的元素 “往后推”,遍历多次后,最大的元素会逐渐 “沉” 到数组末尾,最终实现排序。

代码实现:冒泡排序(从小到大)
#include 
using namespace std;
int main() {
    int scores[] = {85, 72, 93, 68, 98, 88};
    int length = sizeof(scores) / sizeof(int);
    // 冒泡排序核心:外层循环控制“排序轮次”,内层循环控制“每轮对比次数”
    for (int i = 0; i < length - 1; i++) { // 轮次:length个元素需要length-1轮
        for (int j = 0; j < length - 1 - i; j++) { // 每轮对比次数:轮次越多,对比次数越少
            // 相邻元素对比,前大后小则交换(从小到大排序)
                if (scores[j] > scores[j + 1]) {
                // 交换两个元素的值(用临时变量temp过渡)
                    int temp = scores[j];
                    scores[j] = scores[j + 1];
                    scores[j + 1] = temp;
                }
        }
    }
    // 输出排序后的数组
    cout << "冒泡排序后(从小到大):";
    for (int i = 0; i < length; i++) {
        cout << scores[i] << " ";
    }
    return 0;
}

运行结果:

冒泡排序后(从小到大):68 72 85 88 93 98

(2)选择排序:“找最小元素,放到最前面”

核心逻辑:每次遍历数组时,找到 “未排序部分的最小值”,把它和 “未排序部分的第一个元素” 交换,逐渐将最小值 “选” 到数组前面,最终实现排序。

代码实现:选择排序(从小到大)
#include 
using namespace std;
int main() {
    int prices[] = {29, 58, 15, 36, 42};
    int length = sizeof(prices) / sizeof(int);
    // 选择排序核心:外层循环控制“未排序部分的起始位置”
    for (int i = 0; i < length - 1; i++) {
        // 1. 假设未排序部分的第一个元素是最小值,记录其下标
        int minIndex = i;
        // 2. 遍历未排序部分,找到真正的最小值下标
        for (int j = i + 1; j < length; j++) {
            if (prices[j] < prices[minIndex]) {
                minIndex = j; // 更新最小值下标
            }
        }
        // 3. 把最小值和未排序部分的第一个元素交换
        if (minIndex != i) { // 最小值不是当前元素时才交换
            int temp = prices[i];
            prices[i] = prices[minIndex];
            prices[minIndex] = temp;
        }
    }
    // 输出排序后的数组
    cout << "选择排序后(从小到大):";
    for (int i = 0; i < length; i++) {
        cout << prices[i] << " ";
    }
    return 0;
}

运行结果:

选择排序后(从小到大):15 29 36 42 58


4. 数组按值查找:找到元素对应的下标

按值查找是 “根据给定的目标值,在数组中找到对应的元素,并返回它的下标”,就像 “根据名字在通讯录中找电话号码”。如果数组中有多个相同的目标值,通常返回 “第一个匹配元素的下标”。

(1)核心步骤

  1. 遍历数组:逐个访问数组元素;
  1. 对比目标值:判断当前元素是否等于目标值;
  1. 返回下标:找到匹配元素,立即返回其下标;
  1. 查找失败:遍历结束仍未找到,返回一个特殊值(比如 - 1,表示 “不存在”)。

(2)代码实现:按值查找元素下标

需求:定义一个 int 数组,让用户输入目标值,查找该值在数组中的下标(若不存在,提示 “未找到”)。

#include 
using namespace std;
int main() {
    int ids[] = {101, 102, 103, 104, 105};
    int length = sizeof(ids) / sizeof(int);
    int target, index = -1; // index初始为-1(表示未找到)
    // 1. 用户输入目标值
    cout << "请输入要查找的员工编号:";
    cin >> target;
    // 2. 遍历数组查找目标值
    for (int i = 0; i < length; i++) {
        if (ids[i] == target) {
            index = i; // 找到目标值,记录下标
            break; // 找到后立即退出循环,提高效率
        }
    }
    // 3. 输出查找结果
    if (index != -1) {
        cout << "找到目标值 " << target << ",对应的下标是:" << index << endl;
     } else {
        cout << "未找到目标值 " << target << endl;
    }
    return 0;
}

运行场景 1(找到目标值):

请输入要查找的员工编号:103

找到目标值 103,对应的下标是:2

运行场景 2(未找到目标值):

请输入要查找的员工编号:106

未找到目标值 106


5. 综合案例:数组多操作结合(动态赋值 + 排序 + 找最值)

需求:让用户输入 6 个学生的英语成绩,动态存入数组后,先按从高到低排序,再找出最高分和最低分,最后输出排序后的成绩、最高分和最低分。

#include 
using namespace std;
int main() {
    const int STUDENT_NUM = 6;
    int scores[STUDENT_NUM];
    // 1. 动态赋值:用户输入6个成绩
    cout << "请输入6个学生的英语成绩:" << endl;
    for (int i = 0; i < STUDENT_NUM; i++) {
        cout << "第" << (i + 1) << "个学生成绩:";
        cin >> scores[i];
    }
    // 2. 冒泡排序(从高到低)
    for (int i = 0; i < STUDENT_NUM - 1; i++) {
        for (int j = 0; j < STUDENT_NUM - 1 - i; j++) {
            if (scores[j] < scores[j + 1]) { // 前小后大则交换(从高到低)
                int temp = scores[j];
                scores[j] = scores[j + 1];
                scores[j + 1] = temp;
            }
        }
    }
    // 3. 找最高分和最低分(排序后,第一个元素是最高分,最后一个是最低分)
    int maxScore = scores[0];
    int minScore = scores[STUDENT_NUM - 1];
    // 4. 输出结果
    cout << "\n排序后的成绩(从高到低):";
    for (int i = 0; i < STUDENT_NUM; i++) {
            cout << scores[i] << " ";
    }
    cout << "\n最高分:" << maxScore << endl;
    cout << "最低分:" << minScore << endl;
    return 0;
}

运行结果:

请输入6个学生的英语成绩:

第1个学生成绩:82

第2个学生成绩:95

第3个学生成绩:78

第4个学生成绩:100

第5个学生成绩:88

第6个学生成绩:92

排序后的成绩(从高到低):100 95 92 88 82 78

最高分:100

最低分:78


6. ⚠️ 拓展操作常见错误

错误 1:找最值时,初始值设为 0(而非数组第一个元素)

如果数组中所有元素都是负数(比如{-5, -3, -8}),初始值设为 0 会导致最大值判断错误:

// 错误:初始值设为0,数组全为负数时,0会被当作最大值
int maxVal = 0;
for (int i = 0; i < length; i++) {
    if (arr[i] > maxVal) maxVal = arr[i]; // 最终maxVal=0,而非-3
}

✅ 正确:初始值必须设为数组第一个元素(arr[0]),确保覆盖所有元素情况。

错误 2:冒泡排序时,内层循环条件写错(未减去轮次 i)

// 错误:内层循环条件未减i,导致已排序的元素重复对比
for (int j = 0; j < length - 1; j++) {
    // 最后i轮的元素已排序,无需再对比,会浪费效率甚至出错
}

✅ 正确:内层循环条件写j < length - 1 - i,每轮减少对比次数。

错误 3:查找元素时,未处理 “多个相同元素” 的情况

如果数组中有多个相同的目标值(比如{10, 20, 10, 30}),默认只返回第一个匹配元素的下标,若需要返回所有下标,需删除break:

// 查找所有相同元素的下标
for (int i = 0; i < length; i++) {
    if (arr[i] == target) {
        cout << "找到目标值,下标:" << i << endl; // 不break,继续查找
    }
}

7. 下节预告:do-while 循环详解(先执行后判断的循环新方式)

本节课我们掌握了数组的找最值、排序和查找操作,能灵活处理数组数据了。接下来,我们要学习一种新的循环结构 ——do-while 循环

它和之前学的 while 循环最大的区别是:while 循环 “先判断后执行”,可能一次都不执行;而 do-while 循环 “先执行后判断”,至少执行一次。这种特性特别适合 “需要先做一次操作,再判断是否继续” 的场景:

  • 游戏场景:“先让玩家玩一局游戏,再询问是否继续玩”;
  • 输入验证:“先让用户输入密码,再判断密码是否正确,不正确则重新输入”。

下节课我们会学习:

  1. do-while 循环的语法结构与执行原理;
  1. do-while 与 while 循环的区别(什么时候该用 do-while);
  1. do-while 循环的实战案例(输入验证、简单游戏循环)。

学会 do-while 循环后,你能应对更多 “必须先执行一次” 的场景,让循环

posted @ 2025-12-19 13:21  yangykaifa  阅读(11)  评论(0)    收藏  举报