By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,599 Members | 1,184 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,599 IT Pros & Developers. It's quick & easy.

Basic pointers question

P: n/a
I'm trying to understand pointers in a little more detail, and have
written a test program (reproduced below) to experiment with passing
pointers between functions.

Thinking only about the variable x in main, I would expect the
following to happen:
- &x is passed to func_one, so int* p1x is pointing to x (int* p1x =
&x)
- func_one then dereferences p1x to increment x; at this point x = 1
- func_one passes p1x to func_two, so int* p2x = p1x and pointers p2x
and p1x both point to x
- func_two then dereferences p2x to increment x; at this point x = 2
- control passes back to main() and the value of x is printed

Therefore, I would expect this program to produce the output "x = 2; y
= 2; c = 1", but it doesn't. Can anyone provide any insight into why
this is the case?

Thanks in advance

Simon
--code follows --

#include <stdio.h>

void func_two (int* p2x, int* p2y)
{
*px ++;
*py ++;
}

void func_one (int* p1x, int* p1y, int* p1c)
{
*pc ++;
*px ++;
*py ++;
func_two (px, py);
}

int main (void)
{
int x, y, c, d;
x = y = c = 0;
func_one (&x, &y, &c);
printf("x = %d; y = %d; c = %d", x, y, c);
d = getchar();
return 0;
}

Nov 17 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Simon said:
I'm trying to understand pointers in a little more detail, and have
written a test program (reproduced below) to experiment with passing
pointers between functions.

Thinking only about the variable x in main, I would expect the
following to happen:
- &x is passed to func_one, so int* p1x is pointing to x (int* p1x =
&x)
- func_one then dereferences p1x to increment x; at this point x = 1
Here is your mistake. *p1x++ does not increment x (the int pointed to by
p1x)!

This is what happens. Firstly, we need to evaluate p1x++ (because the
grammar says so). The result of this evaluation is the prior value of p1x
(because ++ is POST-increment), and the side effect is to increment p1x at
some time before the next sequence point. The result of the evaluation, as
I say, is the /prior/ value of p1x, which is of course still a pointer to
your original int. The * is then applied to this pointer value, yielding
the value of x, with which you do nothing.

If you want to increment x through p1x, you can do this:

++*p1x;

or this:

(*p1x)++;

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
Nov 17 '06 #2

P: n/a

Richard Heathfield wrote:
Here is your mistake. *p1x++ does not increment x (the int pointed to by
p1x)!
Argh!!! - I new it was something simple! I forgot the relative binding
strengths of ++ and *.

Incidentally - there was another mistake in the code above which was
due to me mis-typing it into Google Groups. All now works perfectly -
thanks a lot for your help!

Simon

Nov 17 '06 #3

P: n/a
Simon wrote:
I'm trying to understand pointers in a little more detail,
There is hardly any detail to know. Really.
void func_two (int* p2x, int* p2y)
{
*px ++;
Dereference `px` and throw the value away. Increment `px`.

I suspect you meant `(*px)++`, which I would write as
`*px += 1` because I think that makes what's going on clearer.

--
Chris "hantwig efferko VOOM!" Dollin
"- born in the lab under strict supervision -", - Magenta, /Genetesis/

Nov 17 '06 #4

P: n/a

Richard Heathfield wrote:
Simon said:

This is what happens. Firstly, we need to evaluate p1x++ (because the
grammar says so). (*p1x)++;
I would request to kindly elaborate on this. I mean to say how from the
C grammar
we can determine this ? In some of the posts, that I read earlier in
this newsgroup
I came to know that C grammar does not specify any precedence. So,
using the C
grammar how post decrement operator is evaluated before the unary
(pointer) operator.
I was looking at the lex and yacc grammar of C, which I downloaded from
the
following links:
http://www.lysator.liu.se/c/ANSI-C-grammar-l.html (lex file)
http://www.lysator.liu.se/c/ANSI-C-g...ml#declaration (yacc
file)

Can you please explain how the expression (*p1x++) will be evaluated
using the
lex and yacc files at the above mentioned links ?

thanks a lot for any help in advance ....

Nov 17 '06 #5

P: n/a
ju**********@yahoo.co.in wrote:
>
Richard Heathfield wrote:
>Simon said:

This is what happens. Firstly, we need to evaluate p1x++ (because the
grammar says so). (*p1x)++;
I would request to kindly elaborate on this. I mean to say how from the
C grammar we can determine this ?
We look at the productions of the grammar and the meaning of the
constructs.
In some of the posts, that I read earlier in
this newsgroup I came to know that C grammar does not specify any precedence.
More accurately, the C grammar does not use the idea of "precedence"
to disambiguate its expression grammar. It just uses an unambiguous
grammar.

In the expression `*p++`, there are only a few productions of interest.
Here is a (strongly selected) view:

primary-expression:
identifier

postfix-expression:
postfix-expression ++
primary-expression

unary-expression:
unary-operator postfix-expression

unary-operator:
*
expression: ... eventually, unary-expression ...

We see from this that `*p++` /must/ be parsed as the unary-operator
`*` applied to the postfix-expression `p++`. There's no other way
to do it (the other productions of the grammar don't help).
So, using the C grammar how post decrement operator is evaluated
before the unary (pointer) operator.
The evaluation rules are different from the grammar. The grammar
says how expressions are /structured/. The evaluation rules tell
you how those structures are /evaluated/. They're in the
Standard, but I expect they're not in the gramamr files you
downloaded, since they're not part of the grammar.

To evaluate `*p++`, we evaluate the unary-expression with operator
`*` and operand `p++`, because that's how it is parsed. To evaluate
`*E`, we evaluate `E` and then dereference the result. Here `E` is
`p++`. To evaluate `X++`, we get the lvalue `X`, deliver its
current value, and note that we must increment `X` by the next
sequence point. So we return the value of `p` (which will be
dereferenced by the `*`) and will eventually increment in. In
the original post, `*p++` is the full expression forming the body
of the expression-statement `*p++;`, which supplies the sequence
point; after the semicolon, `p` will have been incrememented.

--
Chris "hantwig efferko VOOM!" Dollin
"Our future looks secure, but it's all out of our hands"
- Magenta, /Man and Machine/

Nov 17 '06 #6

P: n/a
In the expression `*p++`, there are only a few productions of interest.
Here is a (strongly selected) view:

primary-expression:
identifier

postfix-expression:
postfix-expression ++
primary-expression

unary-expression:
unary-operator postfix-expression

unary-operator:
*
expression: ... eventually, unary-expression ...

We see from this that `*p++` /must/ be parsed as the unary-operator
`*` applied to the postfix-expression `p++`. There's no other way
to do it (the other productions of the grammar don't help).
So, using the C grammar how post decrement operator is evaluated
before the unary (pointer) operator.The evaluation rules are different from the grammar. The grammar
says how expressions are /structured/. The evaluation rules tell
you how those structures are /evaluated/. They're in the
Standard, but I expect they're not in the gramamr files you
downloaded, since they're not part of the grammar.

To evaluate `*p++`, we evaluate the unary-expression with operator
`*` and operand `p++`, because that's how it is parsed. To evaluate
`*E`, we evaluate `E` and then dereference the result. Here `E` is
`p++`. To evaluate `X++`, we get the lvalue `X`, deliver its
current value, and note that we must increment `X` by the next
sequence point. So we return the value of `p` (which will be
dereferenced by the `*`) and will eventually increment in. In
the original post, `*p++` is the full expression forming the body
of the expression-statement `*p++;`, which supplies the sequence
point; after the semicolon, `p` will have been incrememented.
Thanks Chris for the nice explanation. thanks a lot.

Nov 17 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.