How to define a pointer to multiple-subscripted arrays

Z

Zhou Yan

I want to define a pointer to a multiple-subscripted array.
For instance, I have an array defined as below( I have reduced the
size of the array as well as the dimension, but I think it OK to ask
this simple case.)

/----
int array[ 2 ][ 2 ] = { 1, 2, 3, 4 }

\-----

Now I want a pointer to point to this array.

I tried blow
/----
#include <stdio.h>
int main()
{
int array[ 2 ][ 2 ] = {
1, 2,
3, 4
};

int *nPtr[ 2 ];

nPtr = array;
printf( "%d\n", nPtr[ 1 ][ 1 ] );
return 0;
}
\----

when compilation, the compiler say:

main.c:11: warning: assignment from incompatible pointer type
main.c:13: error: subscripted value is neither array nor pointer
 
D

Daniel

I want to define a pointer to a multiple-subscripted array.
For instance, I have an array defined as below( I have reduced the
size of the array as well as the dimension, but I think it OK to ask
this simple case.)

/----
int array[ 2 ][ 2 ] = { 1, 2, 3, 4 }

\-----

Now I want a pointer to point to this array.

I tried blow
/----
#include <stdio.h>
int main()
{
int array[ 2 ][ 2 ] = {
1, 2,
3, 4
};

int *nPtr[ 2 ];

nPtr = array;
printf( "%d\n", nPtr[ 1 ][ 1 ] );
return 0;
}
\----

when compilation, the compiler say:

main.c:11: warning: assignment from incompatible pointer type
Yes, nptr is an array having two pointer members which points to int
type;
however, array is a two dimension array. They have different
type.
main.c:13: error: subscripted value is neither array nor pointer
changing statement "nptr = array;" to "nptr[1] = &array[1][0];" may
work...
 
Z

Zhou Yan

Yes, by this changing, it work properly. But I still do not
understand. Could you kindly give a brief explanation?

Also I tried to print all the 4 numbers and I followed this way, I
find I also need:

nPtr[ 0 ] = array[ 0 ];

and I checked array[ 0 ] is just the same as &array[ 0 ][ 0 ] by

printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

Could you please kindly give me a explanation?
What is array[ 0 ] actually is? Is it an array which contain the the
first row of this array? Or is it a pointer, with the address of array[
0 ][ 0 ]. Or internally it is both?

If I define such an array of pointers, nPtr[ 2 ], I need to initialize
all the pointers in this array,right? Is it possible to define a
single array which can point to any address of a 2-D array? (I need to
ask such silly quetions...but I really know nothing and cannot find a
book talk about these)

Thank you
 
M

mhagerty

I want to define a pointer to a multiple-subscripted array.
For instance, I have an array defined as below( I have reduced the
size of the array as well as the dimension, but I think it OK to ask
this simple case.)

/----
int array[ 2 ][ 2 ] = { 1, 2, 3, 4 }

\-----

Now I want a pointer to point to this array.

I tried blow
/----
#include <stdio.h>
int main()
{
int array[ 2 ][ 2 ] = {
1, 2,
3, 4
};

int *nPtr[ 2 ];

nPtr = array;
printf( "%d\n", nPtr[ 1 ][ 1 ] );
return 0;
}
\----

when compilation, the compiler say:

main.c:11: warning: assignment from incompatible pointer type
main.c:13: error: subscripted value is neither array nor pointer


Change: int *nPtr[2]; // declares an array of 2 pointers to ints
To: int (*nPtr)[2]; // declares a pointer to an array of 2 ints

Recompile, run. The difference is subtle, but the result it totally
different.

http://www.cs.cf.ac.uk/Dave/C/node10.html

Matthew
 
A

Adrian Hawryluk

Zhou said:
Yes, by this changing, it work properly. But I still do not
understand. Could you kindly give a brief explanation?

Also I tried to print all the 4 numbers and I followed this way, I
find I also need:

nPtr[ 0 ] = array[ 0 ];

and I checked array[ 0 ] is just the same as &array[ 0 ][ 0 ] by

printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

Could you please kindly give me a explanation?
What is array[ 0 ] actually is? Is it an array which contain the the
first row of this array? Or is it a pointer, with the address of array[
0 ][ 0 ]. Or internally it is both?

The full explanation is below.
> If I define such an array of pointers, nPtr[ 2 ], I need to initialize
> all the pointers in this array,right?
Right.

> Is it possible to define a single array which can point to any
address of a 2-D array?

Well, you got one answer on how to get a segment of the array, now for
the full explanation:

An 2D array (as you have allocated) is not an array of pointers to an
array of elements, it is in fact a bunch of elements allocated in one chunk.

array is of type int[][2] and is convertible to a pointer to an array of
two elements (int (*)[2]). You can declare a variables of this type
like this:

// Get from zeroth 'row' on down
int (*var0)[2] = array; // or
int (*var0)[2] = array+0; // or
int (*var0)[2] = &array[0];
// Get from first 'row' on down
int (*var1)[2] = array+1; // or
int (*var1)[2] = &array[1];

Note: not int *var[2] as this is an array of int pointers of two
elements. Note also that you cannot cast to or define this type this
directly, something in the language/parser prevents this. To
cast/return, you need to generate a typedef like so:

typedef (*ptrToTwoElementArray_t)[2];

(something that I just figured out now, thanks to you. That has
been bugging me forever, as I've never been able to return or cast
to something like this. Thanks very much!)

array[0] is of type int[] and is convertible to a pointer to an array of
elements (int *). You can also declared a variable of this type
like this:

// Get zeroth 'row'
int *var0 = *(array);
int *var0 = *(array+0);
int *var0 = array[0];
// Get first 'row'
int *var1 = *(array);
int *var1 = *(array+1);
int *var1 = array[1];

This is why your code:

printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

gave you the results that you found.

array[0][0] is of type int and is convertible to an int. You can also
declare a variable of this type like this:

int var = array[0][0];

This should be obvious.

When you dereference an array (declared as you described) using the []
operators, the compiler knows that this is not an array of pointers to
an array of ints, but that it is a big blob of ints and that it can
calculate the offset to the ints via the formula x+y*MaxX.
> (I need to ask such silly quetions...but I really know nothing and
> cannot find a book talk about these)

Don't think your question silly. I've been trying to figure this out
for 20 years. :) The only silly question is the unasked one. I
certainly learned something from answering this question, I hope that I
explained it sufficiently for you to too.


Adrian
 
Z

Zhou Yan

Adrian Hawryluk said:
Zhou said:
Yes, by this changing, it work properly. But I still do not
understand. Could you kindly give a brief explanation?

Also I tried to print all the 4 numbers and I followed this way, I
find I also need:

nPtr[ 0 ] = array[ 0 ];

and I checked array[ 0 ] is just the same as &array[ 0 ][ 0 ] by

printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

Could you please kindly give me a explanation?
What is array[ 0 ] actually is? Is it an array which contain the the
first row of this array? Or is it a pointer, with the address of array[
0 ][ 0 ]. Or internally it is both?

The full explanation is below.
If I define such an array of pointers, nPtr[ 2 ], I need to initialize
all the pointers in this array,right?
Right.

Is it possible to define a single array which can point to any
address of a 2-D array?

Well, you got one answer on how to get a segment of the array, now for
the full explanation:

An 2D array (as you have allocated) is not an array of pointers to an
array of elements, it is in fact a bunch of elements allocated in one
chunk.

array is of type int[][2] and is convertible to a pointer to an array of
two elements (int (*)[2]). You can declare a variables of this type
like this:

// Get from zeroth 'row' on down
int (*var0)[2] = array; // or
int (*var0)[2] = array+0; // or
int (*var0)[2] = &array[0];
// Get from first 'row' on down
int (*var1)[2] = array+1; // or
int (*var1)[2] = &array[1];

Note: not int *var[2] as this is an array of int pointers of two
elements. Note also that you cannot cast to or define this type this
directly, something in the language/parser prevents this. To
cast/return, you need to generate a typedef like so:

typedef (*ptrToTwoElementArray_t)[2];

(something that I just figured out now, thanks to you. That has
been bugging me forever, as I've never been able to return or cast
to something like this. Thanks very much!)

array[0] is of type int[] and is convertible to a pointer to an array of
elements (int *). You can also declared a variable of this type
like this:

// Get zeroth 'row'
int *var0 = *(array);
int *var0 = *(array+0);
int *var0 = array[0];
// Get first 'row'
int *var1 = *(array);
int *var1 = *(array+1);
int *var1 = array[1];

This is why your code:

printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

gave you the results that you found.

array[0][0] is of type int and is convertible to an int. You can also
declare a variable of this type like this:

int var = array[0][0];

This should be obvious.

When you dereference an array (declared as you described) using the []
operators, the compiler knows that this is not an array of pointers to
an array of ints, but that it is a big blob of ints and that it can
calculate the offset to the ints via the formula x+y*MaxX.
(I need to ask such silly quetions...but I really know nothing and
cannot find a book talk about these)

Don't think your question silly. I've been trying to figure this out
for 20 years. :) The only silly question is the unasked one. I
certainly learned something from answering this question, I hope that
I explained it sufficiently for you to too.


Adrian

Thank you very much for you explanation. I will print this message
out to read a few times to get the whole idea...

Thanks!
 
A

Adrian Hawryluk

Zhou said:
Yes, by this changing, it work properly. But I still do not
understand. Could you kindly give a brief explanation?

Also I tried to print all the 4 numbers and I followed this way, I
find I also need:

nPtr[ 0 ] = array[ 0 ];

and I checked array[ 0 ] is just the same as &array[ 0 ][ 0 ] by

printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

Could you please kindly give me a explanation?
What is array[ 0 ] actually is? Is it an array which contain the the
first row of this array? Or is it a pointer, with the address of array[
0 ][ 0 ]. Or internally it is both?

If I define such an array of pointers, nPtr[ 2 ], I need to initialize
all the pointers in this array,right? Is it possible to define a
single array which can point to any address of a 2-D array? (I need to
ask such silly quetions...but I really know nothing and cannot find a
book talk about these)

Thank you
Hi Zhou Yan,

Would you mind if I used your name in my blog? I would like to credit
the question to you.


Adrian
 
A

Adrian Hawryluk

Zhou said:
Thank you very much for you explanation. I will print this message
out to read a few times to get the whole idea...

Thanks!

I don't blame you, I certainly took me a while to figure it out. :)


Adrian
 
Z

Zhou

It's of course Ok... You helped me so much...
But perhaps, I hope you can use "Matthew Zhou" or "Matthew", my
English name instead of my Chinese Name. -:)
 
T

Thad Smith

Zhou said:
I want to define a pointer to a multiple-subscripted array.
#include <stdio.h>
int main()
{
int array[ 2 ][ 2 ] = {
1, 2,
3, 4
};

int *nPtr[ 2 ]; int (*nPtr) [ 2 ];

nPtr = array;
printf( "%d\n", nPtr[ 1 ][ 1 ] );
return 0;
}
\----

when compilation, the compiler say:

main.c:11: warning: assignment from incompatible pointer type

The original code defined nPtr as an array, size 2, of pointer to int.
Adding the parentheses defines nPtr as a pointer to an array, size 2, of
int, which is compatible with an array of arrays (length 2) of int.

The first index then selects the row, while the second selects the
element within the row.
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top