simple pointer question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lokman

    simple pointer question

    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;
    }


  • Jakob Bieling

    #2
    Re: simple pointer question

    "lokman" <lokman@fagi.ne t> wrote in message
    news:c5rdrn$a7h $1@nn-tk102.ocn.ad.jp ...
    [color=blue]
    > *p++; // <<- What is the difference between *p++ and p++ (both achieve
    > the same result) ?[/color]

    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)


    Comment

    • ak

      #3
      Re: simple pointer question

      On Sat, 17 Apr 2004 23:10:00 +0900, "lokman" <lokman@fagi.ne t> wrote:
      [color=blue][color=green]
      >>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;
      >>}
      >>[/color][/color]

      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

      Comment

      • Frane Roje

        #4
        Re: simple pointer question

        "lokman" <lokman@fagi.ne t> wrote in message
        news:c5rdrn$a7h $1@nn-tk102.ocn.ad.jp ...[color=blue]
        > 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 ![/color]

        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++<<end l;

        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


        Comment

        • Kevin Goodsell

          #5
          Re: simple pointer question

          lokman wrote:
          [color=blue]
          > 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";[/color]

          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.
          [color=blue]
          > while (*p) {
          > cout << *p;
          > *p++; // <<- What is the difference between *p++ and p++ (both achieve
          > the same result) ?
          > }
          > cout << endl;
          > return 0;
          > }
          >
          >[/color]

          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.

          Comment

          • Kevin Goodsell

            #6
            Re: simple pointer question

            Jakob Bieling wrote:
            [color=blue]
            > "lokman" <lokman@fagi.ne t> wrote in message
            > news:c5rdrn$a7h $1@nn-tk102.ocn.ad.jp ...
            >
            >[color=green]
            >> *p++; // <<- What is the difference between *p++ and p++ (both achieve
            >>the same result) ?[/color]
            >
            >
            > p ++ increments the pointer, like you expect. *p ++ first dereferences
            > the pointer, and then increments it.[/color]

            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.

            Comment

            • Kevin Goodsell

              #7
              Re: simple pointer question

              Frane Roje wrote:
              [color=blue]
              > "lokman" <lokman@fagi.ne t> wrote in message
              > news:c5rdrn$a7h $1@nn-tk102.ocn.ad.jp ...
              >[color=green]
              >>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 ![/color]
              >
              >
              > Ok,
              > p++ increments the pointer
              > *p gets the contents of the variable to which the pointer is pointing to[/color]

              Actually it gets the variable itself. "Contents of" sounds like a copy.
              [color=blue]
              >
              > You could write in your loop
              > cout<<*p++<<end l;
              >
              > 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)[/color]

              (*p)++ has a completely different meaning than *p++.
              [color=blue]
              >
              > Maybe an example of copying two strings;
              >
              > char *s1="test";
              > char *s2="blab";[/color]

              Make these const char *.
              [color=blue]
              >
              > for(unsigned int i=0;i<strlen(s1 );i++)
              > *s1++=*s2++;[/color]

              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.

              Comment

              • Benoit Mathieu

                #8
                Re: simple pointer question

                [color=blue]
                > while (*dest++ = *src++) { continue; }[/color]

                Would you find this one less readable ?

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

                Benoit

                Comment

                • Kevin Goodsell

                  #9
                  Re: simple pointer question

                  Benoit Mathieu wrote:
                  [color=blue]
                  >[color=green]
                  >> while (*dest++ = *src++) { continue; }[/color]
                  >
                  >
                  > Would you find this one less readable ?
                  >
                  > while (*dest++ = *src++) ;
                  >[/color]

                  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.

                  Comment

                  • Frane Roje

                    #10
                    Re: simple pointer question

                    "Kevin Goodsell" <usenet2.spamfr ee.fusion@never box.com> wrote in message
                    news:rifgc.1491 4$k05.12126@new sread2.news.pas .earthlink.net. ..[color=blue]
                    > Frane Roje wrote:[/color]
                    [color=blue]
                    > (*p)++ has a completely different meaning than *p++.[/color]

                    How?
                    [color=blue][color=green]
                    > > Maybe an example of copying two strings;
                    > >
                    > > char *s1="test";
                    > > char *s2="blab";[/color]
                    >
                    > Make these const char *.[/color]
                    if they were const wouldn't that make then disabled for any kind of change?
                    [color=blue][color=green]
                    > >
                    > > for(unsigned int i=0;i<strlen(s1 );i++)
                    > > *s1++=*s2++;[/color]
                    >
                    > This is wrong or otherwise ill-advised in several ways.[/color]

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

                    [color=blue]
                    > 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:[/color]

                    --
                    Frane Roje

                    Have a nice day

                    Remove (*dele*te) from email to reply


                    Comment

                    • Jakob Bieling

                      #11
                      Re: simple pointer question

                      "Frane Roje" <frane.roje(*de le*te)@st.htnet .hr> wrote in message
                      news:c5s2jq$qvk $1@ls219.htnet. hr...[color=blue]
                      > "Kevin Goodsell" <usenet2.spamfr ee.fusion@never box.com> wrote in message
                      > news:rifgc.1491 4$k05.12126@new sread2.news.pas .earthlink.net. ..[color=green]
                      > > Frane Roje wrote:[/color]
                      >[color=green]
                      > > (*p)++ has a completely different meaning than *p++.[/color]
                      >
                      > How?[/color]

                      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 ..
                      [color=blue][color=green][color=darkred]
                      > > > Maybe an example of copying two strings;
                      > > >
                      > > > char *s1="test";
                      > > > char *s2="blab";[/color]
                      > >
                      > > Make these const char *.[/color]
                      > if they were const wouldn't that make then disabled for any kind of[/color]
                      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.
                      [color=blue][color=green][color=darkred]
                      > > >
                      > > > for(unsigned int i=0;i<strlen(s1 );i++)
                      > > > *s1++=*s2++;[/color]
                      > >
                      > > This is wrong or otherwise ill-advised in several ways.[/color]
                      >
                      > What is advised?(exepct for strcpy(), or maybe strncpy()(I'm not sure if
                      > this one
                      > exists))
                      >[color=green]
                      > > 1) The technically correct type to use is size_t.[/color]
                      > Isn't size_t actualy an unsigned integer?[/color]

                      Not necessarily in all implementations .
                      [color=blue][color=green]
                      > > 3) Prefer pre-increment to post-increment.[/color]
                      > Why?[/color]

                      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)


                      Comment

                      • Kevin Goodsell

                        #12
                        Re: simple pointer question

                        Frane Roje wrote:
                        [color=blue]
                        > "Kevin Goodsell" <usenet2.spamfr ee.fusion@never box.com> wrote in message
                        > news:rifgc.1491 4$k05.12126@new sread2.news.pas .earthlink.net. ..
                        >[color=green]
                        >>Frane Roje wrote:[/color]
                        >
                        >[color=green]
                        >>(*p)++ has a completely different meaning than *p++.[/color]
                        >
                        >
                        > How?[/color]

                        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.
                        [color=blue]
                        >
                        >[color=green][color=darkred]
                        >>>Maybe an example of copying two strings;
                        >>>
                        >>>char *s1="test";
                        >>>char *s2="blab";[/color]
                        >>
                        >>Make these const char *.[/color]
                        >
                        > if they were const wouldn't that make then disabled for any kind of change?[/color]

                        That's the idea. Any change causes undefined behavior, so preventing it
                        is a Good Thing.
                        [color=blue]
                        >
                        >[color=green][color=darkred]
                        >>>for(unsign ed int i=0;i<strlen(s1 );i++)
                        >>> *s1++=*s2++;[/color]
                        >>
                        >>This is wrong or otherwise ill-advised in several ways.[/color]
                        >
                        >
                        > What is advised?(exepct for strcpy(), or maybe strncpy()(I'm not sure if
                        > this one
                        > exists))
                        >
                        >[color=green]
                        >>1) The technically correct type to use is size_t.[/color]
                        >
                        > Isn't size_t actualy an unsigned integer?[/color]

                        Yes, but not necessarily unsigned int.
                        [color=blue]
                        >
                        >[color=green]
                        >>3) Prefer pre-increment to post-increment.[/color]
                        >
                        > Why?[/color]

                        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.

                        Comment

                        • DaKoadMunky

                          #13
                          Re: simple pointer question

                          >'p' is scheduled to be incremented at some point before the[color=blue]
                          >next sequence point[/color]

                          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

                          Comment

                          • Victor Bazarov

                            #14
                            Re: simple pointer question

                            "DaKoadMunk y" <dakoadmunky@ao l.com> wrote...[color=blue][color=green]
                            > >'p' is scheduled to be incremented at some point before the
                            > >next sequence point[/color]
                            >
                            > 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[/color]
                            sure.

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

                            V


                            Comment

                            • lokman

                              #15
                              Re: simple pointer question

                              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" <lokman@fagi.ne t> wrote in message
                              news:c5rdrn$a7h $1@nn-tk102.ocn.ad.jp ...[color=blue]
                              > 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;
                              > }
                              >
                              >[/color]


                              Comment

                              Working...