Why can't I dereference a pointer to multidimensional array? - c

Basic question.. had to ask. Any help will be appreciated.
Q: Why can't I dereference the pointer to a multidimensional array like this:
int arr [2][2] = { {1, 2} , {3, 4} };
printf("%d ", *arr);

You can dereference it, it is just that the result is not going to be what you'd expect: *arr is not an int, it's a pointer to an int (OK, a one-dimensional array). If you want to see 1 printed, add another star:
printf("%d ", **arr);

If a is int[][] then *a is int[]. You need another level of redirection to access an array element. That is, **a is int.

Try:
int arr [2][2] = { {1, 2} , {3, 4} };
printf("%d ", **arr);
You need two levels of dereferencing, as your array is two-dimensional.

Remember if we define a as int[][], then it means it is a two dimensional array and it can be dereferenced by **a. If array is one dimensional then we should use *a to dereference it...
Try it..

Related

What is the difference between a regular array, and array of pointers

Can someone plz explain me what is the diffrence between those tow lines
and when we will want to use each one of then
int array[] = { 1, 2, 3 }; // init a regular array
int *numList = {1, 2, 3}; // init an array of pointers?
I am expecting that there are probably seenarios we will want to use the second over the first,
But when?
Thank You in Advance
You're conflating some concepts. As #ikegami noted, your second line:
int *numList = {1, 2, 3};
Gets treated as:
int *numList = 1;
Which not an array, nor a valid pointer.
If you want to create an array of pointers, you use the same syntax as normal arrays, with the type being a pointer:
int* numList[] = {
&array[0],
&array[1],
&array[2]
};
Will create an array of 3 int pointers, pointing to your original array's elements.

How can I de-reference a 2d array of ints?

#include <stdio.h>
typedef struct
{
int (*p)[2][2];
} S;
int main()
{
int aa[2][2] = {{1, 2}, {3, 4}};
S s = { .p = &aa };
printf("Four: %p\n", s.p[1][1]);
return 0;
}
I'm expecting a '4' to be printed but I'm getting a memory location instead.
You dereference it like any other pointer, with the unary * operator.
However you have to note that operator precedence will play a role here, since the array subscripting operator has higher precedence than the dereference operator. Therefore you have to do e.g.
(*s.p)[x][y]
Furthermore you use the wrong format to print an integer. The "%p" format is to print an actual pointer, not an integer. Use "%d".
As an alternative, remember that arrays naturally decays to pointers to their first element. That means for your array aa, using it just like that will decay to &aa[0], which is of type int (*)[2]. That means you could make your variable the same type, and use plain aa in the initialization, and use it like a normal "2d" array:
typedef struct
{
int (*p)[2];
} S;
int main()
{
int aa[2][2] = {{1, 2}, {3, 4}};
S s = { .p = aa }; // Note: Not using the address-of operator here
printf("Four: %d\n", s.p[1][1]); // Using array-indexing works as expected here
return 0;
}
p is a pointer to an array in the int (*p)[2][2]; Its not a 2D array as you tried to print.
Replace
printf("Four: %p\n", s.p[1][1]);/** %p is format specifier to prints the address, Instead use %d to print value **/
with
printf("Four: %d\n", (*s.p)[1][1]);
s is a structure containing a pointer to a 2 dimensional array. So with "s.p" you get the pointer to your 2 dimensional array. Considering that:
(*(s.p))[1][1]
will do the work for you.
I guess you did not intend to use the %p placeholder as it is used to print addresses.

The difference between pointer in 2D and 1D array

I practiced today some C code, especially array with return function and pointers.
And I found some code which were really confusing and want to know why it is.
So I have first a function which print all elements out of the array.
void function(int *arr)
{
...
printf("%d, arr[i]);
}
Now in main I have a 2D array and a 1D array.
int array2D[2][2] = {{1,2}, {3,4}};
int array1D[3] = {1,2,3};
function(*array2D); // Why do I need here the derefernce pointer
function(array1D); // why I don't need here the deference pointer
And in another case:
void disp( int *num)
{
printf("%d ", *num);
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
for (int i=0; i<10; i++)
{
/* Passing addresses of array elements*/
disp(&arr[i]); // why i need here & and above in the function not
}
}
This is really confusing me right now. Can someone explain me this?
The first line
function(*array2D);
is equivalent to
function(array2D[0]);
So you are passing the first array [1,2]. In C an array decays into a pointer
when it is passed to a function.
However, your function function1 should also get the number of
elements of the array.
void function(int *arr, size_t len)
{
size_t i;
for(i = 0; i < len; ++i)
printf("%d\n", arr[i]);
}
Then you can call it2
int array2D[2][2] = { { 1,2} ,{3,4}};
int array1D[3] = {1,2,3};
function(*array2D, sizeof *array2D / sizeof **array2D);
function(array1D, sizeof array1D / sizeof *array1D);
disp (&arr[i]); // why i need here & and above in the function not
Because arr[i] would give you the value stored at the position i, disp
expects a pointer, so you use the &-operator which returns the address of the
array at the position i, which is also equivalent to arr + i.
1Don't call your functions function. Technically that is valid name, but it
would be better if you give your function more explicit names so that just by
reading the name, you know what the functions does.
2Note that sizeof array / sizeof *array only works with arrays. If you have a
function and you expect an array, you will get only a pointer to the array.
In this case you also would need to pass the length of the array.
We're used to the fact that int mike[10] decays to int *, which points to the first thing in the array. So it seems like int sam[5][10] might also decay to int * pointing to the first element of the array. But int sam[5][10] is not a "two-dimensional array of int" that decays to an int pointer, it's an array of five arrays of ten integers. The first thing in sam is the first of the five arrays, so sam decays to a pointer to an array of ten integers, which type is written int (*)[10], though it rarely is written.
So your array2D decays to a different type than integer pointer, which is why your call function(array2D); creates a type mismatch. But your call function(*array2D); does work because (as noted above) *array2D is the same as array2D[0], which is an array of integers, and does decay to int *.
For your second case, arr is an array, but arr[i] is an int, since it is just one position in the array. The ampersand operator makes a pointer of what it operates, so &arr[i] is a pointer, and the call works.

Why *pointer_name behaves differently in 1D and 2D array

Why is it that when *q is used in 1D array it gives the value in the array whereas *p in 2D array gives an address instead. Isn't *pointer_name supposed to tell what is stored, so why is output an address instead of 40 (the value in array)?
#include<stdio.h>
int main(){
int a[3][4] = {
{40, 1, 2, 3} ,
{4, 5, 6, 7} ,
{8, 9, 10, 11}
};
int (*p)[4] = a;
int b[4] = {3,4,8,5};
int *q = b;
printf("%d, %d",*q, *p);// output- 3, 10485040
return 0;
}
Because p is a pointer to an array. When you dereference p the array will decay to a pointer to the first element. Doing *p and &(*p)[0] is equivalent (and also equivalent to &a[0][0]).
If you want to print the first element then you need to dereference both pointers, i.e. **p.
2D array means an array of arrays! so each slot of first row in the 2D array should have the address of another array.
for instance if you have an array a[2][3] , the a[0] value is the address of the first slot of an array with size 4. and a[1] like so etc .

C: How to get the last element value of an arrary or an two-dimensional arrary through function call

As we known that the last element value of an array or an two-dimensional array can be obtained by below code:
For an array:
int a[] = {1, 2, 3, 4};
printf("%d", *((int *)(&a + 1) - 1));
For an two dimensional array:
int a[2][2] = {1, 2, 3, 4};
printf("%d", *((int *)(&a + 1) - 1));
Both of those code can output the correct value: 4. But when I changed the code like below:
int foo(int a[][2]) {
return *((int *)(&a + 1) - 1);
}
void main() {
int a[2][2] = {1, 2, 3, 4};
printf("%d", foo(a));
}
Then I cannot get the right value. Is there anything wrong with this code? The main purpose of this code is try to get the last element value without knowing the number of elements. Is this possible?
Thanks in advance.
Yes. In your first two cases, a is an array. However in the last case, a is a pointer. You are forgetting that in a function parameter, an array declarator is adjusted to a pointer declarator. Your function is actually:
int foo(int (*a)[2])
{
where a is a pointer to the first element of the array you called the function with. There is no way for the function to get the dimension of the array (or do anything that requires that information).
Related question
When you pass an array to a function, it decays to a pointer. So when doing e.g. &a in the function, you don't get a pointer to an array of arrays of 2 integers, you get a pointer to a pointer to an array of 2 integers.
I don't know anything about C, but every language has / should have a function to check the length of array and mostly it's called length or simly count.
So, if i would want to get the last element say in php i would:
Var elmt = array[array.count-1]
I hope understood correctly what you wanted.

Resources