【问题标题】:Why does subtracting a pointer value from an address result in gap of 8 times the pointer value? [duplicate]为什么从地址中减去指针值会导致指针值的 8 倍间隙? [复制]
【发布时间】:2013-09-23 16:12:59
【问题描述】:

在下面的 sn-p 中,指针地址和值被引用为类型size_t。 然而,正如标题所说,最后的减法对我来说没有意义。它的作用就像是减去乘以 8 的数字,而不是在 int array 中看到的实际值。

#include <stdio.h>
#include <stdint.h>

int main()
{
    int i[6] = {2, 0, 1, 0, 20, 24};

    void *ptr = &i[2];

    printf("%zu\n", ((size_t*)ptr));
    printf("%zu\n", *((size_t*)ptr));
    printf("%zu\n", ((size_t*)ptr) - *((size_t*)ptr));
}

【问题讨论】:

  • %zu 是什么类型的说明符?对我的编译器发出警告:Unknown conversion type character 'z' in format.
  • @hacks 这是size_t的正确转换说明符。
  • @hacks z 是整数格式的修饰符,表示整数参数的预期类型是size_t。恕我直言,这里没有正确使用。 (C11 7.21.6.1 7)
  • @Jimbo 这不是 GNU 扩展,而是标准说明符,存在于 C99 及更高版本中。
  • @chux 完全正确,它(ab)用于size_t *,而它期望size_t

标签: c pointers types type-conversion


【解决方案1】:

首先要注意的是,您正在通过指向无符号整数变量的指针访问有符号整数变量。另请注意sizeof(size_t) 不一定等于sizeof(int)

行:

printf("%zu\n", ((size_t*)ptr) - *((size_t*)ptr));

有效地执行AddressOf(i[2]) - i[2],即AddressOf(i[2]) - 1

在 C 指针算术中,地址不是减 1,而是减 1,而是 1 * sizeof(data type),这就是你机器上的 sizeof(size_t)。如果您在 64 位机器上,这可能是 8 个字节。您获得的地址将是-8,而不是我想您所期望的-1...

编辑:%z 可能是 pointer 地址的%psize_t * 的强制转换不是必需的,并且如上所述可能很危险......

【讨论】:

  • 太好了,我不知道它将值与 sizeof(datatype) 相乘。非常感谢!
  • 不要回答明显重复的问题。改为投票关闭。
【解决方案2】:

您从size_t 指针中减去i[2] == 1,因此实际差值为sizeof(size_t) == 8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多