-2

I am trying to understand the logic behind the printf numbers in the code below. Can someone explain how the valuables change? What symbol is executed first (|| , &&, != and so on)? In which direction is it executed?

#include <stdio.h>
static float w = 3.9;
short
f (short a, short *b)
{
  a++;
  (*b)++;
  w++;
  printf ("13: %d %d %4.2f\n", a, *b, w);
  return a - *b;
}

int
main ()
{
  short x, y, z, arr[] = { 4, 8, 0, 6 }, *p = arr;
  char m[] = "dcrfvtgb", *pc;

  y = 2;
  z = 3;
  x = (++y != z);
  printf ("1: %d %d %d\n", x, y, z);

  x = y = 6;
  x *= (y = 5);
  printf ("2: %d %d\n", x, y);

  x = 0;
  y = 2;
  z = 7;
  printf ("3: %d %d %d %d\n", !x || y && !z, x, y, z);

  x = 5;
  y = 3;
  printf ("4: %d %d %d\n", x, y, x < y ? x : y);

  y = 0;
  if (y)
    x = 7;
  else
    x = 5;
  printf ("5: %d %d\n", x, y);

  y = 8;
  if (z = (y++ > 8))
    x = 9;
  else
    x = 0;
  printf ("6: %d %d %d\n", x, y, z);

  x = y = 5;
  while (y++ < 5)
    x += y;
  printf ("7: %d %d\n", x, y);

  for (x = y = 5; y < 7; x = y++)
    printf ("8:%d %d\n", x, y);

  for (x = 2, y = 5; y >= 1; x++, y /= 3);
  printf ("9: %d %d\n", x, y);

  printf ("10: %d %d\n", p[2], *(arr + 1));

  x = y = 3;
  z = f (x, &y);
  printf ("11:%d %d %d %4.2f\n", x, y, z, w);

  for (x = y = z = 10; z-- > 9; x *= y);
  printf ("12: %d %d %d\n", x, y, z);

  for (pc = m; *pc; pc++)
    (*pc)--;
  printf ("14: %s %c\n", m + 2, *(m + 1));

  return 0;
}
abligh
  • 24,573
  • 4
  • 47
  • 84

2 Answers2

0

The printf function takes a format string as the first argument, then zero or more other arguments. Each of the things beginning with % in the format string correspond to one of the other arguments. At least the way you are using it, these are in the same order, so the first % placeholder corresponds to to the second argument (i.e. the first after the format string), the second % placeholder to the next and so forth. The letter following the % (and sometimes other characters) describe the type of argument and how it is to be printed. See the manual page for printf() for more information.

Each of the arguments is evaluated before the call to printf. The C standard does not specify the order in which the arguments are evaluated. So if you have (e.g.), !x || y && !z as an argument, each of those will be evaluated prior to the call to printf(). For the order in which the components of those are evaluated, see operator precedence.

Note that that only tells you what order operators are evaluated in (i.e. in x + z * y, this says the z * y is evaluated before the +). It doesn't tell you whether x, y or z will be evaluated first; as they may be expressions themselves, that's important. So, for instance in:

int
f(int a, int b, int c)
{
    return g(a) + h(b) * i(c);
}

in the general case you have no guarantee in which order g(a), h(b), and i(c) are evaluated. You only know the order in which the + and * are evaluated.

If you want to know more about evaluation order, you need to research sequence points.

abligh
  • 24,573
  • 4
  • 47
  • 84
0

@abligh says "The C standard does not specify the order in which the arguments are evaluated."

As far as I know, the Intel implementation pushes the arguments right-to-left onto the stack, which means that the arguments are evaluated right-to-left.

printf ("12: %d %d %d\n", x, z, z++);

In this example the first value of z, when printed, will be one higher than the second value of z when printed.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41