1

I have the following code in C (I'm using tdm-gcc 4.9.1 and Netbeans 8.0.2):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * pr(char * str);

int main(void)
{
    char * x;

    x = pr("Ho Ho Ho!");

    return 0;
}

//*************************************

char * pr(char * str)
{
    char * pc;

    pc = str;

    while (* pc)
    {
        putchar(* pc++);
        printf(" %d %d\n", pc, str);
    }

    printf("\n");
    printf(" %d %d\n", pc, str);  
    printf("\n");

    do 
    {
        putchar(* pc--); // alternate case: * --pc
        printf(" %d %d\n", pc, str);
    } while (pc - str);

    return (pc);
}

In the do-while loop, when the argument inside the putchar function is

* pc--

I have the following result printed (1st column prints the string "Ho Ho Ho!", one character at a time, 2nd column prints the address of pointer-to-char pc, whereas the 3rd column prints the address of pointer to char str:

H 4206629 4206628
o 4206630 4206628
  4206631 4206628
H 4206632 4206628
o 4206633 4206628
  4206634 4206628
H 4206635 4206628
o 4206636 4206628
! 4206637 4206628

 4206637 4206628

 4206636 4206628
! 4206635 4206628
o 4206634 4206628
H 4206633 4206628
  4206632 4206628
o 4206631 4206628
H 4206630 4206628
  4206629 4206628
o 4206628 4206628

or

Ho Ho Ho!!oH oH o

When the argument inside the putchar function is

* --pc

The corresponding result is

H 4206629 4206628
o 4206630 4206628
  4206631 4206628
H 4206632 4206628
o 4206633 4206628
  4206634 4206628
H 4206635 4206628
o 4206636 4206628
! 4206637 4206628

 4206637 4206628

! 4206636 4206628
o 4206635 4206628
H 4206634 4206628
  4206633 4206628
o 4206632 4206628
H 4206631 4206628
  4206630 4206628
o 4206629 4206628
H 4206628 4206628

or

Ho Ho Ho!!oH oH oH

My question is as follows: What's the difference between the postfix and the prefix decrement operator regarding the output of the putchar function inside the do-while loop?

Any feedback would be greatly appreciated.

1 Answers1

4

The answer to your question is in the names: prefix does something before, and postfix does something after.

In short:

  • Prefix increment/decrement does the incement/decrement before giving you the result of that increment/decrement.
  • Postfix increment/decrement gives you the old value and then does the increment/decrement.

This works the same no matter what type of variable you perform the operation on.


Lets say you have the string

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

then doing

*++p

will increment the pointer p (making it point to the 'e' character in the string) and then dereference that pointer, giving you the character 'e'.

If you then do

*p--

then the pointer is first dereferenced and you get the 'e' character (again) and then the pointer is decremented and points to the first character again.


Using your new example in the comment, the statement putchar(*++string); is equivalent to

string = string + 1;
putchar(*string);

And the statement putchar(*string++); is equivalent to

char *compiler_generated_temporary_variable = string;
string = string + 1;
putchar(*compiler_generated_temporary_variable);

Note the order in which the increment is done.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks for the feedback. I'm new to C, so I'm using %d specifier for printing the pointers, so as to track down more easily the decrement process. I understand how prefix and postfix work, what I don't understand is how they affect the result of the putchar function I mentioned at my question. In the prefix case, the "!" character corresponds to the address 4206636, whereas in the postfix counterpart, the pointer is decremented to the address 4206636 as expected, but the "!" character is printed next to the address 4206635. – Urovoros Ofis Sep 25 '15 at 11:33
  • This thread - https://stackoverflow.com/questions/5209602/pointer-arithmetic-ptr-or-ptr - provides some insight, yet the issue is baffling, especially considering the unresolved precedence of the involved operators, in the mentioned setting. – Urovoros Ofis Oct 31 '18 at 08:12
  • @UrovorosOfis As I explained in my answer already, `*++string` will modify the pointer *first* before dereferencing it. And `*string++` will modify the pointer *after*. Updated answer with explanations for your latest example. – Some programmer dude Oct 31 '18 at 08:35
  • if I were to print the string "I am I" with a function using `putchar(*string++)`, I would get "I am I". But with `putchar(*++string)` I get " am I". Why only the first character is omitted? – Urovoros Ofis Oct 31 '18 at 09:43
  • @UrovorosOfis ***Again***, the prefix increment modifies the pointer ***before*** the dereference, hence it skips over the first character. Did you even bother to read my answer, especially the last update? – Some programmer dude Oct 31 '18 at 09:44
  • Ok I get it now, what fazed me is the operator precedence (https://en.cppreference.com/w/c/language/operator_precedence) of postfix (++) compared to the dereference operator (*) in `*string++` – Urovoros Ofis Oct 31 '18 at 10:01
  • @UrovorosOfis Ah okay. Then sorry for sounding rude, and I should probably have brought it up earlier. – Some programmer dude Oct 31 '18 at 10:03