How to get an adress of a static array in C - c

Got this
char array1[10][10];
Is it possible to get address of array1 ? In which type could I stock it ?
Already tried the following:
char *hold[10][10];
hold = &array1;
But doesnt work, ideas?

What you have now is a 2D array of char *. You need some parenthesis in this type.
char (*hold)[10][10];
This is a pointer to a 2D array of type char[10][10] that you can assign &array to.

Typically you want to get the address of the first element, not a pointer to a 2D array. The first element is a char [10] (a 1D array), so you need
char (*hold)[10] = array1;
Notice array1 is converted to a pointer to the first element for the assignment. This is not recursively applied!
That way you can dereference the pointer exactly like for the original array:
hold[4][5]
For the char (*hold)[10][10] approach, the syntax is more complicated and not really ideomatic. Accessing an element of the array would require dereferencing the pointer first:
(*hold)[4][5]

Related

C typedef for dereferencing a pointer to a fixed-size 2D array

If I have a pointer to a fixed-size 2D array, e.g.
char (*p)[4][4] = get_array();
is there any way to declare a variable a as
a = *p;
and have a properly be of type char[4][4], so that I can use a[i][j] rather than (*p)[i][j]?
If p is a pointer to an array of arrays of 4 characters, then *p must be an array of arrays of 4 characters (type char [4][4]). Unfortunately you can't really use that type for other variables (only when defining such an array), not even using a typedef. That's because you can't assign to arrays, only copy to them.
Luckily, as arrays naturally decays to pointers to their first element, an array of arrays of 4 characters will then decay to a pointer to an array of 4 characters.
That is, the expression *p is equivalent to char (*)[4], which have to be the type of a:
char (*a)[4];
a is an array of type char [4][4].
is there any way to declare a variable a as
a = *p;
No, you cannot initialize array like this and arrays are not assignable.
Instead, you should do:
memcpy (a, *p, sizeof(a));
and then you can use a[i][j].

Two dimensional array address and corresponding pointer to its 1st element

In terms of one dimensional array, its array name is also the address of the first element. So it is fine to assign it to a pointer, like below:
char data[5];
char* p_data=data;
So I think it should be the same with two dimensional array. The array name should be the address of the first element's address. So, I'd like to do something like this:
char data[5][5];
char** pp_data=data;
Then I get a warning saying the pointer type char** is incompatible with char[ ][ ].
Why does this happen? Do I comprehend the pointer and array concept wrong?
You're right that an array is often referred to by a pointer to its first element. But when you have the "two dimensional" array
char data[5][5];
what you actually have is an array of arrays. The first element of the array data is an array of 5 characters. So this code would work:
char (*pa_data)[5] = data;
Here pa_data is a pointer to array. The compiler won't complain about it, but it may or may not actually be useful to you.
It's true that a pointer-to-pointer like your char **pp_data can be made to act like a two-dimensional array, but you have to do some memory allocation for it to work. It turns out that in the array-of-arrays char data[5][5] there's no pointer-to-char for pp_data to be a pointer to. (In particular, you could not say something like pp_data = &data[0][0].)
See also this question in the C FAQ list.
Two dimensional array is actually an array of arrays. It means the first element of that array is an array. Therefore a two dimensional array will be converted to pointer to an array (its first element).
In
char data[5][5];
when used in expression, wit some exception, data will be converted to pointer to its first element data[0].data[0] is an array of char. Therefore the type of data will become pointer to an array of 5 char, i.e. char (*)[5].
char ** and char (*)[5] are of different type, i.e. incompatible type.

Is this a pointer to a pointer of the start of an array?

I've just been helping someone out with some code. He had this:
char dataArray[10];
Then wanted to get a pointer to the start of the array. Rather than use:
&dataArray[0]
or just
dataArray
He used
&dataArray
Did he end up with a pointer to a pointer there? I'm not sure what &dataArray would give him.
&dataArray[0] is of type char *. That is a pointer to char.
dataArray is of type char[10]
&dataArray will be of type char (*)[10]. That is a pointer-to-array.
Apart from that, the value will be same, i.e., they point to the same address but their types need not be compatible.
None of them is a pointer-to-pointer here. They are just pointer with different types.
Note: Because the array decaying property, char [100] will decay to a char *, for example, when passed as an agument of a function.
dataArray and &dataArray[0] points to the address of the first index of the array so they are the same thing but &dataArray will point to the address of the whole array or we can say it will give the address where the whole 10 index array is located(as a whole)

Is Str a "pointer" or a "pointer to pointer" in Str[Col][Row]?

Is Str a "pointer" or a "pointer to pointer" in Str[3][5]?
I usually declare char **Str to make a simulated 2D array, but how to send the address of Str[3][5] to another function, and how to set the parameter of that function in order to modify values in Str[3][5] ?
As far as I know, the compiler treats a 2D array as an ordinary array, so I should send Str (a pointer) to the other function. But how to modify the value of Str[3][5] via the received pointer?
An array of T when used in most expressions will decay to a pointer of type "pointer to T" and have the value equal to the address of the first element of the array.
If Str is declared as:
char Str[3][5];
Then Str will decay to char (*)[5], and have the value of &Str[0]. If passing to a function, you can declare the function as follows:
void foo (char (*str)[5], size_t n);
And within foo(), you would access str as you would access Str itself.
Pointer address in a C multidimensional array
To expand on this answer to a similar question, when we type to get addresses of arrays. The name of the array is actually a pointer to the first variable in the array.
You can't really pass a pointer of a particular part of an array, as what we interact with in coding is the pointer itself. (array + 1) == array[1] Let's say we have create an array pointer int* arrayPointer; and you want to get the second variable in the array. You could either assign arrayPointer = array + 1 or arrayPointer = &array[1]
So if you want to modify part of array[3][5] the easiest way is to pick that part of the array and assign a variable to it. For example if you want to modify the first "column" and first "row" you would type...
array[0][0] = variable
Hope this helps.

Does name of a 2D array give its base address in C?

Does name of a 2D array give its base address in C like in 1D array? And how can i store the base address of a 2d array in a pointer variable?
It decays to a pointer to the first element:
int a[5][7];
decays to
int (*pa)[7] = a;
In practice, the value stored in pa will be the same as that of a pointer to the first int element of a, but the correct way to get a pointer to the first element of a is to use
int *p_elm = &(a[0][0]);
or equivalently
int *p_elm = &(pa[0][0]);
However, note that a pointer to the first element can't (strictly) be treated as a pointer to the beginning of a N*M array; see e.g. http://www.lysator.liu.se/c/c-faq/c-2.html#2-11
A 2D array is essentially a 1D array, where each element itself is an array.
The name of the array is equivalent to &arrayName[0].
Assigning a pointer to this address is same as always, something like:
int myArray[5][5];
int (*arrayptr)[5] = myArray;
This says arrayptr is a pointer to an array of 5 integers. Since myArray is an address to the first element, which is an int[5], our declaration is fine.
When you dereference this pointer however, you're going to get the first element, which is an array. Therefore you can do something like:
(*arrayptr)[3]; // parens necessary for precedence issues
to access the 3rd element in the array nested inside the first element of the "outer array".
It is the equivalent of
myArray[0][3];
What's happening is you're dereferencing arrayptr which will yield a 1D array (of size 5 in this case).. then you're asking for the 4th element of this 1D array.
Now, if what you're looking for is the top-left "corner" of the matrix, you will want:
int *topleft = &(myArray[0][0]);
Yes and you the store the address as:
int *p = &a[0][0];
Use the address of operator to point to the offset of base.
char base[2][2];
int *basepointer = &base;
I would like to give answer specific to your question.
Whenever you pass name of a 2D Array, that name of array will be decayed into pointer to first element,
In a multi-dimensional array, as multi dimensional array is array of arrays, so first element will be array itself.
So name of 2D array will be decayed to pointer to array, ie pointer to first row having number of elements equal to number of columns in your 2D array.
Remember 2D array is received in a function as pointer to array not pointer to pointer.
int main()
{
int arr[2][3];
display(arr);
............
}
void display( int (*arr)[3])
{
}

Resources