I need to modify some C++ code, but since I'm relatively new to the language I'm having trouble understanding some expressions.
I have a function
void func(double m[2][12],double n[2][3])
that is invoked from inside an other function like this
double A[12];
double B[6];
(...)
func( (double (*)[12])A, (double (*)[3])B )
The last line of code is casting a 1D array to a 2D one, but what is happening there exactly? Can I use the same technique to convert a 1D array into a 2D, like this?:
double A[12];
double B[6];
(double (*)[12])A[0][5] = 5;
What is happening is exactly what you mentioned - the caller is casting the 1 dimensional arrays into in order to pass them to func()
, which has two pointer-to-2D-array parameters. Since 2D arrays in C are just 'arrays of arrays' (i.e. there are no pointers involved) this translation is certainly possible. For example, this 1D array:
int oneDimensionalArray[] = { 0, 1, 2, 3 };
and this 2D array:
int twoDimensionalArray[] = { { 0, 1 },
{ 2, 3 } };
Have exactly the same memory layout. You could coerce the types into matching by using crazy-town casting operations like the one in your question.
And as to your second question, yes, you can do that, but you need one more set of parentheses:
((double (*)[12])A)[0][5] = 5;
I don't recommend writing code with this kind of crazy stuff going on, though. Where did the program come from?
The casting is not from 1D to 2D array but to a pointer to a static 1D array!
double m1[12];
means a variable m1 of type 'static array of 12 doubles'
double m2[2][12];
means a variable m2 of implicitly inferred type 'static array of 2 elements of type "static array of 12 doubles"' When static arrays are used as function arguments they are degenerated to pointers of the type of the array elements. Therefore, for array m1, above we can use any the following functions
f11(double arg[12]) {}
f12(double * arg) {}
both can be called with any pointer to double or any array of double elements like:
double a=0.0;
double b[10];
f11(&a); f11(b);
f12(&b); f12(b);
Similarly, for array m2 (above), the type of a single element is 'double[12]'. Thus we can use any the following functions:
f21(double arg[2][12]) {}
f22(double * arg[12]) {}
which can be called with any pointer to 'array of 12 doubles' or any array of elements of type 'array of 12 doubles' like:
double c[12];
double d[6][12];
f21((double (*)[12])c); f21(d);
f22((double (*)[12])c); f22(d);
Now for your code, the function void func(double m[2][12],double n[2][3])
actually expects a pointer to 'static array of 12 doubles' and a pointer to 'static array of 3 doubles'. Thus the call that you see
double A[12];
double B[6];
func( (double (*)[12])A, (double (*)[3])B )
actually casts A (which is degenerated to pointer to double) to pointer to 'static array of 12 doubles' and casts B (which is also degenerated to pointer to double) to pointer to 'static array of 3 doubles' Because all of the given arrays work with doubles and static arrays are represented sequentially in memory such casting may not cause logical errors.
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