当我们从另一个指针中减去一个指针时,差异不等于它们相隔多少个字节但等于有多少个整数(如果指向整数)它们是分开的。为什么这样?
答案 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++;
您期望的是p
从intArray[0]
开始,p
的增量值为intArray[1]
。这就是指针算术就是这样的原因。 See the code here.
答案 4 :(得分:3)
“当你减去两个指针时,只要它们指向同一个数组,结果就是分隔它们的元素数量”
检查更多here。
答案 5 :(得分:2)
这种方式指针减法行为与指针添加的行为一致。这意味着p1 + (p2 - p1) == p2
(其中p1
和p2
是指向同一数组的指针)。
指针添加(向指针添加整数)的行为方式类似: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个字节为单位。