C - 指针减法

时间:2017-12-31 16:12:10

标签: c pointers pointer-arithmetic

我认为我理解指针和指针算术,但后来我遇到了意想不到的事情。当我运行这段代码时,我以为我会看到"(标题+ 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

(标题+ 1) - 标题= 1

1 个答案:

答案 0 :(得分:1)

来自 standard 6.5.6

  

当减去两个指针时,两个指针都应该指向   相同的数组对象,或者超过数组对象的最后一个元素;   结果是两个数组下标的差异   元素

这里如果你认为它是一个单元素数组,那么两个指针 - 其中一个指向该元素,1指向元素。因此,结果为1.上述规则显然告诉我们,结果按指针所指向的类型的大小进行了扩展。

同样来自同一standard 6.5.6,其中指定1超过数组元素指针可以指向

  

此外,如果表达式P指向一个元素   数组对象或一个超过数组对象的最后一个元素,以及   expression Q指向同一个数组对象的最后一个元素,   表达式((Q)+1)-(P)具有与((Q) - (P))+ 1 相同的值    - ((P) - ((Q)+1)),如果表达式P指出一个过去的值,则其值为零。数组对象的最后一个元素,即使是   expression(Q)+1不指向数组对象的元素

如果我把它们变成无效*,我会得到32对吗?

是。它将是32(如果您使用的是gcc)。 sizeof(void)=1(gcc就是这样 - 没有指定标准)但很可能其他编译器会生成错误,可以使用char*解决。由于sizeof char1你可以使用char*转换来获得相同的结果。根据标准,由于void是不完整的类型,因此未指定和非法。

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