2

Below is the code for which I want to know the answer to 2 questions in the side comment. Please help me

#include<iostream>

using namespace std;

int main()
{
    char *p="Hello";
    cout <<*p;     //gives H
    cout <<*(p++); //also gives H.Why?
    cout <<*(p++); //gives e.
    cout <<*(p++); //gives l.
    cout <<*(p++); //gives l.
    cout <<*(p++); //gives o.
    cout <<*(p++); //gives no output.Why? It should give some garbage value!
}
6
  • Make that const char *, not char *. Commented Jul 25, 2013 at 6:14
  • @chris : That's a different issue.I want to understand the strange output for current code. Commented Jul 25, 2013 at 6:15
  • p++ means post increment , first value is taken , then incremented Commented Jul 25, 2013 at 6:15
  • Look up the postfix increment operator. x++ returns the old value of x and increments it. Also look up null termination. Commented Jul 25, 2013 at 6:16
  • To all those who gave answer to the second part using the cocept hello\0.Let me ask If I add another line cout <<*(p); i still get no output ,instead of some garbage.Is it related to undefined behaviour? Commented Jul 25, 2013 at 6:34

8 Answers 8

4

*(p++) gives 'h' because you first ask the value and than increment the position of your pointer and it the same thing in the last line.

Sign up to request clarification or add additional context in comments.

5 Comments

But won't the p++ executed first as its inside the bracket
Postfix op returns original value. Prefix returns incremented
no the incremtation is done after the value of the point is give to operation
The value of the expression p++ is the value of p before the increment. Doesn't matter how many parentheses are involved.
More explicitly, (p++) returns a copy of the value of p and that copy is dereferenced by *; at any time after the copy is made, the ++ can take affect of p - that could be before or after the dereferencing because () doesn't create a "sequence point", but it doesn't matter when p is incremented because it's copy of the pre-increment value of p that will be dereferenced. It may help understanding to consider a typical user-defined post-increment implementation: T& operator++(int) { T copy(*this); ++*this; return copy; }.
4
  1. If you use p++ anywhere in your code, say:

    <some code> p++ <some code>
    

    It's equivalent to

    <some code> p <some code>;
    p = p + 1;
    

    In contrast, if you write:

    <some code> ++p <some code>
    

    It's equivalent to

    p = p + 1;
    <some code> p <some code>
    

    That should answer your first question.

  2. The C-style strings automatically end with a \0 character. So if you declare:

    char *p="Hello";
    

    The compiler automatically adds a \0 to the end of that string for you (otherwise functions like printf would not know, when the string finishes). So your string is actually:

    "Hello\0"
    

    If you try to push the pointer further though, you will end up in invalid memory and you might encounter anything (garbage, which may be a series of zeros as well)

4 Comments

No undefined behavior here. The sixth character of "Hello" is '\0', every time, guaranteed.
I downvoted, because you're wrong. The sixth character of "Hello" is '\0'. Nothing undefined at all.
@LeeDanielCrocker I was mislead by OP's cout <<*(p++); //gives 0 (instead of //gives o). Indeed, he is still in the valid memory. My mistake. Edited the answer.
+1 for a good overall explanation, but you don't address - of cout << '\0' - "gives no output.Why? It should give some garbage value!". Actually, what the terminal chooses to do when fed a NUL is not defined by the C++ Standard, so it could have been garbage, clearing the screen, nothing etc..
3

What p++ does is increment p and return the old value of p, so *(p++) will always return the character stored at *p and after the statement *p will point to the next character.

cout <<*(p++); //gives 0.

This does not actually give 0, it gives the character "o", the last character in Hello.

cout <<*(p++); //gives no output.Why? It should give some garbage value!

This outputs the NUL character '\0' that terminates the string. It's a non-printable character, and where you're seeing this output you don't see any probably because the software decides to not print non-printables. If you look at the hex dump of the output for example you could see the NUL right after the o:

00000000  48 48 65 6c 6c 6f 00                              |HHello.|

If you added yet another cout <<*(p++) you might see garbage output, or the program might crash, or something else might happen, because it would be "undefined behavior."

4 Comments

:Thanks for your support Sir.How can I see the hex dump?I am using linux with g++.
Pipe the program's output to hd or to hexdump -C like this: programname | hexdump -C
What do those 00000000 at the beginning denote?
It's the seek offset, a 0-based position of the data in the file. Position 0 is the beginning.
3

Doing p++ actually requests the value, and then increment it. If you'd like to increment it then get the value incremented, use ++p.

For your last question, the last value of a C string is always '\0'. That print nothing on the terminal in most case, but this is undefined behavior by the C++ Standard.

1 Comment

"'\0'. That print nothing on the terminal." - we're told that's the case here for Insane Coder, but the behaviour's not defined by the C++ Standard and it printing nothing is not something that should be relied upon.
1

The first *(p++) gives "H" because the ++ operator is defined to give its current value first, then do the increment. The final *(p++) returns the character '\0', because the string literal "Hello" points to an array of SIX characters, the last of which is '\0'.

Comments

1

It's because when using the post-increment (such as your p++), the value is evaluated before the increment is done.

So in your code, your first cout << *(p++); will print 'H' because it will evaluate the value of p before the assignment, which is the address of p, and then the value of p is incremented.

To increment the value of p before it is evaluated, use pre-incremental ++p.

So this is what would happen in your code:

int main()
{
    char *p="Hello";
    cout <<*p;     //gives H
    cout <<*(++p); //this time it will give e
    cout <<*(++p); //gives l.
    cout <<*(++p); //gives l.
    cout <<*(++p); //gives o.
    cout <<*(++p); //gives no output since the character after a string is always \0 (credit to answer below)
}

Hope this helps! =D

1 Comment

It shouldn't give garbage. It gives '\0' because all string literals end with '\0'.
0

Do this:

{
    char *p="Hello";
    cout <<*p;     //gives H.
    cout <<*(++p); //gives e.
    cout <<*(++p); //gives l.
    cout <<*(++p); //gives l.
    cout <<*(++p); //gives o.
    cout <<*(++p); //gives 0.
    cout <<*(++p); //will either be a garbage value or throw an exception
}

The ++p will increment the pointer, and then return the value. p++ pushes the value on the stack, increments the pointer, and pops the stack to return it. It might also use a register; the implementation details are kind of up to the compiler.

Comments

0
char *p="Hello";
cout <<*p;     //gives H
cout <<*(p++); //also gives H.Why?

Because post increment will increment p AFTER evaluation. To increment p BEFORE evaluation, use *(++p)

cout <<*(p++); //gives e.
cout <<*(p++); //gives l.
cout <<*(p++); //gives l.
cout <<*(p++); //gives 0.
cout <<*(p++); //gives no output.Why? It should give some garbage value!

There's a padding \0 in every C-style strings.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.