不同类型指针之间的减法

fed*_*ngo 3 c pointers subtraction pointer-arithmetic

我试图找到两个变量之间的内存距离.具体来说,我需要找到char []数组和int之间的距离.

    char data[5];
    int a = 0;

    printf("%p\n%p\n", &data[5], &a);

    long int distance = &a - &data[5];

    printf("%ld\n", distance);
Run Code Online (Sandbox Code Playgroud)

当我在没有最后两行的情况下运行我的程序时,我得到了两个变量的正确内存地址,如下所示:

   0x7fff5661aac7
   0x7fff5661aacc
Run Code Online (Sandbox Code Playgroud)

现在我明白了,如果我没错,两者之间有5个字节的距离(0x7fff5661aac8,0x7fff5661aac9,0x7fff5661aaca,0x7fff5661aacb,0x7fff5661aacc).

为什么我不能减去类型(int*)和类型(char*)之一的指针.两者都是指内存地址..我该怎么做才能计算两者之间的距离,以字节为单位?我尝试了两个指针中的一个,但它没有用.

我得到:" 错误:'char*'和'int*'不是兼容类型的指针 ".谢谢大家都会帮助我

Sou*_*osh 8

不,这是不可能的.

首先,你只能减去(到)"兼容"类型的指针,这里int和a char是不兼容的类型.因此减法是不可能的.

也就是说,即使两者都是兼容类型的指针,那么下面也会出现以下情况.

所以,其次,你不能只减去两个任意指针,它们必须基本上是同一个数组的(元素的地址)的一部分.Othweise,它调用未定义的行为.

引用C11,章节§6.5.6,附加算子

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

第三,另一个重点是,减去两个指针的结果是类型ptrdiff_t,有符号整数类型.

[...]结果的大小是实现定义的,其类型(有符号整数类型)ptrdiff_t<stddef.h>标头中定义.[...]

因此,要打印结果,您需要使用%td格式说明符.

  • @ PeterA.Schneider:这就是`offsetof`的用途.你能提供标准允许指针的参考吗?IIRC,没有这样的例外('offsetof`的实现是特定于实现的. (2认同)
  • 一个次要的挑剔:我认为减去两个不兼容类型指针的尝试是标准称为*约束违规*(违反的规则出现在n1570的6.5.6的*Constraints*部分中).标准中的*约束*违反了符合编译器在编译时必须诊断的语言规则.这就是OP无法编译和运行程序但正确获取报告错误的原因.UB是不可能的,因为没有生成可执行文件. (2认同)