regarding * and ++ operators

S

sam_cit

Hi Everyone,

I often get confused with * and ++ operator when they are used with
pointers as to which would be considered first by the compiler, Can
anyone explain with some examples to understand them easier???
 
M

Malcolm

Hi Everyone,

I often get confused with * and ++ operator when they are used with
pointers as to which would be considered first by the compiler, Can
anyone explain with some examples to understand them easier???
The first area of confusion.

char *ptr;

declares ptr as a pointer to data of type char.

*ptr = 'a';

dereferences ptr. Or in other words, puts the character 'a' in the place
pointed to by ptr.
Note that, as the code stands, ptr is uninitialised. To have a working,
though useless function we need

void foo(void)
{
char ch;
char *ptr = &ch;

&ptr = 'a';
}

It is comparatively rare for pointers to point to sinle objects. After all,
normally you would just use ch itself.
They come into their own with arrays.

char buff[1024];
char *ptr = buff;

sets ptr to point to the first entry in buff
now let's say we want a function that will set a string to all 'a', adding a
terminating null.

void allas(char *str, int N)
{
int i;
for(i=0;i<N;i++)
*ptr++ = 'a';
*ptr = 0;
}

see how compact and expressive this notation is. The ++ is more binding than
the derefernece, but it is applied last. This is a reversal of normal rules
of mathematical notation, but is is extremely convenient. You very
frequently want to use a pointer to step through an array.
 
R

Robert Gamble

Malcolm said:
The first area of confusion.

char *ptr;

declares ptr as a pointer to data of type char.

*ptr = 'a';

dereferences ptr. Or in other words, puts the character 'a' in the place
pointed to by ptr.
Note that, as the code stands, ptr is uninitialised. To have a working,
though useless function we need

void foo(void)
{
char ch;
char *ptr = &ch;

&ptr = 'a';

Surely you meant:
*ptr = 'a';

Robert Gamble
 
J

John Bode

Hi Everyone,

I often get confused with * and ++ operator when they are used with
pointers as to which would be considered first by the compiler, Can
anyone explain with some examples to understand them easier???

The expression *a++ would be evaluated as follows: *(a++). Here's the
parse tree (best viewed with a monospace font):

unary-expression
/ \
unary-operator cast-expression
| / \
* postfix-expr ++
|
primary-expression
|
a

As the parse tree shows, the postfix ++ binds to the identifier more
tightly to the identifier than the dereference operator.

The expression ++*a would be evaluated as ++(*a). Here's the parse
tree:

unary-expression
/ \
++ unary-expression
/ \
unary-operator cast-expression
| |
* primary-expression
|
a

The parse tree shows that the deference operator binds more tightly to
the identifier than the prefix ++ operator.
 
R

raghu

John said:
The expression *a++ would be evaluated as follows: *(a++). Here's the
parse tree (best viewed with a monospace font):

unary-expression
/ \
unary-operator cast-expression
| / \
* postfix-expr ++
|
primary-expression
|
a

As the parse tree shows, the postfix ++ binds to the identifier more
tightly to the identifier than the dereference operator.

The expression ++*a would be evaluated as ++(*a). Here's the parse
tree:

unary-expression
/ \
++ unary-expression
/ \
unary-operator cast-expression
| |
* primary-expression
|
a

The parse tree shows that the deference operator binds more tightly to
the identifier than the prefix ++ operator.


Its not at all clear....still confusing
 
T

Tech_Head

Raghu wrote
Its not at all clear.....still confusing




This piece of code might clear your doubt.

void main()
{

int a[5]= {1,2,3,4,5};..................(1)
int count= 0;......................................(2)
int *p= a;.................................(3)

for(count=0; count<5; i++)..........................(4)
{
printf("%d\t ",*p++);.....(5)
printf("%u\n ", p);...........(6)
}
}



I have declared an array "a[]" (1) with five values.

Integer variable "count" (2).

Next statement (3), declares a pointer type variable "p", which means
it will store the address of an integer variable. To this pointer
variable I am assigning the "a". Now the pointer "p" will store the
address of the very first element of the array "a".

Next I have just created a for loop (4) to print all the elements in
the array.

In the print statement (5), "*p++" will execute as follows.
*p will fetch the value pointed by the pointer and will be printed by
the printf() statement.

Now consider p is pointing to location
10234(say). and let us say "int" occupies 4 bytes.
Since "p" is an integer type pointer, after the printf() statement, p
will be incremented by one.
e.i it will be pointing to the next integer location . In this case
10234+ 4(since it is 4 bytes)= 10238.

You can check that when the statement (6) executes.

When next for() loop executes, the element at this location will be
displayed and again the same process will execute.

Hope you are now clear. Anybody please point out if I am wrong
anywhere.
 
R

Richard Heathfield

Malcolm said:

*ptr++ = 'a';

see how compact and expressive this notation is. The ++ is more binding
than the derefernece, but it is applied last.

No, it is applied *first*. Its result, however, is the value the pointer has
at the time before the increment is applied.
 
R

Richard Heathfield

(e-mail address removed) said:
Hi Everyone,

I often get confused with * and ++ operator when they are used with
pointers as to which would be considered first by the compiler, Can
anyone explain with some examples to understand them easier???

p++ does two things, in no particular order. One of the things it does is to
get p to point to the next object in a series of objects. But the other
thing is this: it, like all expressions, has a value. In this case, the
value is p's old value, before it was moved along to the next object.

In the expression *p++, ++ has higher precedence than *, so *p++ is exactly
equivalent to *(p++). As you can see, p++ yield's p's old value, so *p++
gives us the object that p pointed to before we started this whole mess.

Switch your newsreader to a courier (or other fixed-pitch) font to see the
following diagram correctly.

If p points to the 'h' in the following memory block:

[ 'h' ] [ 'e' ] [ 'l' ] [ 'l' ] [ 'o' ] [ '\0' ]
^
|
p

then *p++ = 'j' will give us the following result:

[ 'j' ] [ 'e' ] [ 'l' ] [ 'l' ] [ 'o' ] [ '\0' ]
^
|
p
 
T

Tech_Head

Yes, I do apologise for the same. Please put
"int main()" instead of "void main" and also put a return statement in
the main code.
 
R

Richard Heathfield

Tech_Head said:
This piece of code might clear your doubt.

void main()

We dealt with that. You've agreed it should be int main(void) and requires a
matching return statement; that's a great start, so let's move on.
{

int a[5]= {1,2,3,4,5};..................(1)
int count= 0;......................................(2)
int *p= a;.................................(3)

for(count=0; count<5; i++)..........................(4)
{
printf("%d\t ",*p++);.....(5)

Undefined behaviour, because you don't have a valid prototype in scope for
printf.
printf("%u\n ", p);...........(6)

Undefined behaviour not just for the same reason as before, but also because
you should be using %p (and adding a cast: (void *)p since printf requires
a void * when printing a pointer value.
In the print statement (5), "*p++" will execute as follows.
*p will fetch the value pointed by the pointer and will be printed by
the printf() statement.

printf() isn't a statement; it's a function call. More importantly, you are
failing to make clear that ++ has higher precedence than * and thus that
the value * will be working on is the value yielded by p++.
Now consider p is pointing to location
10234(say). and let us say "int" occupies 4 bytes.
Since "p" is an integer type pointer, after the printf() statement, p
will be incremented by one.

The incrementing happens during, not after, the statement in question,
however. (I realise that this may just be unfortunate wording on your
part.) Precisely where the incrementing happens is up to the compiler, as
long as it's between the surrounding sequence points.
 
J

John Bode

raghu said:
Its not at all clear....still confusing

Doesn't help that the charts got screwed up and don't display right.

Let's try again. Assume the following:

char a[5] = {0, 1, 2, 3, 4};
char *p;
char i;

Assume for the purpose of this example that the address of a is 0x8000,
which means the address of a[1] is 0x8001, a[2] is 0x8002, etc.

Lets start by setting p to point to a[0]:

p = a;

The value of p is 0x8000, and the value of *p is 0. Now we execute the
following statement:

i = *p++;

As I said earlier, the expression *p++ is evaluated as *(p++); the
indirection operator * is being applied to the result of the expression
p++, which evaluates to the current value of p (the side effect of
incrementing p is applied sometime before the end of the statement).
Therefore, after executing that statement, the value of i is 0, the
value of p is 0x8001, and the value of *p is 1.

Now we execute the following statement:

i = ++*p;

In this case, the expression is evaluated as ++(*p); the prefix ++
operator is being applied to the result of the expression *p. Since p
= 0x8001, which is the address of a[1], the result of *p is 1.
Therefore, after executing that statement, the value of i is 2, the
value of p is still 0x8001, but the value of *p is now 2.

As a last case, take the statement

i = *++p;

In this case, the expression is evaluated as *(++p); the indirection
operator is being applied to the result of the expression ++p. Since
the current value of p is 0x8001, the result of ++p is 0x8002, which is
the address of a[2], so the result of *(++p) is 2. After executing
this statement, the value if i is 2, the value of p is 0x8002, and the
value of *p is 2.

So basically, each of the above expressions is evaluated left-to-right.
In the first and third cases (*p++ and *++p), the pointer value is
being incremented, and in the second case (++*p) the value of the thing
being pointed to is being incremented.

Does that help any?
 
A

August Karlstrom

Malcolm skrev:
see how compact and expressive this notation is. The ++ is more binding than
the derefernece, but it is applied last. This is a reversal of normal rules
of mathematical notation, but is is extremely convenient.

What mathematical expressions are you thinking of?
You very
frequently want to use a pointer to step through an array.

But it's clearer (and just as fast with any decent compiler) to use an
array index.


August
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top