【问题标题】:K&R pointer manipulationK&R 指针操作
【发布时间】:2013-09-10 18:11:31
【问题描述】:

在 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;
}

在这个程序的早期版本中,我们不使用指针,我们可以将mid 计算为mid = (low+high)/2,但现在我们需要将mid 计算为mid = low + (high-low) / 2

我知道你不能添加指针,因为逻辑上结果没有返回任何有用的东西,但我不明白的是我们不是还在用mid = low + (high-low) / 2添加指针吗?我们将low 添加到(high-low)/2 的结果中?

【问题讨论】:

标签: c pointers pointer-arithmetic


【解决方案1】:

我发现了我对逻辑的误解。两个指针相减,结果就是这两个指针之间的距离,可以加到一个指针上。

【讨论】:

  • 您可以根据两个指针的差异确定offset。然后您可以使用另一个指针的地址作为base。通常,在使用指针(尤其是数组)时,数据存在于BASE + OFFSET。很高兴看到你从中学到了东西。
【解决方案2】:

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

更有趣的问题是为什么数学逻辑反转为:

mid = low + (high - low)/2; // Dealing with pointers

而不是:

mid = (low + high) /2; // Indexing an array using integers

快速回答:C语言禁止添加两个指针 GCC Error: Invalid operands to binary +

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

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

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

【讨论】:

  • 从技术上讲,如果您有一个包含超过 10 亿个元素的数组并且您使用无符号 32 位 int 进行索引,那么 K&R 中用于索引数组的版本也会被破坏。 googleresearch.blogspot.co.uk/2006/06/…
【解决方案3】:

一种看待这个的方法是,计算是:

 temp = ( high - low ) / 2

temp,一个整数值,是高低指针距离的一半。

 mid = low + temp

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多