#ifndef INCLUDED_C_BINARYSEARCH_H #define INCLUDED_C_BINARYSEARCH_H #ifndef INCLUDED_C_TYPES_H #include #endif /*INCLUDED_C_TYPES_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /** * @brief 工业级泛型二分查找算法 (类似于标准库 bsearch) * * @param key 指向待查找目标对象的指针 * @param base 指向已排序连续数组首元素的指针 * @param num 数组中元素的总个数 * @param size 每个元素所占用的内存字节大小 (sizeof) * @param cmp 比对回调函数指针 (不能为 NULL) * @return const void* 找到时返回指向数组中匹配元素的泛型指针;未找到或参数非法时返回 NULL */ C_STATIC_FORCE_INLINE const void* c_BinarySearch(const void* key, const void* base, c_size_t num, c_size_t size, int (*cmp)(const void* key, const void* elem)) { // 边界与防御性校验 if (!key || !base || num == 0 || size == 0 || !cmp) { return NULL; } const char* array_base = (const char*)base; // 🌟【安全加固核心】:采用 c_size_t 无符号左闭右开控制流 c_size_t low = 0; c_size_t high = num; // 右边界设为 num(开区间),high 永远不需要自减,物理杜绝下溢 while (low < high) { // 🌟 注意:开区间控制条件为 low < high,而不是 <= // 采用防算术溢出的中间索引计算法 c_size_t mid = low + ((high - low) >> 1); // 计算当前 mid 元素在扁平内存中的绝对指针位置 const void* mid_elem = (const void*)(array_base + (mid * size)); // 执行用户自定义比对 int cmp_res = cmp(key, mid_elem); if (cmp_res == 0) { return mid_elem; // 精确命中,返回该元素的内存首地址 } else if (cmp_res < 0) { // 🌟【核心修正】:目标在左侧低位半区,直接收缩右开边界为 mid。 // 彻底干掉了原先“high = mid - 1”引发的 UINT64_MAX 死循环隐患! high = mid; } else { low = mid + 1; // 目标在右侧高位半区,安全单调向右靠拢 } } return NULL; // 未在已排好序的数组中检索到目标 } #endif /*INCLUDED_C_BINARYSEARCH_H*/