下面是苹果的通用二进制搜索代码。我不擅长比特操作等,所以这对我来说真的很难理解。我已经在下面的代码中对我理解的部分发表了评论什么是基础?这是包含值的数组吗?如果nremain是数组中尚未分析的值的数目,为什么每次迭代都要将其右移1?另外,请帮助我了解什么是forloop的第一行。所以我的猜测是p点到剩余元素的中点,但我没有得到(nremain>>1)*宽度部分。宽度是多少?用宽度乘以nremain的rightshifted-by-1版本如何设置指向中点的指针?当键>p和指针需要移动到下一个元素时,符号>0。如何通过做p+宽度来实现这一点?再说一次,知道宽度会非常有用。每次迭代结束时,我们从nremain中减去1,表示已经分析了一个元素,但在这种情况下,每次迭代nremain>>=1的意义是什么?提前谢谢!我期待着任何人的回音。void *apple_bsearch(const void *key, const void *base, size_t nmemb, size_t width, int (*compar)(const void *, const void *)) { for (size_t nremain = nmemb; nremain != 0; nremain >>= 1) { void *p = (char *)base + (nremain >> 1) * width; // I don't get this // this is comparing key & where currently p is pointing int sign = compar(key, p); if (sign == 0) { // if p and key are equal, sign is 0 return p; } if (sign > 0) { // when key > p, move right base = (char *)p + width; nremain--; } } return NULL;} 最佳答案 我会做出一定的假设(基于我所说的有根据的猜测):nmemb是数组的成员数width等于sizeof(array[0])base指向数组的第一个成员,即base == array[0]数组被排序(从最小值到最大值)注意,向右移位基本上是整数除法(它丢弃余数,例如3 >> 1 == 1)。函数接受以下参数:key,指向const void的指针base,指向const void的指针nmemb,大小变量width,大小变量compar,(指针)指向带有两个参数(2x pointer toconst void)的函数,该函数返回int使用指向void的指针允许函数对数组元素的大小不可知(因此,是泛型的)。现在我们一行一行地走。for循环初始化nremain为nmemb,循环到nremain != 0(或出现return)。循环结束时,它将nremain除以2,将结果四舍五入(右移1)。p被声明为指向void的指针,该指针在基偏移量设置为nremain的一半(要考虑的数组元素数)乘以width。因此p将指向数组左半部分的末尾。例如,如果数组中有7个元素,在第一次迭代中p将指向第4个元素。cast(char *) base只是确保添加了正确的字节数,假设width == sizeof(array[0]),因为sizeof(char) == 1。compar然后将p与key进行比较,成功时返回p。如果p < key则base设置为p指向的成员之后的下一个成员,并从nremain中减去1。这是由于Eric Postpischil:“先前对p的赋值有效地将数组分成三部分:由p指向的元素、早于此的元素和之后的元素。前面的元素数是nremain>>1,后面的元素数是p。例如,如果1是12,则零件有6、1和5个元素。从(nremain-1)>>1中减去1可确保在下一次迭代的nremain步骤中正确设置它。”重申。如果我们找不到值并退出nremain循环(注意当循环结束时nremain >>= 1 ),返回for。也许我在某些假设上是错的,所以你会想通过改变它们来计算出代码;)。希望这有帮助!关于c - 请为我解释这个二进制搜索功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58577694/
10-11 15:17