指针减法混淆

时间:2010-07-13 15:01:09

标签: c

当我们从另一个指针中减去一个指针时,差异不等于它们相隔多少个字节但等于有多少个整数(如果指向整数)它们是分开的。为什么这样?

8 个答案:

答案 0 :(得分:71)

这个想法是你指向内存块

+----+----+----+----+----+----+
| 06 | 07 | 08 | 09 | 10 | 11 | mem
+----+----+----+----+----+----+
| 18 | 24 | 17 | 53 | -7 | 14 | data
+----+----+----+----+----+----+

如果您有int* p = &(array[5]),那么*p将为14.持续p=p-3会使*p为17。

因此,如果您有int* p = &(array[5])int *q = &(array[3]),则p-q应为2,因为指针指向的内存相隔2个区块。

处理原始内存(数组,列表,地图等)时会抽出很多方块!这真的有帮助!

答案 1 :(得分:35)

因为指针区域中的所有内容都与偏移有关。当你说:

int array[10];
array[7] = 42;

你在第二行中实际说的是:

*( &array[0] + 7 ) = 42;

字面翻译为:

* = "what's at"
(
  & = "the address of"
  array[0] = "the first slot in array"
  plus 7
)
set that thing to 42

如果我们可以添加7来使偏移点到正确的位置,我们需要能够有相反的位置,否则我们的数学中没有对称性。如果:

&array[0] + 7 == &array[7]

然后,为了理智和对称:

&array[7] - &array[0] == 7

答案 2 :(得分:10)

即使在整数长度不同的平台上,答案也是一样的。

答案 3 :(得分:7)

假设您有一个包含10个整数的数组:

int intArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

然后你拿一个指向intArray的指针:

int *p = intArray;

然后你增加p

p++;

您期望的是pintArray[0]开始,p的增量值为intArray[1]。这就是指针算术就是这样的原因。 See the code here.

答案 4 :(得分:3)

“当你减去两个指针时,只要它们指向同一个数组,结果就是分隔它们的元素数量”

检查更多here

答案 5 :(得分:2)

这种方式指针减法行为与指针添加的行为一致。这意味着p1 + (p2 - p1) == p2(其中p1p2是指向同一数组的指针)。

指针添加(向指针添加整数)的行为方式类似:p1 + 1为您提供数组中下一项的地址,而不是数组中的下一个字节 - 这将是公平的无用且不安全的事情。

可以设计语言,以便以与整数相同的方式添加和减去指针,但这意味着以不同的方式编写指针算法,并且必须考虑指向的类型的大小:

  • p2 = p1 + n * sizeof(*p1)代替p2 = p1 + n
  • n = (p2 - p1) / sizeof(*p1)代替n = p2 - p1

因此,结果将是代码更长,更难以阅读,更容易出错。

答案 6 :(得分:1)

对特定类型的指针应用算术运算时,总是希望结果指针指向相对于原始起始点的“有效”(意味着正确的步长)内存地址。这是一种非常舒适的方式,可以独立于底层架构访问内存中的数据。

如果你想使用不同的“步长”,你总是可以将指针强制转换为所需的类型:

int a = 5;
int* pointer_int = &a;
double* pointer_double = (double*)pointer_int; /* totally useless in that case, but it works */

答案 7 :(得分:0)

@fahad指针算术按其指向的数据类型的大小来进行。因此,当ur指针的类型为int时,您应该期望指针算术的大小为int(4个字节)。对于char指针,指针上的所有操作都是如此将以1个字节为单位。