susdu
susdu

Reputation: 862

C: pointer to 2d array

From what I understand:

int B[2][3];
int* p=B;

doesn't work because B isn't a pointer to int but a pointer to an array of 3 ints. But it does not contradict the fact that B still points to the first element in the array, which is an int. so why *p or *B does not contain the value of B[0][0]?

How can something be a pointer to "an array of ints"? a pointer can only point at a single address in memory, not at all 3 addresses. It follows that B should always point to the address where the first element is, doesn't matter how long the memory block is.

Please explain why my reasoning doesn't work because I'm having a hard time fully understanding it. Thanks.

Upvotes: 1

Views: 702

Answers (3)

haccks
haccks

Reputation: 106012

so why *p or *B does not contain the value of B[0][0]?

B is an array of 2 arrays of 3 ints. When used in expression, in most context, arrays are converted to pointer to first element. In expression

int *p = B; 

B is converted to pointer to its first element. First element of B is an array of 2 ints, i.e. B[0]. Therefore, B is converted to pointer to B[0].
Dereferencing a pointer yields the value of data type that pointer points to. In this case B points to B[0] and is of type array of 3 ints. Therefore, *B yield an array of 3 ints and not an int data (B[0][0]).

How can something be a pointer to "an array of ints"?

Any data type can have pointers. Arrays are also data types and can have pointers.

a pointer can only point at a single address in memory, not at all 3 addresses.

I am giving you a real life example to explain this.

You have a house named B having 3 rooms. The address of your house is House no. 18, Steet x. If someone ask you what is the address of your first room, then your answer will be the same as the address of house B. Though the address of your rooms and house is same, House != Room.

The same goes here. The address of B, B[0] and B[0][0] all are same but type of all three are different.

Upvotes: 2

John Bollinger
John Bollinger

Reputation: 180201

B is an array of arrays of int. It is not a pointer and therefore does not point to anything. However, under most circumstances, where it appears in code, B is automatically converted to a pointer to the first element of the array. That element is not an int, but an array of 3 ints.

How can something be a pointer to "an array of ints"? a pointer can only point at a single address in memory, not at all 3 addresses.

You might as well ask how you can have a pointer to int. In every C system I know, ints are wider than one byte, but bytes are individually addressible. How, then, can you point to an int when the individual bytes in it have separate addresses? Of course, the answer is the same for an int as it is for an array: the address of the overall object is the address of its first byte.

It follows that B should always point to the address where the first element is, doesn't matter how long the memory block is.

Exactly so, but a pointer is interpreted according to the type of data it points to. Pointers to different data types may even be represented differently. Given your declaration ...

int B[2][3];

... the expression *B evaluates to an array of 3 ints, specifically B[0]. This is not the same thing as B[0][0] any more than the first byte of an int is the same as the whole int. In particular, (*B)[1] is a perfectly valid alternative expression for B[0][1].

Upvotes: 4

Blindy
Blindy

Reputation: 67380

"Pointers" in C are more than just the underlying number representing a (virtual) memory address, they also carry with them the data type.

In your case, B is of type int[2][3]. You can't assign that to an int* any more than you could assign a char to a char*.

Under the hood, B is obviously the address of the first element, and you can express to the compiler that that's what you're talking about by casting:

int *p = *B;

Or using complete type erasure:

int *p = (int *)(void *)B;

Note that neither of those actually emit any code (debug code aside). You're simply re-interpreting compile-only types.

Upvotes: 1

Related Questions