应使用std::find配合std::begin/std::end获取下标,检查返回迭代器是否等于std::end(arr)再计算,避免解引用尾后迭代器或越界;原生数组无at()或index_of()成员函数,不可误用。

用 std::find 查数组下标,别手写循环
直接用 std::find 最省事,它返回迭代器,减去首地址就是下标。手动写 for 循环不仅容易越界,还可能漏掉 size == 0 的边界情况。
- 必须包含
<algorithm></algorithm>头文件 -
std::find找不到时返回尾迭代器,要检查是否等于std::end(arr),不能只判== nullptr或直接解引用 - 对原生数组要用
std::begin(arr)和std::end(arr),别传指针长度——arr + n容易算错
int arr[] = {10, 20, 30, 40};
int n = sizeof(arr) / sizeof(arr[0]);
auto it = std::find(std::begin(arr), std::end(arr), 30);
int idx = (it != std::end(arr)) ? it - std::begin(arr) : -1; // idx == 2数组不是 std::vector,别误用 at() 或 index_of()
C++ 原生数组没有成员函数,arr.at(i)、arr.index_of(x) 全是编译错误。有人抄 Python 或 Java 习惯,一写就报 error: 'int [4]' has no member named 'at'。
-
std::vector有at()和find(需配合std::find),但原生数组没有 - 没标准库函数叫
index_of,那是某些第三方库或自己封装的,别当 C++ 内置功能用 - 如果真要类似行为,封装一个模板函数比每次重复写 find 更安全
查不到时返回值处理不当,导致未定义行为
最常见坑:拿到 std::find 返回的迭代器后,不检查就直接减、解引用或转 int,结果程序崩溃或返回垃圾值。
- 错误写法:
int idx = it - arr;—— 没判断it == std::end(arr) - 更隐蔽的错:
if (*it == x) {...}——it可能是尾后迭代器,解引用即 UB - 整型数组里搜 0 要小心:0 是合法值,不能用 “返回 -1 表示失败” 就默认 -1 不在数据中
性能和兼容性:std::find 是线性查找,别指望自动变二分
即使数组已排序,std::find 仍是从头扫到尾。想 O(log n),得自己用 std::lower_bound,且必须确保已排序并传入比较逻辑。
立即学习“C++免费学习笔记(深入)”;
-
std::lower_bound返回第一个 ≥ 目标值的位置,要确认是否真等于目标值,不能只靠位置判断 - 未排序数组上用
lower_bound结果未定义,编译器不会报错,但运行结果不可靠 - 所有这些算法都要求迭代器支持随机访问(原生数组满足),但传给
std::list就会编译失败
C++ 数组查找本质就是迭代器运算,关键不在“怎么找”,而在“怎么安全地解释返回值”。越想省事跳过检查,越容易掉进解引用尾后迭代器或越界计算的坑里。










