I know that 2D array is basically pointer to array so in the following code a is pointer to 0th index that is itself an array and than *a should return address of 0th index element how a and *a both return same value
#include <stdio.h>
#include <stdio.h>
int main () {
int a[4] [5] = {{1, 2, 3, 4, 5},
{6, 7,8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17,18, 19, 20}};
printf("%d\n",a);
printf("%d\n",*a);
}
CodePudding user response:
For starters to output a value of a pointer you should use the conversion specifier %p
instead of %d
.
printf( "%p\n", ( void * )a );
printf( "%p\n", ( void * )*a) ;
The array designator a
used as an argument expression is implicitly converted to a pointer to its first element. As the array declared as a two-dimensional array like
int a[4] [5] = {{1, 2, 3, 4, 5},
{6, 7,8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17,18, 19, 20}};
then its elements have the type int [5]
and the pointer (having the type int ( * )[5]
) to which the array is implicitly converted will have the address of the firs "row" of the array that is the initial address of the extent of memory occupied by the array.
Dereferencing the pointer you will get the first "row" that is the array a[0]
of the type int [5]
. Again used as an argument expression it is implicitly converted to a pointer of the type int *
to its first element a[0][0]
. And the address of the first element of the first "row" that is the initial address of the extent of memory occupied by the array is outputted.
That is the addresses of the array as whole, of its first "row" and of the first element of the first "row" are equal each other. But the corresponding expressions, &a
, a
, *a
(after implicit conversion to pointers) have different types. The expression &a
has the type int ( * )[4][5]
, the expression a
(after the implicit conversion) has the type int ( * )[5]
and the expression *a
(also after the implicit conversion) has the type int *
. But their values are equal each other.
CodePudding user response:
I know that 2D array is basically pointer to array
No, it is not. Arrays when used in most expressions "decay" to a pointer to the first element, but that does not make arrays pointers.
so in the following code a is pointer to 0th index
Only in the expression printf("%d\n",a);
where a
decays into a pointer to its first element. The first element of a
is an array of type int [5]
, so in this printf expression, a
decayed to a pointer to such an element, a int (*)[5]
type.
Using %d
to print pointers is not well-defined behavior so the code is wrong, you should be using %p
and cast the parameter to void*
: printf("%p\n", (void*)a);
how a and *a both return same value
For any array, the array itself and it's first element naturally reside at the very same address or the concept of arrays wouldn't make any sense. The very definition of an array is a contiguous chunk of items with the same type allocated at contiguous addresses.
When you de-reference *a
, you de-reference the decayed array a
of type int(*)[5]
and get a type int [5]
. But since arrays cannot be used in most expressions, this too can be said to decay into a pointer to the first element of int [5]
, meaning type int*
, pointing at item [0] in the first array.
CodePudding user response:
There are already two valuable answers above but I think you're still confused about the situation; for I felt the same while I was a rookie (though I'm not a pro yet).
- The line below does not return a pointer. Actually, it returns a memory address and the first address holds the first element of the array as data; but as it is on stack, C treats it like a pointer.
int a[4][5] = { ... };
- The lines below, again, return memory addresses on stack, but they hold other memory addresses and this time, they are literally pointers; they point to different memory addresses —most probably on the heap.
int** b = malloc(4 * sizeof(int*));
int* c = malloc(5 * sizeof(int));
Do not keep your hands clean and debug the code below and inspect the output while keeping an eye on the memory dump at the same time:
#include <stdio.h>
#include <stdlib.h>
int** copyArray(int row, int col, int pSrc[row][col]) {
int** pDst = malloc(row * sizeof(int*));
for (int i = 0; i < row; i ) {
pDst[i] = malloc(col * sizeof(int));
for (int j = 0; j < col; j ) {
pDst[i][j] = pSrc[i][j];
}
}
return pDst;
}
int main() {
int a[4][5] = { { 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 },
{ 11, 12, 13, 14, 15 },
{ 16, 17, 18, 19, 20 } };
int** b = copyArray(4, 5, a);
printf("- - - - -\n", a[0][0], a[0][1], a[0][2], a[0][3], a[0][4]);
printf("%p\n", &a);
printf("%p\n", a);
printf("%p\n", *a);
printf("%p\n", a[0]);
printf("%p\n", &a[0]);
printf("\n");
printf("- - - - -\n", b[0][0], b[0][1], b[0][2], b[0][3], b[0][4]);
printf("%p\n", &b);
printf("%p\n", b);
printf("%p\n", *b);
printf("%p\n", b[0]);
printf("%p\n", &b[0]);
for (int i = 0; i < 4; i ) {
free(b[i]);
}
free(b);
return 0;
}