C Question: Multidimensional array as parameter

My question revolves around pointers passed as a multidimensional array. I’m doing something wrong here and hopefully someone can provide some guidance.

I want to pass a multidimensional array of string to a function as a parameter. Within the function I want to iterate through the elements, printing each one out to the console.

Doing this with array notation is simple.


void displayArrays(char states][20])
{
    int i;
    for(i = 0;i < 3;i++)
    {
        printf("%s
",states*);
    }
}

How would I implement this with pointers? I could do this very simply with a one-dimensional array pointer


void toLowerCase(char *myString)
{
    
    int i;
    int len = strlen(myString);
    printf("%d
",len);
    for(i=0;i<len;i++)
    {
      
       *(myString + i) = tolower(*(myString + i));
    }
    printf("
%s",myString);//toString()
}

Or how would I pass a multidimensional array of integers using pointer notation? thanks*

simple:


int my_func(char** array){

}

Then once inside the function, you can return to array notation. Arrays of arrays are simply pointers to pointers in C.

I looked at a C tutorial, which offered me a few ideas so I came up with this. This will work, but I am sure there are other ways to implement this.


int numbers[2][3] = {{0,1,2},{3,4,5}};
displayArrays(&numbers);


void displayArrays(int (*nums)[3])
{
    int i;
    
     for(i = 0;i < 6;i++)
    {
        printf("%d
",*(*nums + i));
    }
}

Read that small book again: K & R. There is no replacement for that. Students should read it several times and each time you read it you will learn something new.

I’m not doing something right.
For example, let’s say I specify a small string array of states.


char states][20] = {"Maryland","Virginia","Delaware"};

I want to define a method that will accept this array as a parameter and then print out each element using the pointer notation.

I might have a method like:


void displayStates(char **pstates)
{
    printf("%s",pstates); //gives me Maryland   
}

I might invoke the method with this call:


displayStates(&states);

No, that’s wrong, you want printf(“%s”, pstates[0]) to give you Maryland.

I might invoke the method with this call:


displayStates(&states);

That’s also wrong, states is already an address, although in this case the compiler will figure out you wanted an address and ignore the &.

You should try understanding something like this, and also this avoids having to declare the max length of each string:


char *states] = { "Maryland", ..., 0 };

void displayStates(char **pstates) {
  int i;
  for (i = 0; pstates* != 0; i++)
    printf("%s
", pstates*);
}
...
displayStates(states);

**

Thanks, that helps clarify it a bit. So basically when you pass in states to the displayStates function, you’re passing in the address of states? Because when I run


printf("%p",states);

I get a memory address. That would make sense if states merely contains the memory address of the array of strings? From what I understand, pointers never contain values, they contain memory addresses that may in turn contain values.

For some reason, I have a lot of trouble understanding pointers.

I also noticed I could use this syntax to iterate through the array of string pointers.


while(*pstates)
{
      printf("
%s",*pstates);
      *pstates++;
}

I like this a little better because the code is more concise and I don’t have to specify a counter variable.

The name of an array is the same as the address of its first element, i.e. states == &states[0]. So there is no “address of states” since it’s not a scalar, it’s really the address of its first element.

Pointers and arrays are some of the hardest things to understand in C, but once you have grasped it, you can congratulate yourself. Read many expositions on the topic, in books or in online tutes and eventually you will get the picture.

Yes, you are beginning to get the picture. But be careful when writing functions. If you intend to use the pointer again further down the function, you have changed the copy of it passed in. In that case you should iterate using a copy of the pointer.

Also possible is:


char **p;
for (p = pstates; *p; p++)
  printf("
%s", *p);

In this case I’m using a copy of pstates. Also while it’s a matter of taste, and makes absolutely no difference to the code generated, I prefer to make my pointer comparison explicit.

*p != 0 as opposed to *p in the test of the for.

PS: Note to bystanders, 0 there is not really integer zero, (a null pointer does not have to actually have the address 0, although I know of no implementation that doesn’t use address 0), read K&R for the special meaning of the bare token 0 with regard to pointers. This was somewhat obscured in later C standards which allowed any expression with a value of 0, such as 0x0, etc.