C语言 指针减法混淆
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3238482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pointer subtraction confusion
提问by fuddin
When we subtract a pointer from another pointer the difference is not equal to how many bytes they are apart but equal to how many integers (if pointing to integers) they are apart. Why so?
当我们从另一个指针中减去一个指针时,差异不等于它们分开的字节数,而是等于它们分开的整数数(如果指向整数)。为什么这样?
回答by corsiKa
The idea is that you're pointing to blocks of memory
这个想法是你指向内存块
+----+----+----+----+----+----+
| 06 | 07 | 08 | 09 | 10 | 11 | mem
+----+----+----+----+----+----+
| 18 | 24 | 17 | 53 | -7 | 14 | data
+----+----+----+----+----+----+
If you have int* p = &(array[5])then *pwill be 14. Going p=p-3would make *pbe 17.
如果你有int* p = &(array[5])那么*p将是 14。 去p=p-3将*p是 17。
So if you have int* p = &(array[5])and int *q = &(array[3]), then p-qshould be 2, because the pointers are point to memory that are 2 blocks apart.
所以如果你有int* p = &(array[5])and int *q = &(array[3]),那么p-q应该是2,因为指针指向相隔2个块的内存。
When dealing with raw memory (arrays, lists, maps, etc) draw lots of boxes! It really helps!
在处理原始内存(数组、列表、映射等)时,绘制大量的框!它真的很有帮助!
回答by eruciform
Because everything in pointer-land is about offsets. When you say:
因为pointer-land中的一切都是关于偏移量的。当你说:
int array[10];
array[7] = 42;
What you're actually saying in the second line is:
你实际上在第二行说的是:
*( &array[0] + 7 ) = 42;
Literally translated as:
直译为:
* = "what's at"
(
& = "the address of"
array[0] = "the first slot in array"
plus 7
)
set that thing to 42
And if we can add 7 to make the offset point to the right place, we need to be able to have the opposite in place, otherwise we don't have symmetry in our math. If:
如果我们可以添加 7 使偏移点指向正确的位置,我们需要能够将相反的位置放在适当的位置,否则我们的数学中没有对称性。如果:
&array[0] + 7 == &array[7]
Then, for sanity and symmetry:
然后,为了理智和对称:
&array[7] - &array[0] == 7
回答by ptomato
So that the answer is the same even on platforms where integers are different lengths.
因此,即使在整数长度不同的平台上,答案也是相同的。
回答by Jeff Kelley
Say you have an array of 10 integers:
假设您有一个包含 10 个整数的数组:
int intArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Then you take a pointer to intArray:
然后你拿一个指向 intArray 的指针:
int *p = intArray;
Then you increment p:
然后你增加p:
p++;
What you would expect, because pstarts at intArray[0], is for the incremented value of pto be intArray[1]. That's why pointer arithmetic works like that. See the code here.
您所期望的,因为p从 开始intArray[0],是 的递增值p是intArray[1]。这就是为什么指针算法是这样工作的。请参阅此处的代码。
回答by Praveen S
回答by mwfearnley
This way pointer subtraction behaves is consistent with the behaviour of pointer addition. It means that p1 + (p2 - p1) == p2(where p1and p2are pointers into the same array).
这种指针减法的行为与指针加法的行为一致。这意味着p1 + (p2 - p1) == p2( wherep1和p2是指向同一个数组的指针)。
Pointer addition (adding an integer to a pointer) behaves in a similar way: p1 + 1gives you the address of the next item in the array, rather than the next byte in the array - which would be a fairly useless and unsafe thing to do.
指针添加(将整数添加到指针)的行为方式类似:p1 + 1为您提供数组中下一项的地址,而不是数组中的下一个字节 - 这将是一件相当无用且不安全的事情。
The language could have been designed so that pointers are added and subtracted the same way as integers, but it would have meant writing pointer arithmetic differently, and having to take into account the size of the type pointed to:
该语言本可以设计为使指针以与整数相同的方式添加和减去,但这意味着以不同的方式编写指针算术,并且必须考虑指向的类型的大小:
p2 = p1 + n * sizeof(*p1)instead ofp2 = p1 + nn = (p2 - p1) / sizeof(*p1)instead ofn = p2 - p1
p2 = p1 + n * sizeof(*p1)代替p2 = p1 + nn = (p2 - p1) / sizeof(*p1)代替n = p2 - p1
So the result would be code that is longer, and harder to read, and easier to make mistakes in.
所以结果将是代码更长,更难阅读,更容易出错。
回答by das_weezul
When applying arithmetic operations on pointers of a specific type, you always want the resulting pointer to point to a "valid" (meaning the right step size) memory-address relative to the original starting-point. That is a very comfortable way of accessing data in memory independently from the underlying architecture.
在对特定类型的指针应用算术运算时,您总是希望结果指针指向相对于原始起点的“有效”(意味着正确的步长)内存地址。这是一种独立于底层架构访问内存中数据的非常舒适的方式。
If you want to use a different "step-size" you can always cast the pointer to the desired type:
如果您想使用不同的“步长”,您始终可以将指针转换为所需的类型:
int a = 5;
int* pointer_int = &a;
double* pointer_double = (double*)pointer_int; /* totally useless in that case, but it works */
回答by The Stig
@fahad Pointer arithmetic goes by the size of the datatype it points.So when ur pointer is of type int you should expect pointer arithmetic in the size of int(4 bytes).Likewise for a char pointer all operations on the pointer will be in terms of 1 byte.
@fahad 指针算法取决于它指向的数据类型的大小。所以当你的指针是 int 类型时,你应该期望指针算法的大小为 int(4 字节)。同样,对于 char 指针,指针上的所有操作都将在1 个字节的术语。

