C - 指针减法

C - Pointer Subtraction

我以为我理解指针和指针算术,但后来我遇到了一些出乎我意料的事情。当我 运行 这段代码时,我以为我会看到“(header+1) - header = 32”作为输出。但我没有。有人可以向我解释为什么会这样吗?

    struct metadata *header = (struct metadata *)malloc(sizeof(struct metadata));
    printf("Struct size of : %d\n",sizeof(struct metadata));
    printf("header = %d header+1 = %d\n",header,header+1);
    printf("(header+1) - header = %d\n",(header+1) - header);

这给出了以下输出:

结构大小:32

header = 37704768 header+1 = 37704800

(header+1) - header = 1

来自standard 6.5.6

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

在这里,如果您认为它是一个单元素数组,则有两个指针 - 其中一个指向该元素,而 1 指向该元素。所以结果是 1。上面的规则显然告诉我们结果按指针指向的类型的大小放大。

也来自相同的standard 6.5.6,其中指定指针可以指向数组元素后的 1

Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1and as -((P)-((Q)+1)), and has the value zero if the expression P points one past > the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object

如果我将它们转换为 void *,我会得到 32,对吗?

是的。它将是 32(如果您使用的是 gcc)。 sizeof(void)=1(gcc 使它成为那样 - 未指定标准)但很可能其他编译器会生成错误,可以通过使用 char* 来解决。因为 sizeof char1 你可以使用 char* 铸造得到相同的结果。根据标准,这没有指定并且是非法的,因为 void 是一个不完整的类型。

最好使用 char* 强制转换来获得字节差异。