Define a matrix and pass it to a function in C - c

I want to create a program in which I can pass a matrix to a function using pointers.
I initialized and scanned 2 matrices in the void main() and then I tried to pass them to a void add function. I think I am going wrong in the syntax of declaration and calling of the function. I assigned a pointer to the base address of my matrix. (for eg: int *x=a[0][0], *y=b[0][0]). What is the right declaration? How can I specify the dimensions?

Given a 2D array of
T a[N][M];
a pointer to that array would look like
T (*ap)[M];
so your add function prototype should look like
void add(int (*a)[COLS], int (*b)[COLS]) {...}
and be called as
int main(void)
{
int a[ROWS][COLS];
int b[ROWS][COLS];
...
add(a, b);
However, this code highlights several problems. First is that your add function is relying on information not passed via the parameter list, but via a global variable or symbolic constant; namely, the number of rows (the number of columns is explicitly provided in the type of the parameters). This tightly couples the add function to this specific program, and makes it hard to reuse elsewhere. For your purposes this may not be a problem, but in general you only want your functions to communicate with their callers through the parameter list and return values.
The second problem is that as written, your function will only work for matrices of ROWS rows and COLS columns; if you want to add matrices of different sizes within the same program, this approach will not work. Ideally you want an add function that can deal with matrices of different sizes, meaning you need to pass the sizes in as separate parameters. It also means we must change the type of the pointer that we pass in.
One possible solution is to treat your matrices as simple pointers to int and manually compute the offsets instead of using subscripts:
void add (int *a, int *b, size_t rows, size_t cols)
{
size_t i;
for (i = 0; i < rows; i++)
{
size_t j;
for (j = 0; j < cols; j++)
{
*(a + cols * i + j) += *(b + cols * i + j);
}
}
}
and call it like so:
int main(void)
{
int a[ROWS][COLS] = {...};
int b[ROWS][COLS] = {...};
int c[ROWS2][COLS2] = {...};
int d[ROWS2][COLS2] = {...};
...
add(a[0], b[0], ROWS, COLS);
add(c[0], d[0], ROWS2, COLS2);
...
}
The types of a[0] and b[0] are "COLS-element arrays of int"; in this context, they'll both be implicitly converted to "pointer to int". Similarly, c[0] and d[0] are also implicitly converted to int *. The offsets in the add() function work because 2D arrays are contiguous.
EDIT I just realized I was responding to caf's example, not the OP, and caf edited his response to show something very similar to my example. C'est la guerre. I'll leave my example as is just to show a slightly different approach. I also think the verbiage about passing information between functions and callers is valuable.

Something like this should do the trick.
#define COLS 3
#define ROWS 2
/* Store sum of matrix a and b in a */
void add(int a[][COLS], int b[][COLS])
{
int i, j;
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
a[i][j] += b[i][j];
}
int main()
{
int a[ROWS][COLS] = { { 5, 10, 5} , { 6, 4, 2 } };
int b[ROWS][COLS] = { { 2, 3, 4} , { 10, 11, 12 } };
add(a, b);
return 0;
}
EDIT: Unless you want to specify the dimensions at runtime, in which case you have to use a flat array and do the 2D array arithmetic yourself:
/* Store sum of matrix a and b in a */
void add(int rows, int cols, int a[], int b[])
{
int i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
a[i * cols + j] += b[i * cols + j];
}

#caf has shown a good code example.
I'd like to point out that:
I assigned a pointer to the base
address of my matrix. (for eg: int
*x=a[0][0],*y=b[0][0]).
You are not assining a pointer to the base of the matrix. What this does is assign to the value pointed by x and y, the base value in a and b respectively.
The right way would be
int (*x)[] = a;
int (*y)[] = b;
or alternatively
int *x = &a[0][0];
int *y = &b[0][0];

Related

How can I use int** to pass a 2D array in C

Trying to work on leetcode #497 in C on my vscode. When writing main(), I am not sure how to deal with int** that leetcode provides. Is it possible to pass a 2D array using int**?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int rectsSize;
int * rectsColSize;
int** rects;
} Solution;
int points[100];
Solution* solutionCreate(int** rects, int rectsSize, int* rectsColSize) {
Solution* sol = malloc(sizeof(Solution));
sol->rects = rects;
sol->rectsSize = rectsSize;
sol->rectsColSize = rectsColSize;
//some codes
}
return sol;
}
int* solutionPick(Solution* obj, int* retSize) {
//some codes
return ret;
}
void solutionFree(Solution* obj) {
free(obj);
}
int main(void)
{
int rects[2][4] = {{1, 1, 5, 5}, {6, 6, 9, 9}};
int rectsSize = 2;
int rectsColSize = 4;
int retSize;
Solution* obj = solutionCreate(rects, rectsSize, &rectsColSize);
int* param_1 = malloc(sizeof(int));
param_1 = solutionPick(obj, &retSize);
solutionFree(obj);
return 0;
}
While in general there are many different ways to handle 2D array, the simple answer is no. There is a lot of info about 2d arrays in C: 1, 2, 3, etc. In principle, when dealing with 2d arrays, every dimension except first to the left needs to be specified exactly. In your case, every rectangle is defined by 4 integers, so instead int** rects consider int*[4] rects. This makes rectsColSize useless, because now each column has constant size of 4 ints.
Just for completness: what you are trying to do is second approach to arrays, where each column has independent size, and (usually) additional malloc call. While this approach is also valid and requires int** type, it is not needed for your task. Nice description of the difference here.
Edit
Here is how to loop through 2d arrays:
#define col 4
void print_2d(int (*a)[col], int aSize){
for(size_t i = 0; i < aSize; i++){
for(size_t j = 0; j < col; j++){
printf("%d ", a[i][j]);
}
printf("\n");
}
}
and here for int**:
void print_pp(int** a, int aSize, int* aiSize){
for(size_t i = 0; i < aSize; i++){
for(size_t j = 0; j < aiSize[i]; j++){
printf("%d ", a[i][j]);
}
printf("\n");
}
}
It seems that you want to convert int*[4] to int**, or more precisely, int*[4] arr2d with it's size int arr2dSize to structure Solution. In that case, here is wrapper to solutionCreate.
Solution* solutionCreateWrap(int (*arr2d)[4], int arr2dSize) {
int* rectsColSize = malloc(arr2dSize * sizeof(int));
int** rects = malloc(arr2dSize * sizeof(int*));
size_t arr2dMem = arr2dSize * 4 * sizeof(int);
rects[0] = malloc(arr2dMem);
memcpy(rects[0], arr2d, arr2dMem);
rectsColSize[0] = 4;
for(size_t i = 1; i < arr2dSize; i++){
rects[i] = rects[0] + i*4;
rectsColSize[i] = 4;
}
sol->rects = rects;
sol->rectsSize = rectsSize;
sol->rectsColSize = rectsColSize;
//some codes
}
return solutionCreate(rects, arr2dSize, rectsColSize);
}
Now for int rects[2][4] = {{1, 1, 5, 5}, {6, 6, 9, 9}}; call solutionCreateWrap(rects, 2) will return initialised structure Solution. It looks gruesome, and it's details are even worse, so if it just works, you may skip the explanation. Understanding low level C details isn't neccesarily to write in it, and this (or any other) explanation cannot possibly cover this matter, so don't be discouraged, if you won't get it all.
arr2d is contiguous block of memory of arr2dSize*4 integers. When multiplied by sizeof(int) we get size in bytes - arr2dMem in my code. Declaration int (*arr2d)[4] means, that arr2d is of type int*[4]. Knowing this we can cast it to int* like so: int* arr = (int*)arr2d and expression arr2d[i][j] is translated as arr[i*4+j].
The translation to rects is as follows; int** is array of pointers, so every rect[i] has to be pointer to i-th row of arr2d. Knowing this, everything else is pointer arithmetic. rects[0] = malloc(arr2dMem); and memcpy(rects[0], arr2d, arr2dMem); copies whole arr2d to rect[0], then every next rects[i] = rects[0] + i*4; is shifted 4 integers forward. Because rect is of type int**, the expression rects[i][j] translates to *(rects[i]+j), and replacing rects[i] by rects[0] + i*4, we get *((rects[0] + 4*i)+j), that is rects[0][4*i+j]. Note striking similarity between last expression, and arr[i*4+j]. rectsColSize is somewhat superfluous in this case, but it is essential in general int** array, when every subarray could have different sizes. After wrap function is done, rects is exact copy of arr2d, but with type appropriate for your Solution structure, so we can call solutionCreate().

How to operate matrices of different size with one function in C?

I have a code from Mathlab, where all matrix operations are done by a couple of symbols. By translating it into C I faced a problem that for every size of matrix I have to create a special function. It's a big code, i will not place it all here but will try to explain how it works.
I also have a big loop where a lot of matrix operations are going on. Functions which are operating with matrices should take matrices as income and store results in temporary matrices for upcoming operations. In fact i know the size of matrices but i also want to make the functions as universal as possible. In oder to reduce code size and save my time.
For example, matrix transposition operation of 2x4 and 4x4 matrices:
void A_matrix_transposition (float transposed_matrix[4][2], float matrix[2][4], int rows_in_matrix, int columnes_in_matrix);
void B_matrix_transposition (float transposed_matrix[4][4], float matrix[4][4], int rows_in_matrix, int columnes_in_matrix);
int main() {
float transposed_matrix_A[4][2]; //temporary matrices
float transposed_matrix_B[4][4];
float input_matrix_A[2][4], input_matrix_B[4][4]; //input matrices with numbers
A_matrix_transposition (transposed_matrix_A, input_matrix_A, 2, 4);
B_matrix_transposition (transposed_matrix_B, input_matrix_B, 4, 4);
// after calling the functions i want to use temporary matrices again. How do I pass them to other functions if i dont know their size, in general?
}
void A_matrix_transposition (float transposed_matrix[4][2], float matrix[2][4], int rows_in_matrix, int columnes_in_matrix)
{ static int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{ transposed_matrix[j][i] = matrix[i][j];
}
}
}
void B_matrix_transposition (float transposed_matrix[4][4], float matrix[4][4], int rows_in_matrix, int columnes_in_matrix)
{ static int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{ transposed_matrix[j][i] = matrix[i][j];
}
}
}
The operation is simple, but the code is massive already because of 2 different functions, but it will be a slow disaster if I continue like this.
How do i create one function for transposing to operate matrices of different sizes?
I suppose it can be done with pointers, but I don't know how.
I'm looking for a realy general answer to understand how to tune up the "comunication" between functions and temporary matrices, best with an example. Thank you all in advance for the information and help.
There are different way you can achieve this in c from not so good to good solutions.
If you know what the maximum size of the matrices would be you can create a matrix big enough to accommodate that size and work on it. If it is lesser than that - no problem write custom operations only considering that small sub-matrix rather than the whole one.
Another solution is to - create a data structure to hold the matrix this may vary from jagged array creation which can be done using the attribute that is stored in the structure itself. For example: number of rows and column information will be stored in the structure itself. Jagged array gives you the benefit that now you can allocate de-allocate memory - giving you a better control over the form - order of the matrices. This is better in that - now you can pass two matrices of different sizes and the functions all see that structure which contain the actual matrix and work on it. (wrapped I would say).
By Structure I meant something like
struct matrix{
int ** mat;
int row;
int col;
}
If your C implementation supports variable length arrays, then you can accomplish this with:
void matrix_transposition(size_t M, size_t N,
float Destination[M][N], const float Source[N][M])
{
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m][n] = Source[n][m];
}
If your C implementation does not support variable length arrays, but does allow pointers to arrays to be cast to pointers to elements and used to access a two-dimensional array as if it were one-dimensional (this is not standard C but may be supported by a compiler), you can use:
void matrix_transposition(size_t M, size_t N,
float *Destination, const float *Source)
{
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m*N+n] = Source[n*M+m];
}
The above requires the caller to cast the arguments to float *. We can make it more convenient for the caller with:
void matrix_transposition(size_t M, size_t N,
void *DestinationPointer, const void *SourcePointer)
{
float *Destination = DestinationPointer;
const float *Source = SourcePointer;
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m*N+n] = Source[n*M+m];
}
(Unfortunately, this prevents the compiler from checking that the argument types match the intended types, but this is a shortcoming of C.)
If you need a solution strictly in standard C without variable length arrays, then, technically, the proper way is to copy the bytes of the objects:
void matrix_transposition(size_t M, size_t N,
void *DestinationPointer, const void *SourcePointer)
{
char *Destination = DestinationPointer;
const char *Source = SourcePointer;
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
{
// Calculate locations of elements in memory.
char *D = Destination + (m*N+n) * sizeof(float);
const char *S = Source + (n*M+m) * sizeof(float);
memcpy(D, S, sizeof(float));
}
}
Notes:
Include <stdlib.h> to declare size_t and, if using the last solution, include <string.h> to declare memcpy.
Variable length arrays were required in C 1999 but made optional in C 2011. Good quality compilers for general purpose systems will support them.
If you are using C99 compiler, you can make use of Variable Length Array (VLA's) (optional in C11 compiler). You can write a function like this:
void matrix_transposition (int rows_in_matrix, int columnes_in_matrix, float transposed_matrix[columnes_in_matrix][rows_in_matrix], float matrix[rows_in_matrix][columnes_in_matrix])
{
int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{
transposed_matrix[j][i] = matrix[i][j];
}
}
}
This one function can work for the different number of rows_in_matrix and columnes_in_matrix. Call it like this:
matrix_transposition (2, 4, transposed_matrix_A, input_matrix_A);
matrix_transposition (4, 4, transposed_matrix_B, input_matrix_B);
You probably don't want to be hard-coding array sizes in your program. I suggest a structure that contains a single flat array, which you can then interpret in two dimensions:
typedef struct {
size_t width;
size_t height;
float *elements;
} Matrix;
Initialize it with
int matrix_init(Matrix *m, size_t w, size_t h)
{
m.elements = malloc((sizeof *m.elements) * w * h);
if (!m.elements) {
m.width = m.height = 0;
return 0; /* failed */
}
m.width = w;
m.height = h;
return 1; /* success */
}
Then, to find the element at position (x,y), we can use a simple function:
float *matrix_element(Matrix *m, size_t x, size_t y)
{
/* optional: range checking here */
return m.elements + x + m.width * y;
}
This has better locality than an array of pointers (and is easier and faster to allocate and deallocate correctly), and is more flexible than an array of arrays (where, as you've found, the inner arrays need a compile-time constant size).
You might be able to use an array of arrays wrapped in a Matrix struct - it's possible you'll need a stride that is not necessarily the same as width, if the array of arrays has padding on your platform.

Passing an array created from fscanf into a new function

I have successfully fscanf a text file and saved in to an array E2N1. I am trying to pass this into a function as a pointer but it is not working. Whenever I try to call E2N1[0][0], it says that E2N is neither an array or a pointer. I've been looking all over for a solution on this.
(Sorry E2N was meant to be E2N1)
I use fscanf as:
int E2N1[noz.rowE2N][Q.N];
FILE* f = fopen("E2N.txt", "r");
for(i=0; i<noz.rowE2N; i++){
for (j=0; j<Q.N; j++){
fscanf(f,"%d",&E2N1[i][j]);
}
fscanf(f,"\n");
}
fclose(f);
and again I can't pass E2N1 into function.
Your help will be greatly appreciated.
The function is:
double *dudtF = stiffness(&U, &massM, &noz, &newV, &E2N1, &I2E, &B2E, &PP, &QQ);
and I write the function header as:
double *stiffness(double *U, double *massM, MESH *meshN, double *V1, int *E2N1, int *I2E, int *B2E, ordApprox *pp, ordApprox *qq)
V1, I2E, B2E are three arrays and I'm trying to do the same with them as I am trying to do with E2N1.
The funny thing about arrays is that they actually act as pointers.
if you have array char a[3] the variable is equivalent to char* p the same way if you have array char b[3][4] the variable b is equivalent to char** q. In other words, you should consider changing the handling in the method to take reference to reference (and possibly once more to reference) to integer.
Try google... here are some results I've got.
http://www.dailyfreecode.com/code/illustrate-2d-array-int-pointers-929.aspx
http://www.cs.cmu.edu/~ab/15-123S09/lectures/Lecture%2006%20-%20%20Pointer%20to%20a%20pointer.pdf
You don't need to pass as &E2N1, just pass as E2N1 no & as array name itself translates to pointer.
double *dudtF = stiffness(&U, &massM, &noz, &newV, E2N1, &I2E, &B2E, &PP, &QQ);
Also, you need to take it as int ** as its 2-dimensional array.
double *stiffness(double *U, double *massM, MESH *meshN, double *V1, int **E2N1, int *I2E, int *B2E, ordApprox *pp, ordApprox *qq)
Here is the example how to transfer matrix from one function to another ...
void foo (int **a_matrix)
{
int value = a_matrix[9][8];
a_matrix[9][8] = 15;
}
void main ()
{
#define ROWS 10
#define COLUMNS 10
int **matrix = 0;
matrix = new int *[ROWS] ;
for( int i = 0 ; i < ROWS ; i++ )
matrix[i] = new int[COLUMNS];
matrix[9][8] = 5;
int z = matrix[9][8] ;
foo (matrix);
z = matrix[9][8] ;
}
You cannot reference a multi-dimensional array passed to a function by point referencing as in the following:
int iVals[10][10];
foo(iVals);
void foo(int** pvals)
{
// accessing the array as follows will cause an access violation
cout << pvals[0][1]; // access violation or unpredictable results
}
You will need to specify the second dimension to the array in the function prototype
for example:
foo(int ivals[][10])
{
cout << ivals[0][1]; // works fine
}
If do not know the dimensions, then I would suggest you follow the principles outlined here:
void foo(int *p, int r, int c)
{
for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
printf("%d\n", p[i*c+j]);
}
}
}
int c[6][6];
// pointer to the first element
foo(&c[0][0], 6, 6);
// cast
foo((int*)c, 6, 6);
// dereferencing
foo(c[0], 6, 6);
// dereferencing
foo(*c, 6, 6);
I hope this helps.
Alternatively you could use SAFEARRAY - see:
http://limbioliong.wordpress.com/2011/06/22/passing-multi-dimensional-managed-array-to-c-part-2/

passing statically allocated 2D arrays as function arguments in C

Consider this code:
#include <stdio.h>
#define N 5
void printMatrix(int (*matrix)[N],int n)
{
int i,j;
for(i=0;i<n;i++){
for(j=0;j<n;j++)
printf("%d",matrix[i][j]);
printf("\n");
}
}
int main()
{
int R[N][N]={{1,2,3},{4,5,6},{7,8,9}};
printMatrix(R,3);
}
This works fine as expected.
Now, I thought to write the functions handling 2D-matrices in a separate source file and link them wherever required.
But then I ran into a problem as in the function printMatrix, the size of array of int to which matrix points (i.e N) is required at compile-time. So, my functions would not work in other cases when the size is different.
So,How can I handle this?
Dynamic Arrays are a solution but i want to know if it can be done with static arrays.
You can't use the built-in 2D array type if both sizes are not known at compile time. A built-in 2D array must have at least one of the two sizes known at compile time.
If both sizes are run-time values, then you have no other choice but to use a "manual" implementation of 2D array, like an array of pointers to arrays, for example. In that case the function declaration might look as follows (two alternative equivalent forms)
void printMatrix(int *const *matrix, int n, int m);
void printMatrix(int *const matrix[], int n, int m);
To access to the array elements you can still use the "traditional" syntax
matrix[i][j]
The array itself would be created as follows (a simple example)
int row0[] = { 1, 2, 3 };
int row1[] = { 4, 5, 6 };
int *matrix[2];
matrix[0] = row0;
matrix[1] = row1;
printMatrix(matrix, 2, 3);
But if you already have a matrix implemented as a built-in 2d array
int matrix[2][3] = { ... };
then just to be able to pass it to the above function you can "convert" it into the above form by using an additional temporary "row pointer" array
int *rows[2];
rows[0] = matrix[0];
rows[1] = matrix[1];
printMatrix(rows, 2, 3);
Write yourself a macro:
#define MAT(i,j) matrix[i*n + j];
and declare "matrix" as a simple pointer to an "int".
Calculate the array index yourself. This will handle an arbitrary two dimensional array, for example:
void printMatrix(int *matrix,int n, int m)
{
int i,j;
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%d",matrix[m * i + j]);
printf("\n");
}
}
Don't try to pass it as a 2-D array; pass a pointer to the first element, then compute offsets manually:
void printMatrix(int *a, size_t m, size_t n)
{
size_t i,j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("a[%lu][%lu] = %d\n",
(unsigned long) i,
(unsigned long) j,
a[i*n+j]); // treat a as 1-d array, compute offset manually
}
}
}
int main(void)
{
int arr[5][4];
...
printMatrix(&arr[0][0], 5, 4);
...
}
Granted, this will only work for contiguously allocated arrays.
Although the syntax is not exactly the same, but this also happens to work a bit:
#include <stdio.h>
#define N 5
void printMatrix(int* row,int n,int sz)
{
int i,j;
int *currRow;
for(i=0;i<n;i++){
currRow = row+i*sz;
for(j=0;j<n;j++)
printf("%d",currRow[j]);
printf("\n");
}
}
int main()
{
int R[N][N]={{1,2,3},{4,5,6},{7,8,9}};
printMatrix(R[0],3,sizeof(R[0])/sizeof(int));
}

Reference a 2-D array column in C?

Is there an easy way to reference a column in a 2-D array as a separate 1-D array in plain old C (not C++ or C#)? It's easy to do this for a row. Asssume I have 2 functions:
double doSomethingWithARow( double theRow[3] );
double doSomethingWithACol( double theCol[100] );
Then, I might use the first one like this:
double matrix[100][3];
double result;
// pass a single row to a function as an array
// this essentially passes the 3-element array at row 48 to the function
for( int i=0; i < 100; i++ )
{
result = doSomethingWithARow( matrix[i] );
}
What I want it a way to access a column easily.
for( int j=0; j < 3; j++ )
{
result = doSomethingWithACol( ??????????? );
}
The only thing I've come up with so far is transforming the matrix to swap the rows with the columns. But this code is supposed to be as efficient as possible in terms of memory and speed. With all of the convoluted ways to reference pointers in C, it seems like there should be a way to do this.
Well, you'd have to pass the size of a row, and the number of rows:
double doSomethingWithACol(double *matrix, size_t colID, size_t rowSize, size_t nRows);
Now you can make use of the fact that matrix[i][j] = matrix + i * rowSize + j;
Alternatively, you can also use the following signature:
double doSomethingWithACol(double *colPtr, size_t rowSize, size_t nRows);
Here, you'll have to pass the pointer to the first element of the column that you want to process, instead of the pointer to the first row.
Example code: This code sums the elements in the second column (compile with gcc -o main -Wall -Wextra -pedantic -std=c99 test.c):
#include <stdio.h>
#include <stdlib.h>
double colSum1(double *matrix, size_t colID, size_t rowSize, size_t nRows)
{
double *c = NULL, *end = matrix + colID + (nRows * rowSize);
double sum = 0;
for (c = matrix + colID; c < end; c += rowSize) {
sum += *c;
}
return sum;
}
double colSum2(double *colPtr, size_t rowSize, size_t nRows)
{
double *end = colPtr + (nRows * rowSize);
double sum = 0;
for (; colPtr < end; colPtr += rowSize) {
sum += *colPtr;
}
return sum;
}
int
main(void)
{
double matrix[4][3] = {
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
{9, 10, 11}
};
printf("%f\n", colSum1(*matrix, 1, 3, 4));
printf("%f\n", colSum2(&matrix[0][1], 3, 4));
printf("%f\n", colSum2(matrix[0] + 1, 3, 4));
return EXIT_SUCCESS;
}
A nice typesafe way to do this without specifying the dimensions as a separate parameters is as follows:
#define ROWS 100
#define COLUMNS 30
void doSomethingToAllRows(double (*row)[ROWS][COLUMNS], int col, double val)
{
for(size_t i = 0; i < ROWS; ++i)
(*row)[i][col] = val;
}
void doSomethingToAllColumns(double (*col)[ROWS][COLUMNS], int row, double val)
{
for(size_t i = 0; i < COLUMNS; ++i)
(*col)[row][i] = val;
}
int main(int argc, char **argv)
{
double matrix[ROWS][COLUMNS];
/* Modify each column of the 10th row with the value of 3 */
doSomethingToAllColumns(&matrix, 10, 3);
/* Modify each row of the 10th column with the value of 3 */
doSomethingToAllRows(&matrix, 10, 3);
return 0;
}
It is completely wrong to pass a double ** for this reason:
void test()
{
double **a;
int i1 = sizeof(a[0]);//i1 == 4 == sizeof(double*)
double matrix[ROWS][COLUMNS];
int i2 = sizeof(matrix[0]);//i2 == 240 == COLUMNS * sizeof(double)
}
If you passed in a double ** then accessed it like an array you would cause a crash, segfault or undefined behavior.
Since the "columns" as you call them are stored discontiguously in memory, there's no real way to pull this off directly.
You can, however, create an array of pointers, and store references to the indexes of the other array in that one. You'd need to loop through all of the elements in your array, so it's probably not a better solution than any other. Depending on how often you need to access the array by column it might be worthwhile, though.
You can't really do that, because arrays in C are stored such that the elements of each row are stored together. That means a row of an array is a continuous block of memory, and as far as C is concerned it might as well be an independent array itself. It doesn't work the same way with columns because the elements of a column are not continuous in memory; rather they are spaced at intervals of N bytes, where each row is N bytes long. This means that you could efficiently access the various elements of a column of a 2D array by using pointer arithmetic, but there's no way to actually make a column into an array itself other than by copying the elements over into a new array.
No, there isn't. There cannot be, since in C, an array is a consecutive part of memory, and it is trivial that rows and columns cannot be consecutive at the same time.
That being said, it is fairly easy to jump from one cell of a column to the next, if you know the length of the rows. Take the following example:
void processColumn(double *array, int colIdx, int rowLen, int rowCnt) {
for (int i = colIdx; i < rowCnt * rowLen; i += rowLen) {
// do whatever you want
}
}
#define N 5
#define M 10
double array[N*M];
processColumn(array, 3, N, M);

Resources