3

I am practicing on #define and typedef. I think I got a good hold on the matter, according to this valid discussion. Currently, I am on this simple chunk of code:

#include <stdio.h>

/*typedef char *string;       with typedef the code works correctly*/

#define string char *

int main(void){
    string a[] = {"I", "like", "to", "fight,"}, 
           b[] = {"pinch", "and", "bight."};

    printf("%s %s %s %s %s %s %s\n",
        a[0], a[1], a[2], a[3], b[0], b[1], b[2]);
    return 0;
}

I know that define gives directive to the preprocessor. In this case, to substitute string with char *. Because of that, a is correctly declared as char *a[], while b[] is not! The problem could easily be addressed with

string b[] = {"pinch", "and", "bight."};

but my textbook challenge the reader by telling that the code with #define can work just by precisely adding one single character. I have been unable to figure out the solution. It is just for the sake of curiosity that I propose this simple problem to the community. Hence, thanks in advance for your time!

Worice
  • 3,847
  • 3
  • 28
  • 49

3 Answers3

5

This is why you should not use macro, after replacement you will get:

char* a[] = {"I", "like", "to", "fight,"}, 
       b[] = {"pinch", "and", "bight."};

where a is array of pointers to chars, and b is array of chars.

This is how declaration work, counter example:

char* a, b;

a is pointer to char b is char, to make it so you would have to write:

char* a, *b;
Mateusz Wojtczak
  • 1,621
  • 1
  • 12
  • 28
  • 1
    BTW even using `typedef char *string;` is questionable. It make believe that there _is_ a `string` type, but `string` is still a mere pointer to char. – Jabberwocky May 12 '18 at 16:22
3

After preprocessing, your code will look like this:

char * a[] = {"I", "like", "to", "fight,"}, 
       b[] = {"pinch", "and", "bight."};

In this way, b will be an array of char.

To solve the issue:

string a[] = {"I", "like", "to", "fight,"}, 
       *b[] = {"pinch", "and", "bight."};
       ^
       You have to add an asterisk here.
medalib
  • 937
  • 1
  • 6
  • 7
2

Adding a * before b will make the code work because then it expands to:

char *a[] = {"I", "like", "to", "fight,"}, 
     *b[] = {"pinch", "and", "bight."};

Of course having the * there will look utterly confusing when using the string macro (making it look like b is an array of string pointers), which I imagine is the point of the exercise: to show why using macros as a poor man's typedef leads to confusion.

sepp2k
  • 363,768
  • 54
  • 674
  • 675