C K&;指针操作

C K&;指针操作,c,pointers,pointer-arithmetic,C,Pointers,Pointer Arithmetic,在K&R的第6章中,我们讨论了通过指针访问结构的元素。我们得到一个函数: struct key *binsearch(char *word, struct key *tab, int n) { int cond; struct key *low = &tab[0]; struct key *high = &tab[n]; struct key *mid; while (low < high) { mid = low

在K&R的第6章中,我们讨论了通过指针访问结构的元素。我们得到一个函数:

struct key *binsearch(char *word, struct key *tab, int n)
{
    int cond;
    struct key *low = &tab[0];
    struct key *high = &tab[n];
    struct key *mid;

    while (low < high) {
        mid = low + (high-low) / 2;
        if ((cond = strcmp(word, mid->word)) < 0)
            high = mid;
        else if (cond > 0)
            low = mid + 1;
        else
            return mid;
    }
    return NULL;
}
struct key*bin搜索(char*word,struct key*tab,int n)
{
int-cond;
结构键*low=&tab[0];
结构键*高=&tab[n];
结构键*mid;
while(低<高){
中=低+(高-低)/2;
如果((cond=strcmp(word,mid->word))<0)
高=中;
否则如果(条件>0)
低=中+1;
其他的
中途返回;
}
返回NULL;
}
在这个程序的早期版本中,我们没有使用指针,我们可以将
mid
计算为
mid=(低+高)/2
,但现在我们需要将
mid
计算为
mid=low+(高-低)/2


我知道不能添加指针,因为从逻辑上讲,结果不会返回任何有用的结果,但我不明白的是,我们是否仍然添加带有
mid=low+(high-low)/2
的指针?我们正在将
low
添加到
(high-low)/2

的结果中。我发现了我在逻辑上的误解。减去两个指针时,结果是这两个指针之间的距离,可以将其添加到指针中。

示例中的指针只是指向数组,因此指针本身将按顺序编号(它们指向的每个元素之间增加4或8字节)。因此,从低位减去高位指针可以得到数组的范围(以字节为单位)。将其除以2,然后将其添加到底部,以找到中点。这基本上与通过索引数组来实现这一点相同

更有趣的问题是,为什么数学逻辑颠倒为:

mid = low + (high - low)/2; // Dealing with pointers
而不是:

mid = (low + high) /2; // Indexing an array using integers
快速回答:C语言禁止添加两个指针

详细回答: 添加(后一种方法)的问题是存在溢出数据类型最大范围的风险。对于32位计算机(尽管16位可能是编写K&R时的标准),整数和指针的最大范围分别为+/-20亿和4Gb

对于索引数组,数组不太可能有超过几百万个条目,因此即使10000000+10000000也不会导致溢出


但是,在处理指针时,不能从0开始。您将从一个大的数字开始分配一个内存块。根据操作系统和编译器的不同,尤其是在处理堆栈上的项时,添加两个指针时,完全有可能在32位范围内溢出,因此C不允许这样做,您需要减去指针。

一种方法是计算:

 temp = ( high - low ) / 2
 mid = low + temp
temp是一个整数值,是高指针和低指针之间距离的一半

 mid = low + temp
mid是低位地址加上偏移量temp。temp不是指针,而是索引量


因此,此方法不会添加两个指针。

。您可以根据两个指针的差值确定偏移量。然后,您可以使用另一个指针的地址作为
base
。通常,在使用指针(尤其是数组)时,数据存在于
BASE+OFFSET
。很高兴看到您从中学到了这一点。从技术上讲,如果您有一个包含超过10亿个元素的数组,并且您使用无符号32位int进行索引,那么K&R中用于索引数组的版本也会被破坏。
 mid = low + temp