I am relatively new to C programming and am stuck with a problem. I am trying to create a 'Transpose function' that will take a matrix_a and transpose and store it as matrix_b. The end goal is to call this function in an equation later on.
For example: Result_Matrix = Matrix_A + Transpose_Matrix_A + Matrix B*MatrixA
Ideally I would just call the Transpose function in the equation, not sure if that is even possible in C but that's my thought process.
This is what I have got so far
#include <stdio.h>
#define N 4
// This function stores transpose of A[][] in B[][]
void transpose(int A[][N], int B[][N])
{
int i, j;
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
B[i][j] = A[j][i];
}
int main()
// Specify matrix
{
int A[N][N] = { {1, 1, 1, 1},
{2, 2, 2, 2},
{3, 3, 3, 3},
{4, 4, 4, 4}};
int B[N][N], i, j;
transpose(A, B);
// printf("Result matrix is \n");
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
printf("%d ", B[i][j]);
printf("\n");
}
return 0;
}
This transposes a matrix but it does not store the new matrix.
Edit 1: I know the transpose function works but I am not sure how to call it in an equation:
New_Matrix = Matrix_A + Transpose_Function(Matrix_A)
^I want to call the function I created in an equation like so.
As kaylum explained, C does not offer the kind of operator use which you are imagining.
Even if your functions would return something (most likely a pointer to the result matrix), adding it with + would not be what you need.
So it is necessary to call functions, e.g. as kaylum proposed:
transpose(A, B); matrix_add(A, B, C); with final result in C
After the call to transpose() the transposed matrix is found in B, which has to be a suitably sized array (be careful with your code and non-square matrixes by the way). Then, without an operator like + being used, that B is used as parameter to a function matrix_add(), which does not exist in your shown code, but structurally is similar to the one you created. Again, C contains the final result and must be a suitably sized array with scope and life-time beyond that second function (like the B you created).
Related
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().
I would like to create a C function that takes a 2D array of doubles as a parameter and operates on that array via indexing, e.g. printf("%f ", array[i][j]).
What I've been able to piece together from various examples and SO questions is something like this:
void printArray(double **array, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%f ", array[i][j]);
}
printf("\n");
}
}
In main, I'm able to successfully print the array like so:
int i, j, k = 0, m = 5, n = 6;
double **a = malloc(m * sizeof(*a));
//Initialize the arrays
for (i = 0; i < m; i++)
{
a[i] = malloc(n * sizeof(*(a[i])));
}
for (i = 0; i < m; i++)
{
for (j = 0; j<n; j++)
{
k++;
a[i][j] = k;
}
}
printArray(a, m, n);
However, when I try to initialize an array to some given values and then call:
double a[5][6] = { { 1, 2, 3, 4, 5 ,6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6} };
printArray(a, 5, 6);
I am met with the following error:
Unhandled exception at 0x011514D3 in Example.exe: 0xC0000005:
Access violation reading location 0xA1F8E3AC.
Can someone explain what my mistake is and how to fix it? edited
Please note that, for the purposes of the function definition, I will know the size of the array at run time but not compile time. Also, I'm compiling on Windows with VisualStudio 2013.
double a[5][6] has type double[][6], which is not the same as double**. double** is a pointer to a pointer to a double. double[][6] is a compiler-managed data type that represents a two-dimensional array.
What's going on here is that the double[][6] you created is being silently cast to a double** in your invocation of printArray.
If your function is going to take a double**, you need to pass it a double**. You can initialize the array contents by filling each member array individually:
double row1[3] = {3, 4, 5};
a[1] = row1;
This works around the problem; because the double[] is stored by the compiler as a contiguous array of double values, casting it to double* implicitly as above is safe.
Another solution is to change the function to take a "real" double[][6], instead of a pointer-pointer. How you would do this with non-fixed-size arrays is up to your particular off-brand of C; it's not part of the C standard so far as I know.
A third solution is to build the array row by row with malloc and fill it cell by cell with a[0][0] = 1 and so forth. You already have this in your question, and it works correctly.
A final thing to be aware of is that you are allocating a on the stack: when your main function exits, accessing it will result in undefined behavior.
#include <iostream>
#include <math.h>
#include <stdio.h>
#define column 3
#define row 3
#define share 3
int matrix_multiplication(int left_matrix[][column], int right_matrix[][column], int result_matrix[][column], int rows, int cols, int shared);
int A[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
},
B[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}, C[3][3]; //initialize "hard coded" three matrices
int main() {
matrix_multiplication(A, B, C, row, column, share); //passes address of each matrix to function
return 0;
}
int matrix_multiplication(int left_matrix[][column], int right_matrix[][column], int result_matrix[][column], int rows, int cols, int shared) {
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {//stays within first column and row through first iteration
for (k = 0; k < 3; k++)//ensures inner dimensions match with variable k i.e. ixk * kxj =ixj or A*B=C
result_matrix[i][j] += right_matrix[i][k] * left_matrix[k][j]; //C programming has ability to perform matrix multiplication
//Adds result of each operation to C matrix i.e. +=
printf("%d\t", result_matrix[i][j]); //matrix C is composed of rows(i) and columns(j)
}//new tab after each column iteration
printf("\n"); //new line for each row iteration
}
return 0;
}
This code is an good example of passing multidimensional arrays to a function using pointers and printing multidimensional arrays after mutliplication. There are multiple ways to indicate pointers to the compiler. I recommend seeing the "Correct way of passing a 2 dimensional array into a function." for example:
/*void display(int (*p)[numcols],int numRows,int numCols)//First method//
void dispaly(int *p,int numRows,int numCols) //Second Method//
void dispaly (int p[][numCols],int numRows,int numCols) //Third Method*/
Remove the column variable, and add this above the matrix_multiplication function declaration:
#define column 3
(You may also want to rename column to COLUMNS.)
In C++ you can also do this:
static const int column = 3;
or, in C++11:
constexpr int column = 3;
The idea behind all this is that all but the very first size of a multidimensional array must be known at compile time.
To fix the expected primary-expression before ']' token" error, change your inner assignment to something like this:
result_matrix[i][j] += right_matrix[i][k] * left_matrix[k][j];
Also you should initialize result_matrix with 0s first.
Also remove the * from int *result_matrix[][column].
Most modern compilers display warnings if you pass an int instead of an int*. Please enable all warnings in your compiler, recompile, fix them, and update your question stating that the example code compiles cleanly, without warnings.
To print an element of the matrix, you have to specify which element you want to print:
printf("%d\t", result_matrix[i][j]);
I can't believe that your compiler didn't display a warning when you omitted the [i][j]. Warnings are for your benefit: they indicate possible bugs in your code.
I am new to C and I am learning from "Programming in C" by Stephen G. Cochan. I have been given next exercise:
12.A matrix M with i rows, j columns can be transposed into a matrix N having j rows
and i columns by simply setting the value of N a,b equal to the value of M b,a for all
relevant values of a and b.
a) Write a function transposeMatrix that takes as an argument a 4 x 5 matrix
and a 5 x 4 matrix. Have the function transpose the 4 x 5 matrix and store
the results in the 5 x 4 matrix. Also write a main routine to test the function.
I have done something wrong with the arguments.
The errors I'm getting are:
warning: return makes integer from pointer without a cast [enabled by default]
passing argument 1 of ‘transposeMatrix’ makes pointer from integer without a cast [enabled by default]
expected ‘int (*)[5]’ but argument is of type ‘int’ (It seems to me like this can be ignored)
etc..all about arguments..
I know code is not perfect but i think it should work if array was returned correctly and arguments were fixed..but I can't find a way to fix it..
// Program to transpose M matrix to N matrix
#include <stdio.h>
int transposeMatrix(int matrixM[][5], int matrixN[][4]) {
int i, j;
i = 0;
j = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 5; j++) {
matrixN[j][i] = matrixM[i][j];
}
}
return matrixN;
}
int main(void) {
int i, j;
int matrixM[4][5] = {{12, 25, 47, 87, 54},
{16, 89, 78, 63, 58},
{45, 21, 47, 62, 82},
{14, 56, 47, 41, 98}};
int matrixN[5][4];
transposeMatrix(matrixM[4][5], matrixN[5][4]);
i = 0;
j = 0;
for (j = 0; j < 5; j++) {
for (i = 0; i < 4; i++) {
printf("%i ", matrixN[j][i]);
}
printf("\n");
}
return 0;
}
There are two ways a function can pass data back to the caller:
Returning a value, and
Changing a data structure a pointer to which is passed to the function as an argument
The first way involves copying, and is inefficient for larger values. The second way is preferred when a large value needs to be returned without copying, or when you need to return multiple results.
Another problem is passing the arrays: your call should pass array names without indexes, like this:
transposeMatrix(matrixM,matrixN);
Your code is using the second strategy. However, it does not need to return anything else. Therefore, the proper return type for your function should be void, not int. Change the return type, and remove the return statement to fix this issue.
Demo on ideone.
Actually the code linked above doesn't really work, it's just printing a transposed matrix by switching rows with columns in the printf() call, it does not truly transpose the matrix as the exercise requires (you can avoid calling transposeMatrix at all and the result is the same). Pay attention to how the exercise is worded, you should use a function and store the results in a new matrix. Also, at this point in the book we're not supposed to use pointers (yet).
This is how I did it:
/*
A matrix M with i rows, j columns can be transposed into a matrix N having j rows and i columns
by simply setting the value of Na,b equal to the value of Mb,a for all relevant values of a and b.
Write a function transposeMatrix() that takes as an argument a 4 × 5 matrix and a 5 × 4
matrix. Have the function transpose the 4 × 5 matrix and store the results in the 5 × 4 matrix. Also
write a main() routine to test the function.
*/
#include <stdio.h>
void transposeMatrix(int matrix45[4][5], int matrix54[5][4])
{
int x, y;
for (x = 0; x < 4; x++)
for (y = 0; y < 5; y++)
matrix54[y][x] = matrix45[x][y];
}
int main(void)
{
int x, y;
int myMatrix[4][5] = { {0, 1, 2, 3, 4},
{5, 6, 7, 8, 9},
{10, 11, 12, 13, 14},
{15, 16, 17, 18, 19} };
int myTransposedMatrix[5][4];
printf("Original Matrix: \n\n");
for (x = 0; x < 4; x++)
{
for (y = 0; y < 5; y++)
{
printf("%3i", myMatrix[x][y]);
}
printf("\n");
}
transposeMatrix(myMatrix, myTransposedMatrix);
printf("\nTransposed Matrix: \n\n");
for (x = 0; x < 5; x++)
{
for (y = 0; y < 4; y++)
{
printf("%3i", myTransposedMatrix[x][y]);
}
printf("\n");
}
return 0;
}
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];