指针减法混淆
当我们从另一个指针中减去一个指针时,差异不等于它们分开了多less个字节,而是等于多less个整数(如果指向整数),它们是分开的。 为什么这样?
这个想法是,你指着内存块
+----+----+----+----+----+----+ | 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])
,那么pq
应该是2,因为指针指向的是相隔2个块的内存。
处理原始内存(数组,列表,地图等)时,请抽出大量的盒子! 这真的有帮助!
因为指针地上的所有东西都是偏移量。 当你说:
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来使偏移点到正确的位置,我们需要能够有相反的地方,否则我们的math中就没有对称性。 如果:
&array[0] + 7 == &array[7]
那么,为了理智和对称:
&array[7] - &array[0] == 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]
。 这就是为什么指针运算就像这样。 看到这里的代码。
“当你减去两个指针时,只要它们指向同一个数组,结果就是分隔它们的元素的数量”
在这里检查更多。
对特定types的指针应用算术运算时,总是希望生成的指针指向相对于原始起点的“有效”(意思是正确的步长)存储器地址。 这是一种非常舒适的方式,独立于底层体系结构访问内存中的数据。
如果您想要使用不同的“步长”,您可以始终将指针转换为所需的types:
int a = 5; int* pointer_int = &a; double* pointer_double = (double*)pointer_int; /* totally useless in that case, but it works */
这与指针添加行为的方式一致。 这意味着p1 + (p2 - p1) == p2
*。
指针加法(在指针中加一个整数)的行为与此类似: p1 + 1
给出了数组中下一项的地址,而不是数组中的下一个字节 – 这是一个相当无用和不安全的事情做。
C可以被devise成使得指针被添加和减去与整数相同的方式,但是这意味着:
- 做
p2 = p1 + n * sizeof(*p1)
而不是p2 = p1 + n
- 做
n = (p2 - p1) / sizeof(*p1)
而不是n = p2 - p1
这将导致代码更长,更难以阅读,并且不太安全。
*:假定p1和p2之间的差异是它们指向的types的精确倍数。 如果他们在相同的内存中,这将是真实的。 如果它们不是,那么对它们进行指针运算就没有太大意义了。
@fahad指针的算术是指向它指向的数据types的大小。所以当ur指针的types为int时,你应该期望指针的算术大小为int(4个字节)。对于一个char指针,指针的所有操作都将在1字节的条款。