Multidimensional arrays

W

whisper

Hi: there is an issue that confuses me and the FAQ did not clarify it
for me.
(Sorry I am just learning!)

Let say I define a multidimensional array in my main routine as
follows:

int arr[2][3]={{0,1,2}, {3,4,2}};

and I pass the array as a parameter to a function declared by:

int getsum(int arr[][], int numrows, int numcols)

by calling getsum(arr,2,3) (getsum tries to sum up all the elements).

I know that this is illegal, but I don't quite understand why.

When arr is created (at compile time), we know exactly what its row
width
and column width are. So why do we have to pass that information to
getsum ?


Thanks
 
M

Mark A. Odell

Hi: there is an issue that confuses me and the FAQ did not clarify it
for me.
(Sorry I am just learning!)

Let say I define a multidimensional array in my main routine as
follows:

int arr[2][3]={{0,1,2}, {3,4,2}};

and I pass the array as a parameter to a function declared by:

int getsum(int arr[][], int numrows, int numcols)

by calling getsum(arr,2,3) (getsum tries to sum up all the elements).

I know that this is illegal, but I don't quite understand why.

What is? Calling getsum()?
When arr is created (at compile time), we know exactly what its row
width
and column width are. So why do we have to pass that information to
getsum ?

Because 'arr' is effectively a pointer from getsum's perspective. Thus,
sizeof will only tell you how big the pointer is, not the object it points
to. If you do this:

struct Array
{
int arr[2][3];
};

int getsum(struct Array *pArr)
{
int arraySize = sizeof pArr->arr;

/* ... */

return 0;
}
 
D

Dan Pop

In said:
Hi: there is an issue that confuses me and the FAQ did not clarify it
for me.
(Sorry I am just learning!)

Let say I define a multidimensional array in my main routine as
follows:

int arr[2][3]={{0,1,2}, {3,4,2}};

and I pass the array as a parameter to a function declared by:

int getsum(int arr[][], int numrows, int numcols)

by calling getsum(arr,2,3) (getsum tries to sum up all the elements).

I know that this is illegal, but I don't quite understand why.

When arr is created (at compile time), we know exactly what its row
width
and column width are. So why do we have to pass that information to
getsum ?

Because getsum doesn't have it. All it has is the address of a
one-dimensional array of 3 int's. The getsum definition that minimises
redundancy is:

int getsum(int arr[][3], int rows)
{
int cols = sizeof arr[0] / sizeof arr[0][0];
...
}

It is only in C99 that you can do better than that and avoid having to
hard code the number of columns in the function definition:

int getsum(int rows, int cols, int arr[][cols]) { ... }

Note that cols must be declared before being used, so the following is
not allowed:

int getsum(int arr[][cols], int rows, int cols) { ... }

Of course, you can also specify the number of rows, but the compiler will
simply discard this information:

int getsum(int rows, int cols, int arr[rows][cols]) { ... }

Dan
 
D

Dan Pop

In said:
Hi: there is an issue that confuses me and the FAQ did not clarify it
for me.
(Sorry I am just learning!)

Let say I define a multidimensional array in my main routine as
follows:

int arr[2][3]={{0,1,2}, {3,4,2}};

and I pass the array as a parameter to a function declared by:

int getsum(int arr[][], int numrows, int numcols)

by calling getsum(arr,2,3) (getsum tries to sum up all the elements).

I know that this is illegal, but I don't quite understand why.

What is? Calling getsum()?
When arr is created (at compile time), we know exactly what its row
width
and column width are. So why do we have to pass that information to
getsum ?

Because 'arr' is effectively a pointer from getsum's perspective. Thus,
sizeof will only tell you how big the pointer is, not the object it points
to. If you do this:

struct Array
{
int arr[2][3];
};

int getsum(struct Array *pArr)
{
int arraySize = sizeof pArr->arr;

/* ... */

return 0;
}

Now, you have managed to hardcode both dimensions of the array, instead of
the only one required by the C89 standard...

Dan
 
M

Malcolm

whisper said:
Hi: there is an issue that confuses me and the FAQ did not clarify it
for me.
(Sorry I am just learning!)
Most beginners' books introduce multidimensional arrays at the same time as
single-dimensional arrays, and quite early. This is a mistake since
multidimensional arrays in C are an advanced feature. You can of course use
a mutli-dimensional array in the function it was declared quite simply, but
passing the array to a subroutine is complex.
int getsum(int arr[][], int numrows, int numcols)
I know that this is illegal, but I don't quite understand why.
It is illegal because C passes the array as a raw address. Without column
information, it has no way of resolving an expression such as arr[1][1].
When arr is created (at compile time), we know exactly what its row
width and column width are. So why do we have to pass that information to
getsum?
Because C is so close to assembler, it doesn't package variables with extra
information, like bounds or type or array dimensions. Another language would
allow you to do what you want, but not C.
 
E

E. Robert Tisdale

whisper said:
There is an issue that confuses me
and the FAQ did not clarify it for me.

The FAQ is obsolete.
(Sorry I am just learning!)

Let's say that
I define a multidimensional array in my main routine as follows:

int arr[2][3] = {{0,1,2}, {3,4,2}};

and I pass the array as a parameter to a function declared by:

int getsum(int arr[][], int numrows, int numcols)

int getsum(size_t numrows, size_t numcols,
arr[numrows][numcols]) {
int total = 0;
for (size_t i = 0; i < numrows; ++i)
for (size_t j = 0; j < numcols; ++j)
total += arr[j];
return total;
}
by calling getsum(arr,2,3)

int total = getsum(2, 3, arr);
(getsum tries to sum up all the elements).

I know that this is illegal, but I don't quite understand why.

When arr is created (at compile time),
we know exactly what its row width and column [height] are.
So why do we have to pass that information to getsum?

So that getsum knows what they are?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top