cf3.c The C Puzzle Book

職業訓練
https://qiita.com/kaizen_nagoya/items/95368b63fa21d64271ec

Programmer, Day 6
https://qiita.com/kaizen_nagoya/items/632d8f191268e88eb86a

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識, error(21), coding(28)
https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

The C Puzzle Book
https://efrei.poupa.net/Programmation%20en%20C/Cours/The_C_Puzzle_Book.pdf

defs.h "The C Puzzle Book"
https://qiita.com/kaizen_nagoya/items/6d284651ac1244963bd9

```c:cf3.c
#include "defs.h"
#define ENUF 3
#define EOS '\0'
#define NEXT(i) input[i++]
#define FALSE 0
#define TRUE 1

char input[]="PI=3.14159, approximately";

main()
{
	char c;
	int done, high, i, in, low;

	i=low=in=high=0;
	while( c=NEXT(i), i=EOS ) 
		if( c<'0' ) low++;
		else if( c>'9' ) high++;
		else in++;
	PRINT3(i,low,in,high);		/* (Control Flow 3.1) */

	i=low=in=high=0; done=FALSE;
	while( (c=NEXT(i))!=EOS && !done )
		if( c<'0' ) low++;
		else if( c>'9' ) high++;
		else in++;
			if( low>=ENUF || high>=ENUF || in>=ENUF )
				done = TRUE;
	PRINT3(i,low,in,high);		/* (Control Flow 3.2) */

	i=low=in=high=0; done=FALSE;
	while( (c=NEXT(i))!=EOS && !done )
		if( c<'0' ) done = (++low>=ENUF);
		else if( c>'9' ) done = (++high>=ENUF);
		else done = (++in>=ENUF);
	PRINT3(i,low,in,high);		/* (Control Flow 3.3) */
}

cf3.c:10:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
   10 | main()
      | ^~~~
In file included from cf3.c:1:
cf3.c: In function ‘main’:
cf3.c:20:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
cf3.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
cf3.c:20:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
cf3.c:20:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
defs.h:9:20: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
    9 | #define NL putchar("\n")
      |                    ^~~~
      |                    |
      |                    char *
defs.h:11:32: note: in expansion of macro ‘NL’
   11 | #define PRINT1(f,x1) PR(f,x1), NL
      |                                ^~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(i,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
In file included from defs.h:5:
/usr/include/stdio.h:618:25: note: expected ‘int’ but argument is of type ‘char *’
  618 | extern int putchar (int __c);
      |                     ~~~~^~~
cf3.c:29:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
cf3.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
cf3.c:29:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
cf3.c:29:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
defs.h:9:20: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
    9 | #define NL putchar("\n")
      |                    ^~~~
      |                    |
      |                    char *
defs.h:11:32: note: in expansion of macro ‘NL’
   11 | #define PRINT1(f,x1) PR(f,x1), NL
      |                                ^~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(i,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
/usr/include/stdio.h:618:25: note: expected ‘int’ but argument is of type ‘char *’
  618 | extern int putchar (int __c);
      |                     ~~~~^~~
cf3.c:36:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
cf3.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
cf3.c:36:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
cf3.c:36:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
defs.h:9:20: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
    9 | #define NL putchar("\n")
      |                    ^~~~
      |                    |
      |                    char *
defs.h:11:32: note: in expansion of macro ‘NL’
   11 | #define PRINT1(f,x1) PR(f,x1), NL
      |                                ^~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
/usr/include/stdio.h:618:25: note: expected ‘int’ but argument is of type ‘char *’
  618 | extern int putchar (int __c);
```
```c:cf3a.c
#include "defs.h"
#define ENUF 3
#define EOS '\0'
#define NEXT(i) input[i++]
#define FALSE 0
#define TRUE 1

char input[]="PI=3.14159, approximately";

void main(void)
{
        char c;
        int done, high, i, in, low;

        i=low=in=high=0;
        while( c=NEXT(i), i=EOS )
                if( c<'0' ) low++;
                else if( c>'9' ) high++;
                else in++;
        PRINT3(i,low,in,high);          /* (Control Flow 3.1) */

        i=low=in=high=0; done=FALSE;
        while( (c=NEXT(i)) != EOS && !done )
                if( c<'0' ) low++;
                else if( c>'9' ) high++;
                else in++;
                        if( low>=ENUF || high>=ENUF || in>=ENUF )
                                done = TRUE;
        PRINT3(i,low,in,high);          /* (Control Flow 3.2) */

        i=low=in=high=0; done=FALSE;
        while( (c=NEXT(i)) != EOS && !done )
                if( c<'0' ) done = (++low>=ENUF);
                else if( c>'9' ) done = (++high>=ENUF);
                else done = (++in>=ENUF);
        PRINT3(i,low,in,high);          /* (Control Flow 3.3) */
}
```

```shell-session:bash
$ gcc cf3a.c
In file included from cf3a.c:1:
cf3a.c: In function ‘main’:
cf3a.c:20:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
cf3a.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
cf3a.c:20:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
cf3a.c:20:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
defs.h:9:20: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
    9 | #define NL putchar("\n")
      |                    ^~~~
      |                    |
      |                    char *
defs.h:11:32: note: in expansion of macro ‘NL’
   11 | #define PRINT1(f,x1) PR(f,x1), NL
      |                                ^~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:20:9: note: in expansion of macro ‘PRINT3’
   20 |         PRINT3(d,low,in,high);          /* (Control Flow 3.1) */
      |         ^~~~~~
In file included from defs.h:5:
/usr/include/stdio.h:618:25: note: expected ‘int’ but argument is of type ‘char *’
  618 | extern int putchar (int __c);
      |                     ~~~~^~~
cf3a.c:23:27: error: expected ‘)’ before ‘i’
   23 |         while( (c=NEXT(i))i != EOS && !done )
      |              ~            ^
      |                           )
cf3a.c:29:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
cf3a.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
cf3a.c:29:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
cf3a.c:29:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
defs.h:9:20: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
    9 | #define NL putchar("\n")
      |                    ^~~~
      |                    |
      |                    char *
defs.h:11:32: note: in expansion of macro ‘NL’
   11 | #define PRINT1(f,x1) PR(f,x1), NL
      |                                ^~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:29:9: note: in expansion of macro ‘PRINT3’
   29 |         PRINT3(d,low,in,high);          /* (Control Flow 3.2) */
      |         ^~~~~~
/usr/include/stdio.h:618:25: note: expected ‘int’ but argument is of type ‘char *’
  618 | extern int putchar (int __c);
      |                     ~~~~^~~
cf3a.c:36:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
cf3a.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
cf3a.c:36:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
cf3a.c:36:29: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=]
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |                             ^
defs.h:8:35: note: in definition of macro ‘PR’
    8 | #define PR(format, value) printf(#value" = %format\t",(value))
      |                                   ^~~~~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
defs.h:9:20: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
    9 | #define NL putchar("\n")
      |                    ^~~~
      |                    |
      |                    char *
defs.h:11:32: note: in expansion of macro ‘NL’
   11 | #define PRINT1(f,x1) PR(f,x1), NL
      |                                ^~
defs.h:12:35: note: in expansion of macro ‘PRINT1’
   12 | #define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
      |                                   ^~~~~~
defs.h:13:41: note: in expansion of macro ‘PRINT2’
   13 | #define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
      |                                         ^~~~~~
cf3a.c:36:9: note: in expansion of macro ‘PRINT3’
   36 |         PRINT3(d,low,in,high);          /* (Control Flow 3.3) */
      |         ^~~~~~
/usr/include/stdio.h:618:25: note: expected ‘int’ but argument is of type ‘char *’
  618 | extern int putchar (int __c);
      |                     ~~~~^~~
```

```c:defs.h
// https://qiita.com/kaizen_nagoya/items/6d284651ac1244963bd9
// Type by Dr. Kiyoshi Ogawa
#include <stdio.h>
#include <stdlib.h>

#define PR(format, value) printf(#value" = %"#format"\t",(value))
#define NL putchar('\n')

#define PRINT1(f,x1) PR(f,x1), NL
#define PRINT2(f,x1,x2) PR(f,x1), PRINT1(f,x2)
#define PRINT3(f, x1, x2, x3) PR(f,x1), PRINT2(f,x2,x3)
#define PRINT4(f,x1,x2, x3, x4) PR(f,x1), PRINT3(f,x2, x3,x4)
```

```shell-session:bash
$ gcc cf3a.c
$ ./a.out
low = 25        in = 0  high = 0
low = 3 in = 6  high = 16
low = 0 in = 0  high = 3
```