简体   繁体   English

C指针上的一元加法如何工作?

[英]How does unary addition on C pointers work?

I know that the unary operator ++ adds one to a number. 我知道一元运算符++将一个加到一个数字上。 However, I find that if I do it on an int pointer, it increments by 4 (the sizeof an int on my system). 但是,我发现如果我在一个int指针上执行它,它会递增4(我的系统上的int的sizeof)。 Why does it do this? 为什么这样做? For example, the following code: 例如,以下代码:

int main(void)
{
  int *a = malloc(5 * sizeof(int));
  a[0] = 42;
  a[1] = 42;
  a[2] = 42;
  a[3] = 42;
  a[4] = 42;
  printf("%p\n", a);
  printf("%p\n", ++a);
  printf("%p\n", ++a);
  return 0;
}

will return three numbers with a difference of 4 between each. 将返回三个数字,每个数字之间相差4。

It's just the way C is - the full explanation is in the spec, Section 6.5.6 Additive operators , paragraph 8: 这就是C的方式 - 完整的解释在规范中, 第6.5.6节“附加算子” ,第8段:

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. 当一个具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。 If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. 如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向偏离原始元素的元素,使得结果元素和原始数组元素的下标的差异等于整数表达式。 In other words, if the expression P points to the i -th element of an array object, the expressions (P)+N (equivalently, N+(P) ) and (P)-N (where N has the value n ) point to, respectively, the i + n -th and in -th elements of the array object, provided they exist. 换句话说,如果表达式P指向数组对象的第i个元素,则表达式(P)+N (等效地, N+(P) )和(P)-N (其中N具有值n )指向分别为数组对象的第i + n和第i - n个元素,只要它们存在即可。 Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. 此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向一个超过数组对象的最后一个元素,如果表达式Q指向一个超过数组对象的最后一个元素,表达式(Q)-1指向数组对象的最后一个元素。 If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; 如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; otherwise, the behavior is undefined. 否则,行为未定义。 If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated. 如果结果指向数组对象的最后一个元素之后,则不应将其用作已计算的一元*运算符的操作数。

To relate that to your use of the prefix ++ operator, you need to also read Section 6.5.3.1 Prefix increment and decrement operators , paragraph 2: 要将它与您使用前缀++运算符联系起来,您还需要阅读第6.5.3.1节“前缀增量和减量运算符” ,第2段:

The value of the operand of the prefix ++ operator is incremented. 前缀++运算符的操作数的值递增。 The result is the new value of the operand after incrementation. 结果是增量后操作数的新值。 The expression ++E is equivalent to (E+=1) . 表达式++E等价于(E+=1)

And also Section 6.5.16.2 Compound assignment , paragraph 3: 第6.5.16.2节“复合转让 ”第3段:

A compound assignment of the form E1 op = E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once. E1 op = E2形式的复合赋值与简单赋值表达式E1 = E1 op (E2)仅在于左值E1仅被评估一次。

It's incrementing the pointer location by the size of int , the declared type of the pointer. 它将指针位置增加int的大小,即指针的声明类型。

Remember, an int * is just a pointer to a location in memory, where you are saying an "int" is stored. 请记住, int *只是指向内存中某个位置的指针,您可以在其中存储“int”。 When you ++ to the pointer, it shifts it one location (by the size of the type), in this case, it will make your value "4" higher, since sizeof(int)==4 . 当你指向++ ,它会将它移动一个位置(按类型的大小),在这种情况下,它会使你的值“4”更高,因为sizeof(int)==4

The reason for this is to make the following statement true: 这样做的原因是使以下陈述成立:

*(ptr + n) == ptr[n]

These can be used interchangeably. 这些可以互换使用。

In pointer arithmetic, adding one to a pointer will add the sizeof the type which it points to. 在指针运算中,向指针添加一个将添加它指向的类型的大小。

so for a given: 所以对于给定的:

TYPE * p;

Adding to p will actually increment by sizeof(TYPE) . 添加到p实际上会增加sizeof(TYPE) In this case the size of the int is 4. 在这种情况下,int的大小为4。

See this related question 看到这个相关的问题

Because in "C" pointer arithmetic is always scaled by the size of the object being pointed to. 因为在“C”中,指针算术总是按指向的对象的大小进行缩放。 If you think about it a bit, it turns out to be "the right thing to do". 如果你仔细想一想,事实证明这是“正确的事情”。

它这样做是为了让你不开始访问它中间的整数。

Because a pointer is not a reference ;). 因为指针不是引用;)。 It's not a value, it's just an address in memory. 它不是一个值,它只是内存中的一个地址。 When you check the pointer's value, it will be a number, possibly big, and unrelated to the actual value that's stored at that memory position. 检查指针的值时,它将是一个数字,可能很大,与存储在该存储器位置的实际值无关。 Say, printf("%p\\n", a); 比如, printf("%p\\n", a); prints "2000000" - this means your pointer points to the 2000000th byte in your machine's memory. 打印“2000000” - 这意味着您的指针指向机器内存中的第2000000个字节。 It's pretty much unaware of what value it's stored there. 它几乎没有意识到它存储在什么价值。

Now, the pointer knows what type it points to. 现在,指针知道它指向的类型。 An integer, in your case. 在您的情况下为整数。 Since an integer is 4 bytes long, when you want to jump to the next "cell" the pointer points to, it needs to be 2000004. That's exatly 1 integer farther, so a++ makes perfect sense. 由于一个整数是4个字节长,当你想要跳转到指针所指向的下一个“单元格”时,它需要是2000004.这是1个整数,所以a++非常有意义。

BTW, if you want to get 42 (from your example), print out the value pointed to: printf("%d\\n", *a); 顺便说一句,如果你想获得42 (从你的例子),打印出指向的值: printf("%d\\n", *a);

I hope this makes sense ;) 我希望这是有道理的 ;)

Thats simple, cause when it comes down to pointer, in your case an integer pointer, a unary increment means INCREMENT THE MEMORY LOCATION BY ONE UNIT, where ONE UNIT = SIZE OF INTEGER . 这很简单,因为它归结为指针,在你的情况下是一个整数指针,一元增量意味着由一个单元增加内存位置,其中一个单元=整数的大小。

This size of integer depends from compile to compiler, for a 32-bit and 16-bit it is 4bytes, while for a 64-bit compiler it is 8bytes. 这个整数大小取决于从编译到编译器,对于32位和16位,它是4字节,而对于64位编译器,它是8字节。

Try doing the same program with character datatype, it will give difference of 1 byte as character takes 1 byte. 尝试使用字符数据类型执行相同的程序,当字符占用1个字节时,它将给出1个字节的差异。

In Short, the difference of 4's that you've come across is the difference of SIZE OF ONE INTEGER in memory. 简而言之,您遇到的4的差异是内存中SIZE OF ONE INTEGER的差异。

Hope this helped, if it didn't i'll be glad to help just let me know. 希望这有所帮助,如果不是,我会很乐意帮助我告诉我。

"Why does it do this?" “为什么这样做?” Why would you expect it to do anything else? 为什么你会期望它做任何其他事情? Incrementing a point makes it point to the next item of the type that it's a pointer to. 递增一个点使它指向它指向的类型的下一个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM