c++中如何寻找数组最大值_c++获取数组最大元素和下标【实例】

std::max_e

lement最稳妥,返回指向最大元素的迭代器,需检查是否等于end以防越界,解引用得值,减数组首地址得下标,适用于所有容器及原生数组。

std::max_element 找最大值和下标最稳妥

直接手写循环不是不行,但容易越界或漏处理空数组;std::max_element 是标准库专为此设计的工具,返回迭代器,既能取值又能算下标,且对所有容器(包括原生数组)都适用。

  • 它返回的是指向最大元素的 iterator,不是值本身,别直接赋给 int 变量
  • 对原生数组使用时,必须传入指针范围:beginend(不能只传数组名)
  • 若数组为空,返回的迭代器等于 end,解引用前必须检查
int arr[] = {3, 7, 2, 9, 1};
size_t n = sizeof(arr) / sizeof(arr[0]);
auto it = std::max_element(arr, arr + n);
if (it != arr + n) {
    int max_val = *it;
    size_t max_idx = it - arr; // 迭代器减法得下标
    std::cout << "最大值: " << max_val << ", 下标: " << max_idx << "\n";
}

原生数组用 std::max_element 必须传指针边界

很多人写成 std::max_element(arr, arr) 或漏掉 + n,结果行为未定义——因为 std::max_element 要求第二个参数是“尾后指针”,即第一个不参与比较的位置。

  • arr 是首元素地址,类型是 int*
  • arr + n 才是合法的尾后指针(哪怕 n == 0 也安全)
  • 写成 std::max_element(std::begin(arr), std::end(arr)) 更清晰,但底层仍是转成指针

手动遍历时下标变量类型要用 size_t 或带符号等价类型

int i 遍历大数组可能溢出(尤其在 64 位系统上 size_t 是 64 位,int 通常还是 32 位),编译器有时会警告 comparison between signed and unsigned

  • 推荐统一用 size_t i = 0,和 sizeof 结果类型一致
  • 如果后续要传给 STL 算法(如 vector::at()),它们的索引参数也是 size_t
  • 注意:size_t 是无符号类型,循环条件别写成 i >= 0,那会死循环
size_t max_idx = 0;
for (size_t i = 1; i < n; ++i) {
    if (arr[i] > arr[max_idx]) max_idx = i;
}
int max_val = arr[max_idx];

自定义比较逻辑时传 lambda 给 std::max_element

比如找绝对值最大的数、或按结构体某个字段比较,这时不能依赖默认 ,得显式传比较器。

  • lambda 参数类型必须和元素类型一致(如 const int& a, const int& b
  • 返回 true 表示 a 应排在 b 前面(即 a “更小”),所以找“最大绝对值”要写 abs(a)
  • 错误写法:return abs(a) > abs(b) —— 这会让算法误以为你定义的是“降序”,结果反了
auto it = std::max_element(arr, arr + n, 
    [](const int& a, const int& b) { return abs(a) < abs(b); });
if (it != arr + n) {
    std::cout << "绝对值最大: " << *it << "\n";
}

原生数组没有长度信息,sizeof(arr)/sizeof(arr[0]) 这种计算只在定义处有效;一旦数组退化为指针(比如传进函数),就彻底丢失大小——这时候必须额外传长度,或者改用 std::arraystd::vector