In perl I can create 1D arrays and then create 2D array from them, following way:
@a1=(a,b,c)
@a2=(d,e,f)
@a3=(g,h,i)
@m23_v1=(\@a1,\@a2,\@a3)
Here is another way (assuming that @a1
, @a2
and @a3
are the same as in previous example):
@m23_v2=([@a1],[@a2],[@a3])
The difference between those two ways is that when backslashes are used then changing $a[0][0]
will also change $a1[0]
. On the other hand when brackets are used then the value is copied so changing $a[0][0]
will not change $a1[0]
. Bellow are memory addresses of variables which should clarify what I mean:
print \$a1[0]
SCALAR(0x2006c0a0)
print \$m23_v1[0][0]
SCALAR(0x2006c0a0)
print \$m23_v2[0][0]
SCALAR(0x2030a7e8)
How to achieve the same but in C? I've tried following code:
# include <stdio.h>
int main(){
int a1[3] = {1,2,3};
int a2[3] = {4,5,6};
int m23[2][3] = {a1, a2};
printf("%d\n", a1[0]);
printf("%d\n", m23[0][0]);
}
But it gives me following compilation warnings:
2d.c: In function ‘main’:
2d.c:4:3: warning: initialization makes integer from pointer without a cast [enabled by default]
2d.c:4:3: warning: (near initialization for ‘m23[0][0]’) [enabled by default]
2d.c:4:3: warning: initialization makes integer from pointer without a cast [enabled by default]
2d.c:4:3: warning: (near initialization for ‘m23[0][1]’) [enabled by default]
2d.c:5:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
After execution the C code returns following:
1
-1077371888
Questions:
You get the warning because when you initialize the m23
array, the arrays a1
and a2
decays to pointers, making you have an array not of arrays but of pointers.And that's also how you solve your problem, by declaring m23
as an array of pointers:
int *m23[2] = { a1, a2 };
You can use array of pointers to get an equivalent of backslahed version (i.e. @m23_v1
):
#include <stdio.h>
int main(void)
{
int a1[3] = {1,2,3};
int a2[3] = {4,5,6};
int *m23[2] = {a1, a2};
printf("%d\n", a1[0]);
printf("%d\n", m23[0][0]);
return 0;
}
In your code:
int m23[2][3] = {a1, a2};
initializer expects to be filled with integers. Basically you create two-dimensional array with two integers: a1
, a2
. The remaining elements are initialized with zeros. To illustrate it, this looks something like:
int m23[2][3] = {0xaaee33, 0xaaee55, 0, 0, 0, 0};
which is effectively the same as:
int m23[2][3] = {{0xaaee33, 0xaaee55, 0}, {0, 0, 0}}; // two rows, three columns
However, a1
is not an integer. It's name of array, that is implicitely converted to int
(after it is converted into pointer, that points to array's first element). In other words you are implicitely converting addresses of a1
and a2
into two integers. In fact, such operation is illegal in C and such code should not even compile with -pedantic-errors
flag (or equivalent).
what is the equivalent for brackets version (and vice versa)?
The equivalent of braced version is define an multidimensional array of specific size and then copy each element of a1
and a2
arrays into it:
#include <stdio.h>
#include <string.h>
int main(void)
{
int a1[3] = {1,2,3};
int a2[3] = {4,5,6};
int m23[2][3];
memcpy(m23 + 0, a1, sizeof(a1));
memcpy(m23 + 1, a2, sizeof(a2));
printf("%d\n", a1[0]);
printf("%d\n", m23[0][0]);
return 0;
}
Well you can't initialize array with use of other array. You can do it like that:
int m[2][3] = {{1,2,3},{4,5,6}};
This is because a1 and a2 is treated as pointer to int. You can this with array of pointers:
int* m[2] = {a1,a2);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With