Arguments and returning array in C - c

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;
}

Related

What is the C syntax/operator for adding matrixes?

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).

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().

Passing a pointer to an array in a function in C

I need to write a program that implements 3 ways of passing an array to a function.
2 functions work as intented, but I am having issues with the function that passes a pointer.
I tried googling it, and testing other way, but I don't seem to understand how those pointers should work out.
First function should output 1, 2, 3.
Second function should output 11, 12, 13
Third function should output 101, 102, 103
First and third function work, but the issues is with the second one.
Here's what I wrote:
int main(void)
{
int iArray[3] = {100,234,567};
f1(iArray);
f2(iArray);
f3(iArray);
return EXIT_SUCCESS;
}
void f1(int ia[3]) // sized array
{
ia[0] = 1;
ia[1] = 2;
ia[2] = 3;
for (int i = 0; i < 3; i++)
{
printf("%d\n", ia[i]);
}
printf("\n");
}
void f2(int* pi) // pointer
{
*pi = 11, 12, 13;
printf("%d", *pi);
printf("\n\n");
}
void f3(int ia[]) // unsized array
{
ia[0] = 101;
ia[1] = 102;
ia[2] = 103;
for (int i = 0; i < 3; i++)
{
printf("%d\n", ia[i]);
}
}
In C you can't pass an array, only pointers to their elements. That means for all arguments like int ia[] the compiler really treats it as int *ia. Any potential "array" size is irrelevant, all your functions are taking the exact came int * type argument.
This is because arrays naturally decay to pointers to their first elements.
In fact, the function calls
f1(iArray);
f2(iArray);
f3(iArray);
are actually equal to
f1(&iArray[0]);
f2(&iArray[0]);
f3(&iArray[0]);
Now for the problem with the second function, it's this line:
*pi = 11, 12, 13
That is equivalent to:
pi[0] = 11, 12, 13;
which is using the comma operator which makes it equivalent to:
pi[0] = 13;
To assign each element of the array you need to index each element just like you do with the "array" functions:
pi[0] = 11;
pi[1] = 12;
pi[2] = 13;
Of course you need to print the values the same way as well, with a loop.
The syntax for referencing pointers is the same as for an array:
pi[0] = 1;
pi[1] = 2;
pi[2] = 3;
You'll also want to change the printf loop accordingly.

I need a straightforward example of passing an 2D array to a function in C

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.

How to pass unbound multidimensional array?

Is there any way to pass a multidimensional array to a function without knowing the no of columns.... I mean say I want to print a multidimensional array say a[][9] and b[][3]. If I make a common function say print.
// I have to specify the no of columns right and since
// the no of columns should be same for both actual and
// formal arguments
void print(int a[][])
I have to make different functions for different multidimensional arrays. There should be some way around it.
How to pass unbound multidimensional array?
You have to include all of the array dimensions, except the innermost one (although you probably do want to give the innermost one anyway, so that your function knows when to stop printing). If the dimension is not known at compile time then you can make it a parameter to the function:
void print(size_t m, size_t n, int a[m][n])
{
for ( size_t i = 0; i < m; ++i )
for ( size_t j = 0; j < n; ++j )
printf("%d\n", a[i][j]);
}
Calling the function:
int main(void)
{
int a[][4] = { { 0, 1, 2, 3 }, {8, 7, 6, 5}, {11, 10, 12, 9} };
print(3, 4, a);
return 0;
}
Matt McNabb's answer shows how to use the C99 or C11 variable-length array facilities. There is an alternative that will work with C89 too (which might be a factor if you code on Windows with MSVC), but you still have to tell the function about both dimensions of the array, and you have to do the subscript calculations yourself:
void print(size_t m, size_t n, int *a)
{
size_t i;
size_t j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf(" %d", a[i * n + j]);
putchar('\n');
}
}
You might call this as:
int main(void)
{
int a[][4] = { { 0, 1, 2, 3 }, {8, 7, 6, 5}, {11, 10, 12, 9} };
print(3, 4, &a[0][0]);
return 0;
}
Sample output:
0 1 2 3
8 7 6 5
11 10 12 9
(One minor comment: I'm not certain that the automatic array could be initialized like that in C89 — there were some restrictions still on automatic variable initialization. If it doesn't work, simply move the entire array declaration outside of main() and prefix it with static so it becomes a file scope array.)

Resources