frillybob
frillybob

Reputation: 620

Function Prototypes with multi-dimensional arrays as a parameter

Brand new to C, I come from a Java background.

I am having an issue where I can't compile because the compiler wants to know at compile time the size of my array. For example, I want to print my array to the console. It won't allow me to declare a function prototype as such:

void printRoom(char[][], int, int); //not allowed 

What am I supposed to do instead? Is there not a way around this? Online resources that I have found seem to indicate that I MUST know the dimensions if I want to use a function prototype. It appears that it also requires that the function header have the size of the array as well.

void printRoom(char room[][], int height, int width){ // not allowed, missing array bounds

Would a valid solution to this problem just be to say the array is of size 1000*1000 (the maximum array size I can expect)? That seems sloppy to me but I'm pretty sure it would work as long as I stayed within the bounds of what the array size is actually supposed to be.

I am NOT interested in pointers and malloc at this time.

Upvotes: 3

Views: 10243

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 754780

The C standard says in §6.7.6.3 Function declarators (including prototypes):

¶12 If the function declarator is not part of a definition of that function, parameters may have incomplete type and may use the [*] notation in their sequences of declarator specifiers to specify variable length array types.

That's standard-speak for: You can write a function declaration, but not the function definition, using a notation such as:

void printRoom(int, int, char [*][*]);

where the arguments are re-ordered in the declaration because in the function definition, you must specify the sizes before you specify the array:

void printRoom(int height, int width, char room[height][width])
{
    …
}

You could reverse the order of height and width in the function, but normally in C you'd name the dimensions in the order they're used. You're not obliged to specify the size of the leading dimension; all the others must have a size associated with them. That means you could write:

void printRoom(int, int, char [][*]);

and:

void printRoom(int height, int width, char room[][width])
{
    …
}

The function still needs to know the height so that it can process the array accurately, but it doesn't have to be part of the array definition.

§6.9.1 Function definitions

¶10 On entry to the function, the size expressions of each variably modified parameter are evaluated and the value of each argument expression is converted to the type of the corresponding parameter as if by assignment. (Array expressions and function designators as arguments were converted to pointers before the call.)

Your room is a variably-modified parameter.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

If the compiler supports variable length arrays then you can declare the function the following way

void printRoom( int, int, char[*][*]); 

or just

void printRoom( int, int, char[][*]); 

Here is a demonstrative program

#include <stdio.h>
#include <string.h>

void printRoom( int, int, char[*][*]); 

void printRoom( int m, int n, char a[m][n] )
{
    for ( int i = 0; i < m; i++ )
    {
        printf( "%3s ", a[i] );
        putchar( ' ');
    }
    printf( "\n" );
}   

int main(void) 
{
    const int M = 2;
    const int N = 10;
    char a[M][N];

    strcpy( a[0], "Hello" ),
    strcpy( a[1], "World" );

    printRoom( M, N, a );

    return 0;
}

Its output is

Hello  World 

If the compiler does not support VLAs then the number of columns has to be a constant. For example

#define N 100

//...

void printRoom(char[][N], int, int); 

Upvotes: 5

Related Questions