-2

So for example:

#define char fruits[5][8] = {"APPLES", "ORANGES", "PEARS", "TOMATOES", "CABBAGES"};

function a() { This function uses the fruits array. }

function b() { This is another function that uses the fruits array. }

function c() { This is yet another function that uses the fruits array. }

Right now, it is in the main function but I want it to be accessed globally and it to be a constant.

Chris
  • 26,361
  • 5
  • 21
  • 42
GroxDots
  • 17
  • 6
  • 3
    There are no arrays in macros. – Barmar Jun 21 '23 at 23:38
  • 4
    Just declare a global array, you don't need `#define`. – Barmar Jun 21 '23 at 23:39
  • But maybe don't declare global variables at all if you can avoid it? – Chris Jun 21 '23 at 23:59
  • Just because you can use macros doesn't mean you should. – tadman Jun 22 '23 at 00:01
  • @tadman As I said in the question, I want the array to be declared globally because all functions will need access to the array at one point or another. Leaving it in the main function will probably cause extra complexity as it will probably require passing the array as parameter to every function. – GroxDots Jun 22 '23 at 00:10
  • 4
    That's not "declared gobally", that's a macro definition that **REDEFINES WHAT `char` MEANS**. I say this with emphasis because code like this basically trashes the rest of the program, utterly. – tadman Jun 22 '23 at 00:14
  • Instead of a global variable, at least consider a global function, as in something that can, given an index, return the `char*` name. You should also avoid specifying anything you don't *strictly* need to specify, it's super easy to make a mistake and overflow a buffer. `char *fruits[] = { "APPLES", ..., NULL }` for example. Here the `NULL` terminator means you can skip the size argument and just spin through the list until you hit `NULL`. – tadman Jun 22 '23 at 00:18
  • 1
    Yes, `#define char /* ... whatever ... */` means you are *redefining the meaning of `char`*. And that is a very bad idea, to put it mildly. – printf Jun 22 '23 at 00:24
  • @GroxDots some [reading](https://stackoverflow.com/questions/484635/what-are-the-pros-and-cons-in-use-of-global-variables) on global variables. – Chris Jun 22 '23 at 00:35

1 Answers1

3

You don't need to use a macro to accomplish this. You can simply declare a global variable.

char fruits[5][8] = {
    "APPLES", 
    "ORANGES", 
    "PEARS", 
    "TOMATOES", // Need 9 characters, not 8.  If you tried to print "TOMATOES" ... you'll probably get garbage!
    "CABBAGES"
};

But... you have an issue. "Tomatoes" and "Cabbages" are both eight characters long. To hold an eight character string, you need nine characters of space to accommodate the null terminator.

If you really want them to be constants, then declare it as an array of five const char pointers rather than an array of five arrays of eight characters. A char array can be modified. A string literal cannot.

const char *fruits[5] = {
    "APPLES", 
    "ORANGES", 
    "PEARS", 
    "TOMATOES", 
    "CABBAGES"
};

Further, there's no need for these to live at a global level. You can declare a, b, and c to take them as an argument.

void a(const char *strings[], size_t n) {
    // ...
}

int main(void) {
    const char *fruits[5] = {
        "APPLES", 
        "ORANGES", 
        "PEARS", 
        "TOMATOES", 
        "CABBAGES"
    };

    a(fruits, sizeof(fruits) / sizeof(*fruits));
}
paulsm4
  • 114,292
  • 17
  • 138
  • 190
Chris
  • 26,361
  • 5
  • 21
  • 42
  • After reading this [link](https://stackoverflow.com/questions/10186765/what-is-the-difference-between-char-array-and-char-pointer-in-c/)[link] I still am not sure what is the difference a char array and a char pointer array. – GroxDots Jun 22 '23 at 00:37
  • 1
    By declaring an array, you allocate memory space. `char foo[] = "foo";` means you have allocated 4 bytes of memory space and initialized it with the string literal "foo" (and the null terminator). But if we declare the variable as a pointer to a string literal, no additional memory is allocated and the contents of it can be modified. `char *foo = "foo";` In this case `foo` simply points to a string literal. The contents of that string literal cannot be modified (or rather attempting to do so will invoke undefined behavior). – Chris Jun 22 '23 at 00:41
  • Are char pointers iterable? – GroxDots Jun 22 '23 at 00:52
  • Yes, you can iterate over a string literal. – Chris Jun 22 '23 at 00:55