The basics
Arrays in c are declared and accessed using the [] operator. So that
int ary1 [5]; >
declares an array of 5 integers. Elements are numbered from scratch, so ary1 [0] is the first element, and ary1 [4] is the last element. Note1: There is no default initialization, so the memory occupied by the array may first contain something . ary1 [5] : ary1 [5] accesses memory in undefined state (which may not even be available to you), so do not do this!
Multidimensional arrays are implemented as an array of arrays (arrays (from ...)). So
float ary2 [3] [5]; >
declares an array of three one-dimensional arrays of 5 floating point numbers. Now ary2 [0] [0] is the first element of the first array, ary2 [0] [4] is the last element of the first array, and ary2 [2] [4] is the last element of the last array. The '89 standard requires this data to be contiguous (section A8.6.2 on page 216 of my K & R 2nd ed. Ed.), But it seems agnostic to populate.
Trying to go dynamically in more than one dimension
If you do not know the size of the array at compile time, you need to dynamically allocate the array. Tempting to try
double * buf3; buf3 = malloc (3 * 5 * sizeof (double)); >
which should work if the compiler did not insert the selection (add extra space between one-dimensional arrays). It could be safer:
double * buf4; buf4 = malloc (sizeof (double [3] [5])); >
but in any case, the trick comes to dereferencing. You cannot write buf [i] [j] because buf is of the wrong type. You also cannot use
double ** hdl4 = (double **) buf; hdl4 [2] [3] = 0; >
because the compiler expects hdl4 be the address of the double address. You also cannot use double incomplete_ary4 [] []; because it is a mistake;
So what can you do?
- Do arithmetic of rows and columns yourself
- Select and do work in function
- Use an array of pointers (the qrdl mechanism says so)
Do it yourself math
Just calculate the memory offset for each item as follows:
for (i = 0; < 3; ++ i) { (j = 0; j < 3; ++ j) { buf3 [i * 5 + j] = someValue (i, j); } } >
Select and do work in function
Define a function that takes the required size as an argument and acts like normal
void dary (int x, int y) { double ary4 [x] [y]; ary4 [2] [3] = 5; } >
Of course, in this case ary4 is a local variable, and you cannot return it: all work with the array must be performed in the function that you call in the functions that it .
Array of pointers
Consider this:
double ** hdl5 = malloc (3 * sizeof (double *)); (i = 0; < 3; ++ i) { hdl5 [i] = malloc (5 * sizeof (double)) } >
Now hdl5 points to an array of pointers, each of which points to an array of doubles. The cool bit is that you can use two-dimensional array notation to access this structure --- hdl5 [0] [2] gets the middle element of the first line --- but it's not less than an object than the two-dimensional array declared by double ary [3] [5]; .
This structure is more flexible than a two-dimensional array (because the lines do not have to be the same length), but access to it will usually be slower and require more memory (you need a place to store intermediate pointers).
Please note that since I did not configure any guards, you will have to independently monitor the size of all arrays.
Arithmetic
c does not support vector, matrix or tensor math, you will have to implement it yourself or bring a library.
Scaling up and adding and subtracting arrays of the same rank are easy: just iterate over the elements and perform the operation as you go. Domestic products are also straightforward.
External products mean more cycles.