1. ## stupid question time

how do i pass a 2d array of characters to a function as a whole thing
many thanks
coop

2. What kind of 2D array? C has 2 kinds of 2D arrays, contiguous and jagged.

Code:
```int contiguous[8][8];
int **jagged;```
A contiguous array is really just a 1D array, but C needs to know the width of the array (the second dimension) in order to pass it to a function. Otherwise it can't know how wide the rows are, and won't know where the 2nd, 3rd, etc rows start. The second parameter in this function is necessary to know the number of rows in the array. This type of parameter is only useful when the number of columns is known at compile-time. For anything dynamically allocated, see the next example.

Code:
```void act_on_contiguous(int a[][10], int n) {
}```
The other type, a jagged array, is actually just an array of integer pointers. You just pass it as a normal **. Note that n is the number of rows, but I don't specify the number of columns. The number of columns can change from row to row in a jagged array.

Code:
```void act_on_jagged(int **a, int n) {
}

int main(void) {
int **jagged = malloc(sizeof(int) * 10);
for(int i = 0; i < 10; i++)
jagged[i] = malloc(sizeof(int) * 10);
act_on_jagged(jagged);
}```
But I prefer to use a 1D array as a 2D array. It's the same as the normal 2D array, but the indexing is done manually. These are just normal pointers or 1D arrays which makes them easier to allocate than jagged arrays but are more flexible than 2D arrays. Again, it needs to know the number of columns in the array to generate the offsets into the 1D array.

Code:
```void act_on_1D_as_2D(int *a, int n) {
// Set x5,y2 to 7
a[2*n+5] = 7;
}

int main(void) {
int *a = malloc(sizeof(int) * 20 * 20); // 20x20 array
act_on_1D_as_2D(a, 20);
}```

3. And there are no stupid questions, but I think we'd all prefer if your subject lines were more meaningful

4. sorry i guess i haven't been very clear here is an example of what i mean
Code:
```void myfunc(char str1[]);

int main()
{
char str1[2][11];

strcpy(str1[0][11], "hello world");
strcpy(str1[1][11], "goodbye you");
myfunc(str1);
return 0;
}
void myfunc(char str1[])
{
int i,j;
for (j=0; j<1; j++)
{
for (i=0; i<11;i++)
{
printf("%c", str1[i]);
}
printf("\n");
}

}```
i get warnings about making pointers from int without cast and stack overflow if i run it
many thanks
coop

5. You're getting warnings because they're not the same type, you're passing a char a[][11] and it's expecting a char a[]. See my act_on_contiguous example.

The first thing to understand here is that 2D arrays don't really "exist," they're just 1D arrays. All that's needed to operate on them is the address of their start and the number of columns. In memory, your array just looks like this.

Code:
```+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|h|e|l|l|o| |w|o|r|l|d|g|o|o|d|b|y|e| |y|o|u|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+```
The more rows you add, the further it just extends out to the right. C just knows that each row is 11 characters long and for every row it just makes the array another 11 elements longer. It's also how it calculates the offset to any row, it knows they're 11 characters long so the second row starts at offset 11, the next at offset 22, etc.

The next thing you have to understand is that every time you pass an array to a function, it "decays" into a pointer to that type. For example, if you pass an int a[3] to a function, it becomes an int a[], which is the same thing as an int *. This was a design decision early in C's history and there are probably better ways to handle it, but it's what we have.

So how does this work with 2D arrays? Your char a[2][11] decays to a pointer to a 2D array of 11 character columns and becomes a char [][11]. C can't tell from that type how many rows it has, but it knows that it has 11 columns. So the type for the parameter you should be using is char str1[][11]. It's also good practice and a common idiom to pass the array length along with the function, so your code should look something like this.

Code:
```#define arraylen(a) (sizeof(a)/sizeof(a[0]))

void func(int a[][11], int n) {
}

int main(void) {
int a[4][11] = {0};
func(a, arraylen(a));
}```
I hope I'm explaining this well. This is one of the more confusing corners of C so don't be discouraged if you don't get this right away.