increment value of int being pointed to by pointer - c

I have an int pointer (i.e., int *count) that I want to increment the integer being pointed at by using the ++ operator. I thought I would call:
*count++;
However, I am getting a build warning "expression result unused". I can: call
*count += 1;
But, I would like to know how to use the ++ operator as well. Any ideas?

The ++ has equal precedence with the * and the associativity is right-to-left. See here. It's made even more complex because even though the ++ will be associated with the pointer the increment is applied after the statement's evaluation.
The order things happen is:
Post increment, remember the post-incremented pointer address value as a temporary
Dereference non-incremented pointer address
Apply the incremented pointer address to count, count now points to the next possible memory address for an entity of its type.
You get the warning because you never actually use the dereferenced value at step 2. Like #Sidarth says, you'll need parenthesis to force the order of evaluation:
(*ptr)++

Try using (*count)++. *count++ might be incrementing the pointer to next position and then using indirection (which is unintentional).

Related

Is dereferencing a pointer an alias for the pointed variable or does it just access the value of the variable?

I am not able to fully understand the nature of dereferencing operator. Does dereferencing is just an alias of the pointed variable or it fetches the value of the variable.
We know that for constant doing &constant is invalid as a constant does not have its own memory.
Now suppose we have something like this-
int i=5;
int *ptr=&i;
And then if we do &(*ptr) then how it will happen on lower level?
There are two three things in my mind let me take you to the all.
Case 1: I read that *ptr gives the value at that memory location so by this in mind &(*ptr) will evaluate to &5 but this will give an error as 5 is a constant.
Case 2: That *ptr is just an alias for the variable 'i' then &(*ptr) will become &i and this looks fine by me.
Case 3: What I was told that & and * cancels each other out in the expression &(*ptr) but I am not able to get it. How they cancels each other out?
In the C standard :
A.7.4.3 Indirection Operator The unary * operator denotes indirection,
and returns the object or function to which its operand points. It is
an lvalue if the operand is a pointer to an object of arithmetic,
structure, union, or pointer type. If the type of the expression is
``pointer to T,'' the type of the result is T.
So, *ptr will return an lvalue and not the value stored in i (So, saying it returns an alias is right). The & operator can be used on this lvalue and you get the same result as &i on using &(*ptr).
So, it is case 2
And, for saying that & and * cancel each other out, as we see above, &(*ptr) will evaluate to the same result as &i which is the same as just ptr. So, in the end result, you can say, they cancelled each other. But, unless the compiler decides to do some optimizations and remove the & and *, first the *ptr gets evaluated and then the & operates on that result.
It literally does the 2nd case. As a pointer points to a local stack variable the &(*ptr) will get it's address.
The constant variables do have their memory in the same way as non-constants. But if it doesn't manipulate their memory address in any way, the optimizer may carve it out and put constant values just-in-place.

Postfix increment and derefencing of pointer variable in the same statement - what is executed first and what is executed next [duplicate]

I am learning C language and quite confused the differences between ++*ptr and *ptr++.
For example:
int x = 19;
int *ptr = &x;
I know ++*ptr and *ptr++ produce different results but I am not sure why is that?
These statements produce different results because of the way in which the operators bind. In particular, the prefix ++ operator has the same precedence as *, and they associate right-to-left. Thus
++*ptr
is parsed as
++(*ptr)
meaning "increment the value pointed at by ptr,". On the other hand, the postfix ++ operator has higher precedence than the dereferrence operator *. Thefore
*ptr++
means
*(ptr++)
which means "increment ptr to go to the element after the one it points at, then dereference its old value" (since postfix ++ hands back the value the pointer used to have).
In the context you described, you probably want to write ++*ptr, which would increment x indirectly through ptr. Writing *ptr++ would be dangerous because it would march ptr forward past x, and since x isn't part of an array the pointer would be dangling somewhere in memory (perhaps on top of itself!)
Hope this helps!
The accepted answer is not correct. It's not the case that the postfix ++ operator has the same precedence as dereference/indirection *. The prefix and postfix operators have different precedence, and only the prefix operator has the same precedence as dereference/indirection.
As the precedence table shows, postfix ++ has a higher precedence than dereference/indirection *. So *ptr++ gets evaluated as *(ptr++). ptr++ evaluates to the current value of ptr; it increments ptr only as a side effect. The value of the expression is the same as the current value of ptr. So it won't have any effect on the value stored at the pointer. It will merely dereference the pointer (i.e., get the current value stored there, which is 19), then advance the pointer. In your example there is no defined value stored at the new position of ptr, so the pointer is pointing to garbage. Dereferencing it now would be dangerous.
Also as the table shows, prefix ++ has the same precedence as dereference/indirection *, but because of right-left associativity, it gets evaluated as ++(*ptr). This will first dereference the pointer (i.e., get the value stored at the address pointed to) and then increment that value. I.e., the value will now be 20.
The accepted answer is correct about the effects of the two, but the actual mechanism is different from the one given there.
As templatetypedef says, but you should provide the parenthesis around *ptr to ensure the outcome. For instance, the following yields 1606415888 using GCC and 0 using CLang on my computer:
int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);
And you expected x to be 20. So use (*ptr)++ instead.

prefix or postfix operation on c pointer

#include<stdio.h>
void increment(int *p) {
*p = *p + 1;
}
void main() {
int a = 1;
increment(&a);
printf("%d", a);
}
for above if I run above code it prints 2
but if I replace *p = *p + 1; with *p++;
it is printing 1.Why is it so?...
operator precedence...
When writing *p++ you get these operations:
p++ is evaluated (later p will get incremented)
the original value of p is returned (since this is a suffix ++, if it was prefix, the value returned would have been p+1... )
dereference of the the pointer p and since p earlier pointed to 1, that's what you get
If you take a look at the precedence table for operators you will see that the postfix increment has a higher precedence than dereference. This means that *p++ will actually be grouped as *(p++).
You should use parenthesis to explicit what you are trying to do, in this case (*p)++ or ++(*p).
To answer this question consult the table of C operator precedence: operator + has lower precedence than dereference operator *, while increment operator ++ has higher precedence.
That is why ++ is applied to the pointer, while + 1 is applied to the result of pointer dereference.
Read about operator precedence. Check what happens when you do (*p)++.
Note: You may also try doing *(p++). But this will invoke undefined behaviour UB.
In the first case *p=*p+1; the control adds one to the value at *p by 1 and then stores the result in *p. This actually uses a temporary variable during program runtime which you are not able to see. Now,the value at the temporary instance is incremented and finally stored in *p.
In the second case, *p++; a sequence point concept comes.
According to C standard an object's stored value can be modified only once (by evaluation of expressions) between two sequence points.
A sequence point occurs:
at the end of full expressions
at the &&,|| and ?: operators.
at a function call (after evaluation of arguments,just before the actual call)
In *p++;, since the expression is modified only after the sequence point is encountered, *p is unable to store the modified value of itself.

Understanding pointer variable increment

While reading about pointers I found a pointer variable is used to indicate an array like this:
char* chrArray;
int* intArray;
After that I found charArray++ and intArray++ used in code to indicate the next element of charArray and intArray. But so far I know char in C is 1 byte and int in array is 4 byte. So I can not understand how the increment operator behave here. Can anyone please explain it.
This is handled by the compiler that knows the type of the pointer, thus can increment the address it stores by the relevant size, whether it is a char, an int or any other type.
As per the C11 standard document, chapter 6.5.2.5, Postfix increment and decrement operators
The result of the postfix ++ operator is the value of the operand. As a side effect, the
value of the operand object is incremented (that is, the value 1 of the appropriate type is
added to it).
So, whenever you're using a postfix increment operator, you're not adding any specific value, rather, you're addding value 1 of the type of the operand on which the operator is used.
Now for your example,
chrArray is of type char *. So, if we do chrArray++, a value of the type char [sizeof(char), which is 1] will be added to chrArray as the result.
OTOH, intArray is of type int *. So, if we do intArray++, a value of the type int [sizeof(int), which is 4 on 32 bit platform, may vary] will be added to intArray as the result.
Basically, a Postfix increment operator on a pointer variable of any type points to the next element (provided, valid access) of that type.

Pointer Arithmetic: ++*ptr or *ptr++?

I am learning C language and quite confused the differences between ++*ptr and *ptr++.
For example:
int x = 19;
int *ptr = &x;
I know ++*ptr and *ptr++ produce different results but I am not sure why is that?
These statements produce different results because of the way in which the operators bind. In particular, the prefix ++ operator has the same precedence as *, and they associate right-to-left. Thus
++*ptr
is parsed as
++(*ptr)
meaning "increment the value pointed at by ptr,". On the other hand, the postfix ++ operator has higher precedence than the dereferrence operator *. Thefore
*ptr++
means
*(ptr++)
which means "increment ptr to go to the element after the one it points at, then dereference its old value" (since postfix ++ hands back the value the pointer used to have).
In the context you described, you probably want to write ++*ptr, which would increment x indirectly through ptr. Writing *ptr++ would be dangerous because it would march ptr forward past x, and since x isn't part of an array the pointer would be dangling somewhere in memory (perhaps on top of itself!)
Hope this helps!
The accepted answer is not correct. It's not the case that the postfix ++ operator has the same precedence as dereference/indirection *. The prefix and postfix operators have different precedence, and only the prefix operator has the same precedence as dereference/indirection.
As the precedence table shows, postfix ++ has a higher precedence than dereference/indirection *. So *ptr++ gets evaluated as *(ptr++). ptr++ evaluates to the current value of ptr; it increments ptr only as a side effect. The value of the expression is the same as the current value of ptr. So it won't have any effect on the value stored at the pointer. It will merely dereference the pointer (i.e., get the current value stored there, which is 19), then advance the pointer. In your example there is no defined value stored at the new position of ptr, so the pointer is pointing to garbage. Dereferencing it now would be dangerous.
Also as the table shows, prefix ++ has the same precedence as dereference/indirection *, but because of right-left associativity, it gets evaluated as ++(*ptr). This will first dereference the pointer (i.e., get the value stored at the address pointed to) and then increment that value. I.e., the value will now be 20.
The accepted answer is correct about the effects of the two, but the actual mechanism is different from the one given there.
As templatetypedef says, but you should provide the parenthesis around *ptr to ensure the outcome. For instance, the following yields 1606415888 using GCC and 0 using CLang on my computer:
int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);
And you expected x to be 20. So use (*ptr)++ instead.

Resources