为什么C中的指针减法产生一个整数?

时间:2016-01-22 20:42:00

标签: c pointers

为什么如果我从指针中减去另一个没有类型转换的指针(整数指针),结果将是1而不是4个字节(就像我将两个指针都转换为int时一样)。示例:

int a , b , *p , *q;
p = &b;
q = p + 1; // q = &a;
printf("%d",q - p); // The result will be one .
printf("%d",(int)q - (int)p); // The result will be 4(bytes). The memory address of b minus The memory address of a.

5 个答案:

答案 0 :(得分:4)

根据C标准(6.5.6添加剂操作员)

  

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

如果两个指针指向同一个数组的元素,那么就像在标准引用中所说的那样

  

结果是两个数组下标的差异   元素

那就是你会得到这两个指针之间数组的元素数量。这是所谓的指针算法的结果。

如果将存储在指针中的地址减去整数值,则会得到与算术减法运算相对应的数字。

答案 1 :(得分:3)

因为指针减法的ptrdiff_t是相对于指向的元素的大小计算的。这样方式更方便;例如,它会告诉您在到达另一个指针之前可以增加一个指针的次数。

答案 2 :(得分:3)

  

为什么如果我从指针中减去另一个没有类型转换的指针(整数指针),结果将是1而不是4个字节

这是指针指向的数据类型的重点。查看下面的数组上下文可能更容易。无论基础数据类型(此处为longdouble)如何,您都可以使用指针算法来导航数组,而无需关心其元素的大小。换句话说,(指针+ 1)表示指向下一个元素,无论其类型如何。

long l[] = { 10e4, 10e5, 10e6 };
long *pl = l + 1;    // point to the 2nd element in the "long" array.

double d[] = { 10e7, 10e8, 10e9 };
double *pd = d + 2;    // point to the 3rd element in the "double" array.

请在代码中注明:

int a , b , *p , *q;
p = &b;
q = p + 1; // q = &a;   <--- NO this is wrong. 

ab 声明彼此相邻的事实并不意味着ab分配在内存中彼此相邻。因此q指向b旁边的内存地址 - 但该地址中的内容未定义。

答案 3 :(得分:3)

你有

的地方
int a , b , *p , *q;

编译器可以将ab置于任何位置。他们甚至不必彼此靠近。此外,当您减去两个int指针时,结果的大小为int,而不是字节。

答案 4 :(得分:2)

C不是汇编语言。所以指针不只是简单的整数 - 指针是特殊的人,知道如何指向其他东西。

指针和指针算术在C中的工作方式的基础是它们可以指向数组的连续元素。所以,如果我们写

int a[10];
int *p1 = &a[4];
int *p2 = &a[3];

然后p1 - p2将为1.结果为1,因为&#34;距离&#34; a[3]a[4]之间是一个int。结果是1,因为4 - 3 = 1.结果是 4(因为您可能认为如果您知道int在您的计算机上是32位),因为我们在进行汇编语言编程或使用机器地址时并不感兴趣;我们正在使用数组进行更高级别的语言编程,我们正在考虑这些术语。

(但是,是的,在机器地址级别,计算p2 - p1的方式通常为(&lt; p2中的原始地址值&gt; - &lt; {{1中的原始地址值}}&gt;)/ p1。)