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

simple pointer question

P: n/a
Hi,

In the following code, can someone tell me the difference between *p++ and
p++ ? I can see both achieve the same result.

Thanks a lot !


#include <iostream>
using namespace::std;
int main() {
char *p = "test pointer";
while (*p) {
cout << *p;
*p++; // <<- What is the difference between *p++ and p++ (both achieve
the same result) ?
}
cout << endl;
return 0;
}
Jul 22 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk102.ocn.ad.jp...
*p++; // <<- What is the difference between *p++ and p++ (both achieve
the same result) ?


p ++ increments the pointer, like you expect. *p ++ first dereferences
the pointer, and then increments it. Since the dereferenced temporary is not
assigned to anything, it is discarded.

hth
--
jb

(replace y with x if you want to reply by e-mail)
Jul 22 '05 #2

P: n/a
ak
On Sat, 17 Apr 2004 23:10:00 +0900, "lokman" <lo****@fagi.net> wrote:
Hi,

In the following code, can someone tell me the difference between *p++ and
p++ ? I can see both achieve the same result.

Thanks a lot !


#include <iostream>
using namespace::std;
int main() {
char *p = "test pointer";
while (*p) {
cout << *p;
*p++; // <<- What is the difference between *p++ and p++ (both achieve
the same result) ?
}
cout << endl;
return 0;
}


in this context there is no diff.

if you would for instance do a cout << *p++
then it would print p's current char and then
incr the ptr

*p get the value from the ptr
++ incr the ptr with whatever size of type it is.

/ak
Jul 22 '05 #3

P: n/a
"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk102.ocn.ad.jp...
Hi,

In the following code, can someone tell me the difference between *p++ and
p++ ? I can see both achieve the same result.

Thanks a lot !


Ok,
p++ increments the pointer
*p gets the contents of the variable to which the pointer is pointing to

You could write in your loop
cout<<*p++<<endl;

Because of the precedence of the * operator so the *p is done before p++,
maybe it would be more clear if you wrote (*p)++ (don't use this in coding
this is just for you to understand you should write *p++ in your code)

Maybe an example of copying two strings;

char *s1="test";
char *s2="blab";

for(unsigned int i=0;i<strlen(s1);i++)
*s1++=*s2++;

So the content of the s1 becomes the content of the s2;
Note that they are both the same size, if not you might have
undefined behavior.
But if you want to copy strign I would reccomed using <string>
rather than char*.

HTH
--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
Jul 22 '05 #4

P: n/a
lokman wrote:
Hi,

In the following code, can someone tell me the difference between *p++ and
p++ ? I can see both achieve the same result.

Thanks a lot !
#include <iostream>
using namespace::std;
int main() {
char *p = "test pointer";
Quick note: don't do this. Never make a (non-const) char pointer point
to a string literal. This conversion is allowed for C compatibility, but
is deprecated because it is dangerous. It allows you to write code that
(attempts to) modify a string literal without getting a warning from the
compiler. Modifying a string literal (or attempting to) invokes
undefined behavior.

If you want a pointer to a string literal, always use a pointer to const
char, like one of the following:

const char *p = "some string";
char const *p = "some string"; // same as prev

const char * const p = "some string";
char const * const p = "some string"; // same as prev

In the last two 'p' itself is also const.
while (*p) {
cout << *p;
*p++; // <<- What is the difference between *p++ and p++ (both achieve
the same result) ?
}
cout << endl;
return 0;
}


It looks like all the replies so far are wrong in one way or another.
The expression 'p++' causes p to be incremented at some point before the
next sequence point. It also has a result, which is the value of 'p'
before being incremented. There's an subtle but important point here:
you don't know *when* 'p' will actually be updated, only that it will
happen sometime before the next sequence point (usually a semi-colon,
but there are others). People frequently get this wrong.

As for the expression '*p++', it is equivalent to '*(p++)' (contrary to
what one of the other replies said, post-increment has higher precedence
than dereference -- check any precedence chart). So, as described
previously, 'p' is scheduled to be incremented at some point before the
next sequence point, and also a result is given. The result is the value
of 'p' prior to the increment. The '*' is applied to that, giving the
object that 'p' pointed to prior to the increment. This result is
immediately discarded in your case.

So there's no reason for the '*' in this case. It might even slow your
program down a little, so get rid of it.

Also, replace 'p++' with '++p'. Get in the habit of using pre-increment
in cases where either will work. There's a chance it will be faster, and
it almost certainly won't be slower. There probably is no difference for
built-in types, but for class types there may be a substantial difference.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #5

P: n/a
Jakob Bieling wrote:
"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk102.ocn.ad.jp...

*p++; // <<- What is the difference between *p++ and p++ (both achieve
the same result) ?

p ++ increments the pointer, like you expect. *p ++ first dereferences
the pointer, and then increments it.


Nitpick: That sequence of events is not required.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #6

P: n/a
Frane Roje wrote:
"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk102.ocn.ad.jp...
Hi,

In the following code, can someone tell me the difference between *p++ and
p++ ? I can see both achieve the same result.

Thanks a lot !

Ok,
p++ increments the pointer
*p gets the contents of the variable to which the pointer is pointing to


Actually it gets the variable itself. "Contents of" sounds like a copy.

You could write in your loop
cout<<*p++<<endl;

Because of the precedence of the * operator so the *p is done before p++,
maybe it would be more clear if you wrote (*p)++ (don't use this in coding
this is just for you to understand you should write *p++ in your code)
(*p)++ has a completely different meaning than *p++.

Maybe an example of copying two strings;

char *s1="test";
char *s2="blab";
Make these const char *.

for(unsigned int i=0;i<strlen(s1);i++)
*s1++=*s2++;


This is wrong or otherwise ill-advised in several ways.

1) The technically correct type to use is size_t.

2) Recalculating the length on each iteration is unnecessarily inefficient.

3) Prefer pre-increment to post-increment.

4) Modifying a string literal (which is a const object) gives undefined
behavior.

Besides that, the general approach is definitely not correct in general.
You'd need to check the relative length of the source string against the
available length of the destination buffer, then loop based on the
source string. If you knew the destination length was adequate, you
could just do this:

while (*dest++ = *src++) { continue; }

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #7

P: n/a
while (*dest++ = *src++) { continue; }


Would you find this one less readable ?

while (*dest++ = *src++) ;

Benoit
Jul 22 '05 #8

P: n/a
Benoit Mathieu wrote:
while (*dest++ = *src++) { continue; }

Would you find this one less readable ?

while (*dest++ = *src++) ;


I find it less clear. A semi-colon in a place where they aren't usually
seen can be easily missed, making the reader think that the 'while'
controls (or is supposed to control) some statement that follows. It can
also look like an error, as if the programmer added the semi-colon at
the end of the line out of habit.

An explicit 'continue' statement removes all doubt about the intent.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #9

P: n/a
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:ri*******************@newsread2.news.pas.eart hlink.net...
Frane Roje wrote: (*p)++ has a completely different meaning than *p++.
How?
Maybe an example of copying two strings;

char *s1="test";
char *s2="blab";


Make these const char *.

if they were const wouldn't that make then disabled for any kind of change?

for(unsigned int i=0;i<strlen(s1);i++)
*s1++=*s2++;


This is wrong or otherwise ill-advised in several ways.


What is advised?(exepct for strcpy(), or maybe strncpy()(I'm not sure if
this one
exists))
1) The technically correct type to use is size_t. Isn't size_t actualy an unsigned integer?
3) Prefer pre-increment to post-increment. Why?

Besides that, the general approach is definitely not correct in general.
You'd need to check the relative length of the source string against the
available length of the destination buffer, then loop based on the
source string. If you knew the destination length was adequate, you
could just do this:


--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
Jul 22 '05 #10

P: n/a
"Frane Roje" <frane.roje(*dele*te)@st.htnet.hr> wrote in message
news:c5**********@ls219.htnet.hr...
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:ri*******************@newsread2.news.pas.eart hlink.net...
Frane Roje wrote:

(*p)++ has a completely different meaning than *p++.


How?


Consider the following:

char test[] = "Hello";
char* p = test;

char t = *p ++;
char s = (*p) ++;

Now think about which values 's' and 't' will hold ..
Maybe an example of copying two strings;

char *s1="test";
char *s2="blab";


Make these const char *.

if they were const wouldn't that make then disabled for any kind of

change?

Right, because changing what they are pointing at is wrong. String
literals are constant, which is why you should use 'char const*' instead of
'char*' to enforce this constantness. See Kevin's reply to the OP for more
about this.

for(unsigned int i=0;i<strlen(s1);i++)
*s1++=*s2++;


This is wrong or otherwise ill-advised in several ways.


What is advised?(exepct for strcpy(), or maybe strncpy()(I'm not sure if
this one
exists))
1) The technically correct type to use is size_t.

Isn't size_t actualy an unsigned integer?


Not necessarily in all implementations.
3) Prefer pre-increment to post-increment.

Why?


Post-increment means:
1) Copy current value to temporary
2) Increment
3) Return the temporary from 1

Pre-increment means:
1) Increment:
2) Return self

So you see, pre-increment does the same (in your case), but does it
faster, ie. definitely not slower. There are cases where you actually do
need to post-increment, but in all others, prefer pre-increment. But again,
see Kevin's reply to the OP's message ;)

regards
--
jb

(replace y with x if you want to reply by e-mail)
Jul 22 '05 #11

P: n/a
Frane Roje wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:ri*******************@newsread2.news.pas.eart hlink.net...
Frane Roje wrote:
(*p)++ has a completely different meaning than *p++.

How?


Uh... Well, the former increments the thing pointed to and returns the
un-incremented value. The later increments the pointer and returns the
thing it pointed to before the increment.

Maybe an example of copying two strings;

char *s1="test";
char *s2="blab";
Make these const char *.


if they were const wouldn't that make then disabled for any kind of change?


That's the idea. Any change causes undefined behavior, so preventing it
is a Good Thing.

for(unsigned int i=0;i<strlen(s1);i++)
*s1++=*s2++;
This is wrong or otherwise ill-advised in several ways.

What is advised?(exepct for strcpy(), or maybe strncpy()(I'm not sure if
this one
exists))

1) The technically correct type to use is size_t.


Isn't size_t actualy an unsigned integer?


Yes, but not necessarily unsigned int.

3) Prefer pre-increment to post-increment.


Why?


Because it may be faster and is very unlikely to be slower.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #12

P: n/a
>'p' is scheduled to be incremented at some point before the
next sequence point


If 'p' is a user defined type would the point of incrementation be
well-defined?

It seems like it would be given that it is a function call, but I am not sure.

Brian F. Seaberg
Naperville, Illinois
Delray Beach, Florida
Jul 22 '05 #13

P: n/a
"DaKoadMunky" <da*********@aol.com> wrote...
'p' is scheduled to be incremented at some point before the
next sequence point


If 'p' is a user defined type would the point of incrementation be
well-defined?

It seems like it would be given that it is a function call, but I am not

sure.

You are correct. Some elements of C++ do offer "work-arounds" for
undefined behaviour. However, relying on them means building bad
habits...

V
Jul 22 '05 #14

P: n/a
Hi and thanks for the great help.

I have modified the simple code a little bit based on the reply.

And I have a question again. I know that instead of using pointer
arithmetic, I can access individual characters in this way: e.g. cout <<
p[5]; This will simply print the 5th character in the character array.
(Correct me if I am wrong please.).

My question is: Can someone please tell me what is the reason that if I do:
cout << p[5] << endl; before the while loop, it prints the charater "p", as
expected. But somehow, after the while loop, if I do : cout << p[5] << endl;
again, it cannot print the "p" character anymore.

Thanks a lot again.
// Code starts below.
#include <iostream>

using namespace::std;

int main() {

const char *p = "test pointer";

cout << p[5] << endl; // New piece of code

while (*p) { cout << *p; ++p;} // Modified ! I understand ++pp is a good
practice now, thanks !!
cout << endl;

cout << p[5] << endl; // New piece of code

return 0;
}


"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk102.ocn.ad.jp...
Hi,

In the following code, can someone tell me the difference between *p++ and
p++ ? I can see both achieve the same result.

Thanks a lot !


#include <iostream>
using namespace::std;
int main() {
char *p = "test pointer";
while (*p) {
cout << *p;
*p++; // <<- What is the difference between *p++ and p++ (both achieve
the same result) ?
}
cout << endl;
return 0;
}

Jul 22 '05 #15

P: n/a
"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk105.ocn.ad.jp...
Hi and thanks for the great help.

I have modified the simple code a little bit based on the reply.

And I have a question again. I know that instead of using pointer
arithmetic, I can access individual characters in this way: e.g. cout <<
p[5]; This will simply print the 5th character in the character array.
(Correct me if I am wrong please.).
It will actually print the 6th character .. p [0] prints the first, p
[1] prints the second and so on
My question is: Can someone please tell me what is the reason that if I do: cout << p[5] << endl; before the while loop, it prints the charater "p", as expected. But somehow, after the while loop, if I do : cout << p[5] << endl; again, it cannot print the "p" character anymore.

Thanks a lot again.
// Code starts below.
#include <iostream>

using namespace::std;

int main() {

const char *p = "test pointer";

cout << p[5] << endl; // New piece of code

while (*p) { cout << *p; ++p;} // Modified ! I understand ++pp is a good
Above you modifiy the pointer, ie the address it is pointing to.
practice now, thanks !!
cout << endl;

cout << p[5] << endl; // New piece of code
That means, that in the line above, p [5] means something different than
the p [5] before the loop, because the value of p is different.
return 0;
}


hth
--
jb

(replace y with x if you want to reply by e-mail)
Jul 22 '05 #16

P: n/a
"Jakob Bieling" <ne*****@gmy.net> wrote in message
news:c5*************@news.t-online.com...
Now think about which values 's' and 't' will hold ..
Yes I tried this code and it behaved correctly, I mean the out put
is
H e
But then I didn't know what was the difference so I did a little bit
different code:
char test[]="Hello";

char* p = test;

char t = *p++;

char s = (*p)++;

char u = (*p)++;

Now this outputs(remember the string is "Hello"):

H e f

So I was confused and did another test:

char test[]="Hello";

char* p = test;

char t = (*p)++;

char s = (*p)++;

char u = (*p)++;

And this outputs:

H I J

And I'm still confused, it seems like it outputs the alphabetically next
character.

I don't get it. Could someone clarify this? Not necessarily in all implementations.

So to be techically correct I should use size_t rather than unsigned int?

--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
Jul 22 '05 #17

P: n/a
Thanks !

I now understand that: During the while loop, pointer p is keep on changing
its memory address from the initial one which is point to character 't', up
to '\0'. That is the reason why after the while loop, if I put the statement
cout << p[5];, nothing will be return.

In odder to have point p to point to the start of the "test pointer"
characters, does it mean that I have to traverse p all the way back to where
it is pointing to initially (doesn't seem to work as I tested and doesn't
sound like a good practice) or should I reinitialize the p to point to "test
pointer again" ?
Actually, I have modified the previous code to become a version where I can
guarantee to get char number 6 before and after the while loop, please give
some comment.

Thanks a lot.
#include <iostream>

using namespace::std;

int main() {

char chr[] = "test pointer";
const char *p = chr; // constant character pointer to avoid chr[] content
being change

cout << p[5] << endl; // this prints p
cout << chr[5] << endl; // this prints p too !

while (*p) { cout << *p; ++p;}
cout << endl;

cout << chr[5] << endl; // this prints p after the while loop
cout << p[5] << endl; // this doesn't print the 6th char anymore

return 0;

}

"Jakob Bieling" <ne*****@gmy.net> wrote in message
news:c5*************@news.t-online.com...
"lokman" <lo****@fagi.net> wrote in message
news:c5**********@nn-tk105.ocn.ad.jp...
Hi and thanks for the great help.

I have modified the simple code a little bit based on the reply.

And I have a question again. I know that instead of using pointer
arithmetic, I can access individual characters in this way: e.g. cout <<
p[5]; This will simply print the 5th character in the character array.
(Correct me if I am wrong please.).
It will actually print the 6th character .. p [0] prints the first, p
[1] prints the second and so on
My question is: Can someone please tell me what is the reason that if I

do:
cout << p[5] << endl; before the while loop, it prints the charater "p",

as
expected. But somehow, after the while loop, if I do : cout << p[5] <<

endl;
again, it cannot print the "p" character anymore.

Thanks a lot again.
// Code starts below.
#include <iostream>

using namespace::std;

int main() {

const char *p = "test pointer";

cout << p[5] << endl; // New piece of code

while (*p) { cout << *p; ++p;} // Modified ! I understand ++pp is a

good
Above you modifiy the pointer, ie the address it is pointing to.
practice now, thanks !!
cout << endl;

cout << p[5] << endl; // New piece of code
That means, that in the line above, p [5] means something different

than the p [5] before the loop, because the value of p is different.
return 0;
}


hth
--
jb

(replace y with x if you want to reply by e-mail)

Jul 22 '05 #18

P: n/a
* Frane Roje <fr********@st.htnet.hr>:
"Jakob Bieling" <ne*****@gmy.net> wrote in message
news:c5*************@news.t-online.com...
Now think about which values 's' and 't' will hold ..
Yes I tried this code and it behaved correctly, I mean the out put
is
H e
But then I didn't know what was the difference so I did a little bit
different code:

Ok, so let's look at what this does exactly.
char test[]="Hello";

char* p = test; Now p holds the address of the first char in test.
char t = *p++; If you would have braces in here this would look something like this:
char t = *(p++);
First p is dereferenced and assigned to t.
Afterwards p is incremented by the length of one char.
So now it holds the address of the second char of test, which is 'e'.
char s = (*p)++; As before first the value p points to is assigned to s.
But now the value p points to is incremented, instead of p itself.
So you modify test directly, which now holds "Hfllo".
char u = (*p)++; Same as before but as test is modified yoiu get 'f';
After this line test should be "Hgllo"
Now this outputs(remember the string is "Hello"):

H e f

So I was confused and did another test: This should also become clear now.
char test[]="Hello";

char* p = test;

char t = (*p)++; Iello
char s = (*p)++; Jello
char u = (*p)++; Kello
And this outputs:

H I J

And I'm still confused, it seems like it outputs the alphabetically next
character.

I don't get it. Could someone clarify this?

Hope i succeeded.

David

--
,' David Riebenbauer - Student at Technichal University of Graz ~~~|
/' / da*****@sbox.tugraz.at /_,~""~""/ ICQ: 322056002 -\/- Playlist: |
< /' Fernbedienung ~= Macht ,/'*','* '/ Die geht euch nichts an! |
/\/\/\/\/\/\/\/\/\/\/\/\/\/' /)/(\ |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Jul 22 '05 #19

P: n/a
"David Riebenbauer" <da*****@sbox.tugraz.at> wrote in message
news:40***********************@aconews.univie.ac.a t...
Yes you made it clear.
It seems I've learned something wrong and it would be very bad if I hadn't
found it now and then years later did.
Anyway thanx

--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
Jul 22 '05 #20

P: n/a
David Riebenbauer wrote:
char t = *(p++);
First p is dereferenced and assigned to t.
Afterwards p is incremented by the length of one char.


As I've mentioned a few times in this thread, this sequence of events is
not required. In the expression 'p++' only the following is required:

* The resulting value is equal to the value of the expression 'p' --
that is, if you used 'p' instead of 'p++', the result would be the same,
other than the side-effects.

* As a side-effect, 'p' will be updated to point to the next character
sometime before the next sequence point.

There is no constraint on when the increment will occur, other than the
requirement that it occurs before the next sequence point.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #21

P: n/a
lokman wrote:
Thanks !
Please stop top-posting, and trim the quoted text down to the relevant
part. Read section 5 of the FAQ for posting guidelines.

I now understand that: During the while loop, pointer p is keep on changing
its memory address from the initial one which is point to character 't', up
to '\0'. That is the reason why after the while loop, if I put the statement
cout << p[5];, nothing will be return.
It's not accurate to say "nothing will be return". The behavior is
undefined. You cannot wildly index past the end of an array.

In odder to have point p to point to the start of the "test pointer"
characters, does it mean that I have to traverse p all the way back to where
it is pointing to initially (doesn't seem to work as I tested and doesn't
sound like a good practice) or should I reinitialize the p to point to "test
pointer again" ?
If you iterate backward, how will you know when you've reached the
beginning? The smart thing to do would be to save your original pointer
if you still need it:

const char * const the_string = "some literal";
const char *p = the_string;

// now use 'p' however you want

p = the_string;

You could reassign the same literal again, but 1) it's not guaranteed to
be the same address and 2) duplicating parts of the code like that leads
to problems later. When you change one, you have to be sure to change
the other, and it's not obvious that the two are related.


Actually, I have modified the previous code to become a version where I can
guarantee to get char number 6 before and after the while loop, please give
some comment.

Thanks a lot.
#include <iostream>

using namespace::std;

int main() {

char chr[] = "test pointer";
const char *p = chr; // constant character pointer to avoid chr[] content
being change
Just so we're clear, you don't *need* to have 'const' here -- that is,
it would not be an error (from the language's point of view) if you
modified the thing p points to. If it's not what you want your program
to do, that's fine. But you could if you wanted to.

cout << p[5] << endl; // this prints p
cout << chr[5] << endl; // this prints p too !

while (*p) { cout << *p; ++p;}
cout << endl;

cout << chr[5] << endl; // this prints p after the while loop
cout << p[5] << endl; // this doesn't print the 6th char anymore
This gives undefined behavior.

return 0;

}


-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #22

P: n/a
* Kevin Goodsell <us*********************@neverbox.com>:
David Riebenbauer wrote:
char t = *(p++);
First p is dereferenced and assigned to t.
Afterwards p is incremented by the length of one char.


As I've mentioned a few times in this thread, this sequence of events is
not required. In the expression 'p++' only the following is required:

* The resulting value is equal to the value of the expression 'p' --
that is, if you used 'p' instead of 'p++', the result would be the same,
other than the side-effects.

* As a side-effect, 'p' will be updated to point to the next character
sometime before the next sequence point.

There is no constraint on when the increment will occur, other than the
requirement that it occurs before the next sequence point.


Ok, thanks for making this clear again.

David

--
,' David Riebenbauer - Student at Technichal University of Graz ~~~|
/' / da*****@sbox.tugraz.at /_,~""~""/ ICQ: 322056002 -\/- Playlist: |
< /' Fernbedienung ~= Macht ,/'*','* '/ Die geht euch nichts an! |
/\/\/\/\/\/\/\/\/\/\/\/\/\/' /)/(\ |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Jul 22 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.