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

int main()
{
    float *pf;
    float m[][3]={  
        {0.1, 0.2, 0.3},
        {0.4, 0.5, 0.6},
        {0.7, 0.8, 0.9} 
    };
    printf("%d  \n",sizeof(m));
    pf=m[1];
    printf("%f   %f   %f  \n",*pf, *(pf+1), *(pf+2));
    printf("%f   %f   %f  \n",*pf, *(pf++), *(pf++));
}

I do understand the output of 2nd last printf. Please correct me if I am wrong. pointer pf stores address of first element of m[1]. *pf goes to that first element and outputs 0.4, *(pf+1) increments and jumps to next elements address and outputs that element and so on. What I dont get is the last printf. Shouldn't it be the similar thing. Lets say in last printf *pf goes to address stored in pf(which is same as first element of m[1]), so output should be 0.4 but instead output is 0.6. For *(pf++) should increment to next element and output 2nd element, i.e. 0.5 and last one *(pf++) should also output 0.5 but instead outputs 0.4. Please explain I am really confused.

peace9000
  • 31
  • 4
  • Array sizes are reported in bytes not number of entries. Your (double) array has 9 entries at 4 bytes each. – kaylum Feb 06 '17 at 05:41
  • 3
    In order to obtain th number of entries in the array `m`, use `sizeof(m)/sizeof(*m)`. – barak manos Feb 06 '17 at 05:45
  • "*I am really confused.*" but not due to pointers, but because you seem to not understand how the `++`-operator works. Read about it and fall back to a simpler example just using `int`, no arrays, no pointers. – alk Feb 06 '17 at 07:04
  • Just because the operand is a pointer type, it does change the fact that this code invokes undefined behavior. – Lundin Feb 06 '17 at 09:21

1 Answers1

1

The compiler is free to evaluate the arguments of a function in whatever order it pleases. In your case, the compiler chose to evaluate the arguments in the following order:

*pf, *(pf++), *(pf++)
3rd  2nd      1st
  1. The second *(pf++) is evaluated first. pf points to 0.4, that's the value of the expression, and then pf is incremented.

  2. The first *(pf++) is evaluated second. pf points to 0.5, that's the value of the expression, and then pf is incremented.

  3. *pf is evalued third. pf points to 0.6.

  4. The printf() prints

    0.6 0.5 0.4
    

Your code is a classic example of undefined behavior.

AlexP
  • 4,370
  • 15
  • 15
  • Since there are no sequence points between those operations, the compiler is also free to make your code crash & burn, or print a picture of a cat. The order of evaluation of function arguments is unspecified behavior, but that's not the reason why this code contains undefined behavior. – Lundin Feb 06 '17 at 09:24
  • so there is no way to predict the output of such statements? – peace9000 Feb 06 '17 at 17:20
  • @peace9000: No, there isn't. You _must_ avoid constructions where the evaluation order of the arguments of a function, or the evaluation order of the operands of an operator, is significant. – AlexP Feb 07 '17 at 00:43