Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Question about pointers in C.

  1. Jul 5, 2007 #1


    User Avatar
    Gold Member

    if i have declared int *p
    and afterwards, in the progress of the programme iv'e typed
    ++p or p++
    is there any difference between and what exactly is the difference?

    thanks advance.
  2. jcsd
  3. Jul 5, 2007 #2
    yes postfix and prefix...i can never remmeber if the post/pre imply the ++ or p

    ++p will increment the pointer and then perform the operation you ask it

    p++ will increment the pointer after performing the opreation you ask it

    you can always try
    x=++p; printf("...",*x); printf("%p",x);
    x=p++; printf("...",*x); printf("%p",x);

    in C: printf("%p",x); is your friend unless you know how to use a debugging program.
  4. Jul 5, 2007 #3
    Yes. Since P is a memory address as a pointer, heres why:

    If you do something to P, say :
    P = (P++)*5;
    Then P will be equal to 25.

    If you do
    P = (++P)*5;

    It calculates ++P BEFORE the operations are performed, and that P is incremented.
    So you should get P=30;

    Either way they both permanently change P (until you change it back). Its a matter of whenter its ++before or after++ the operation line.

    "--" works the same way.
  5. Jul 5, 2007 #4

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    It could also be 20, 30, 1024, or any random value. What you just posted is a classical example of an undefined construct in C. This code could even make a http://catb.org/~esr/jargon/html/N/nasal-demons.html" [Broken].
    Last edited by a moderator: May 3, 2017
  6. Jul 5, 2007 #5
    Hmm, why? I'm not a super programmer.

    Ahh, I see.
    Yeah, forgot i was working with a pointer there for a moment.

    Same idea, but P++ will increment the pointer to point to the next memory address.
  7. Jul 5, 2007 #6


    User Avatar
    Gold Member

    so if p is in cell 1200, and
    for int x=20;
    then int y=++p;
    is y==1201, and int y=p++; is y==21, or something else?
  8. Jul 5, 2007 #7

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    Forget the pointer business for a while. Your little code snippets such as
    P = (P++)*5;
    invoke unspecified behavior because both the = and ++ operators alter the value of P. Which one should the compiler use? The language specification doesn't say which. The language specification says that this kind of statement is illegal, and illegal in a very nasty way. The compiler can do ANYTHING with statements that invoke unspecified behavior, including nothing at all or wiping your disk drive, and still be in full compliance with the standard.
  9. Jul 5, 2007 #8
    If the difference between ++p and p++ matters, then you must use the appropriate one. However, in those cases where it does not matter, I always use ++p. The reason is that I got into the habit back in the day when there was a performance gain by doing so. Compilers used to dereference a variable twice (for instance p [x[k]][y[k]] takes a lot of dereferencing) for post-increment, but only once for preincrement. With optimizing compilers, the issue has gone away, but the habit remains. Also, someone has noted that ++p reads increment p which sounds better than p++ which reads p increment.
  10. Jul 5, 2007 #9
    lqg: are u using a textbook for a class? or learning on your own?

    the equations you are giving us are operations acting on both (int) and (int*).
    Or in generic terms (datatype) and (datatype*)

    As stated in someone's post above this will produce erroneous data...

    if p is a ptr: it will always produce an address so in your example 1200 or incremented. Go back to your own example and reread it as that..."p is always a ptr" and try to figure out p++ and ++p where "p is a ptr". To dereference(hope thats the right term) a ptr you use the * (eg *p) and this gives you the datatype of the ptr.

    when you implement code in C...your operations should be acting on the same datatype (where ptr is also a datatype) similar to the concepts of operators in algebra

    since ++ is unary...it takes a datatype and returns the same datatype.

    if you try y=p++ you are acting on 2 different datatypes. Correct that statement as suggested above and then you should be able to figure out the postfix/prefix...Try the example i posted in my first thread where x,p are ptrs to the same datatype and the ... represents the datatype you chosen for printf.
  11. Jul 5, 2007 #10


    User Avatar
    Gold Member

    what about the next thing
    int *ptr,ii,jj;
    int arrayInts[]={4,6,8,9,10,12,14,15,16,18};
    ii=++ptr; jj=ptr++;
    printf("%d", ii-jj);
    what will be printed if the first place of the array is in 1200.

    naively i think that zero, but im not sure, this is why asked if there's a difference.

    im learning from colourful lecture notes. (-:
  12. Jul 5, 2007 #11


    User Avatar

    Just for those that might be asking or wondering.

    An increment (++p OR p++) increment the address pointed to by p by sizeof( type pointed to by p ) amount. So ++c where c is a char* and c points to say 1234 beforehand, afterwards will point to 1235, whereas ++i where i is an int* will cause i to point to an address of at least 1236. (*at least* because C doesn't guarantee the size of the integer types (apart from char), so it could be 1237, or 1238, or ... etc.) But then, you shouldn't be worrying about the actual physical address a pointer is pointing to!
  13. Jul 5, 2007 #12


    User Avatar

    Bad, bad, bad.

    ptr is a pointer to an int. ii and jj is an int, not a pointer!

    Code (Text):
    int *ptr, *ii, *jj;
    Or use separate lines when you're declaring pointers to avoid such errors!
  14. Jul 5, 2007 #13
    Hi loop q g

    Yeah, you are right. You will get zero.
    When you write,
    It means ii=1200+2=1202

    But when you write
    It means jj=1202
    Only after jj has been assigned the value 1202, does the value of p increment to 1204.

    So, ii-jj=1202-1202=0.
    That's what will be printed on the screen.

    You know, when I read the expression,
    I thought "what the heck is going on?". I write in C++, which considers such an expression as an error: Error: cannot convert from *ptr to ptr.
    But when I tried it in C, I was surprised to see that it worked perfectly. So, I think that C-programers will just have to take it in their stride. But such erronous conversions can be quite harmful for your system (it can crash!).
    I think this is one of the shortcomings of C.

    Mr V
    Last edited: Jul 5, 2007
  15. Jul 5, 2007 #14


    User Avatar
    Homework Helper

    With ++p, p and the pointer value used are incremented before being used. With p++, the existing value of p is used, and after being used, p is incremented. This is a throwback to machine specific instruction sets, which included pre and post incrementing and decrementing, and the authors of C decided to implement this feature into the C language.

    In many machine languages, stack "pushes" are implemented as "*(--p) = value", and stack "pops" are implemented as "value = *(p++)".

    Getting back on topic.

    int array[5] = {1, 2, 3, 4, 5}l
    int *p = array;
    int i;

    The statement:
    i = *(++p);

    Is the equivalent of:

    p += 1;
    i = *(p);

    The statement:
    i = *(p++);

    Is the equivalent of:

    i = *(p);
    p += 1;
  16. Jul 5, 2007 #15


    User Avatar

    Please see my first post. That statement is not guarantee to be true (even if we assume ii to be of type int*). See http://www.jk-technology.com/c/inttypes.html" for what is actually guarantee by the language in terms of the size of the integer types.
    Last edited by a moderator: Apr 22, 2017
  17. Jul 5, 2007 #16
    Er.. I was not guaranteeing anything. Just before posting the reply, I checked it all on my TC compiler, and the program ran perfectly.

    You are right about integer sizes. For example, Dev C/C++ uses 4 bytes, TC uses 2 bytes, VC++ uses 4 bytes again. And not only integers, even pointers are provided 4 bytes in modern compilers.

    You are also right that we cannot convert a pointer into an integer, or vice versa, simply because a pointer stores data in quite a different form than an integer, and we are forcing the compiler to implicitly perform conversion from one data type to another.
    For example, if we write,
    int i, *ptr; ..1
    i=ptr; ..2
    ptr=i; ..3

    In line 2, I am forcing the compiler to convert data stored in pointer-form, into data which can be stored in an integer. The compiler may be successful in doing so at some times, but may fail miserably on many occasions, leading to wrong results or system failure.

    Didn't I mention in my post that C should actually forbid this type of conversion. I am totally against such faulty techniques. But lqg was asking a question, and I told him what the right answer would be, if everything went right inside the computer.

    warm regards
    Mr V
  18. Jul 5, 2007 #17


    User Avatar
    Homework Helper

    This is getting a bit off topic, but in enviroments with memory mapped I/O or similar situations, declaring pointers to fixed locations in a processors memory map requires type casting of an integer to a pointer, for example on a 32 bit machine where usigned longs and pointer are both 32 bits:

    #define PTR2PORT1234 = ((volatile unsigned char*)0xFFFF1234ul)

    which allows this usage:

    value = *PTR2PORT1234;
    *PTR2PORT1234 = value;
    value = PTR2PORT1234;
    PTR2PORT1234 = value;
  19. Oct 13, 2007 #18
    Those are the exact same since the ++ is in a completely different expression from the printf call.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook