Difference between *ptr += 1 and *ptr++ in C
CPointersPost IncrementC Problem Overview
I just started to study C, and when doing one example about passing pointer to pointer as a function's parameter, I found a problem.
This is my sample code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int* allocateIntArray(int* ptr, int size){
if (ptr != NULL){
for (int i = 0; i < size; i++){
ptr[i] = i;
}
}
return ptr;
}
void increasePointer(int** ptr){
if (ptr != NULL){
*ptr += 1; /* <----------------------------- This is line 16 */
}
}
int main()
{
int* p1 = (int*)malloc(sizeof(int)* 10);
allocateIntArray(p1, 10);
for (int i = 0; i < 10; i++){
printf("%d\n", p1[i]);
}
increasePointer(&p1);
printf("%d\n", *p1);
p1--;
free(p1);
fgets(string, sizeof(string), stdin);
return 0;
}
The problem occurs in line 16, when I modify *ptr+=1
to *ptr++
. The expected result should be the whole array and number 1 but when I use *ptr++
the result is 0.
Is there any diffirence between +=1
and ++
? I thought that both of them are the same.
C Solutions
Solution 1 - C
The difference is due to operator precedence.
The post-increment operator ++
has higher precedence than the dereference operator *
. So *ptr++
is equivalent to *(ptr++)
. In other words, the post increment modifies the pointer, not what it points to.
The assignment operator +=
has lower precedence than the dereference operator *
, so *ptr+=1
is equivalent to (*ptr)+=1
. In other words, the assignment operator modifies the value that the pointer points to, and does not change the pointer itself.
Solution 2 - C
The order of precedence for the 3 operators involved in your question is the following :
post-increment ++
> dereference *
> assignment +=
You can check this page for further details on the subject.
>When parsing an expression, an operator which is listed on some row will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it. For example, the expression *p++
is parsed as *(p++)
, and not as (*p)++
.
Long story short, in order to express this assignment *ptr+=1
using the post-increment operator you need to add parentheses to the dereference operator to give that operation precedence over ++
as in this (*ptr)++
Solution 3 - C
Let's apply parentheses to show the order of operations
a + b / c
a + (b/c)
Let's do it again with
*ptr += 1
(*ptr) += 1
And again with
*ptr++
*(ptr++)
- In
*ptr += 1
, we increment the value of the variable our pointer points to. - In
*ptr++
, we increment the pointer after our entire statement (line of code) is done, and return a reference to the variable our pointer points to.
The latter allows you to do things like:
for(int i = 0; i < length; i++)
{
// Copy value from *src and store it in *dest
*dest++ = *src++;
// Keep in mind that the above is equivalent to
*(dest++) = *(src++);
}
This is a common method used to copy a src
array into another dest
array.
Solution 4 - C
Very good question.
In K&R "C programming language" "5.1 Pointers and Addresses", we can get an answer for this.
"The unary operators * and & bind more tightly than arithmetic operators"
*ptr += 1 //Increment what ptr points to.
"Unary operators like * and ++ associate right to left."
*ptr++ //Increment prt instead of what ptr point to.
//It works like *(ptr++).
The correct way is:
(*ptr)++ //This will work.
Solution 5 - C
*ptr += 1 : Increment data that ptr points to. *ptr++ : Increment pointer that is point to next memory location instead of the data that pointer points to.