I want to construct a function that takes a matrix as input and then calculates the means of all rows (or columns). I tried to do it like this, but it gives me a bunch of errors.
#include <stdio.h>
#include <stdlib.h>
int sum_rows[1000], sum_columns[1000], mean_row[1000], mean_column[1000], N, A[100][100], i, j;
void values(int A[N][N]) {
for (i=0; i<N; ++i) {
for (j=0; j<N; ++j) {
A[i][j] = (rand()%61+20);
}
}
}
void mean_r (int A[N][N]) {
for (i=0; i<N; ++i) {
sum_row[i] = 0;
for (j=0; j<N; ++j) {
sum_row[i] += A[i][j];
}
mean_row[i] = sum_row[i]/N;
}
}
void mean_c (int A[N][N]) {
for (j=0; j<N; ++j) {
sum_column[j] = 0;
for (i=0; i<N; ++i) {
sum_column[j] += A[i][j];
}
mean_column[j] = sum_column[j]/N;
}
}
int main()
{
int N;
printf("Enter size of matrix: ");
scanf("%d", &N);
int A[N][N];
values(A[N][N]);
mean_r(A[N][N]);
mean_c(A[N][N]);
for (i=0; i<N; ++i) {
for (j=0; j<N; ++j) {
printf("A[%d][%d] = %d\n", i, j, A[i][j]);
}
}
for (i=0; i<N; ++i) {
printf("Mean row #%d = %.2f\n", i, mean_row[i]);
}
for (j=0; j<N; ++j) {
printf("Promedio Columna #%d = %.2f\n", j, mean_column[j]);
}
return 0;
}
Can you explain to me how to pass a matrix into a function? I have to do these operations with a function defined beforehand, and just call it inside the main function.
It seems that your matrix is dynamic(the number of of rows and columns are not fixed). In C language, you are not allowed to declare the array of array with the dynamic rows and columns because the compiler does not know how to allocate the how much memory for you. You will have to allocate the memory at run-time. In my example, the matrix is stored in the memory as first row, the second row and so on. In math, the access to the element of the matrix is by row index and column index. "row index and column index" is translated to the memory address of the element using the starting address of the memory allocated + row number * column number + the column index based on how the matrix is stored in my example. Note: both row number and column number start with zero. The first element is denoted by p where p+0*columncount+0) is p. The next element is denoted by p+0*columncount+1. Following this, the element of the second row and second column(2,2) is denoted by p+1*column count+1. The following example uses single pointer to represent the dynamic matrix(Other technique does exist, eg. the pointer array)
In my example, 3(three rows) by 4(four columns) matrix is created and initialized. The ProcessMatrix function display the sum of each row.
If possible, I recommend you use C++ that allows you to allocate the memory with the size specified by the value of one integer, which makes things more easier. If you have access to other math libraries(many available), you should use them instead of trying to reinvent wheel.
// c_matrix.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <stdio.h>
int GetElementValue(int* m, int rowIndex, int colIndex, int columnCount)
{
return *(m + (rowIndex * columnCount + colIndex));
}
void ProcessMatric(int* myMatrix, int rowcount, int colcount)
{
// calculate the sum of each row
int sum = 0;
for (int i = 0; i < rowcount; i++)
{
sum = 0;
for (int j = 0; j < colcount; j++)
{
sum = sum + GetElementValue(myMatrix, i, j, colcount);
}
printf("Sum of row %d=%d\r\n", i+1, sum);
}
}
int main()
{
int row = 3;
int col = 4;
int* matrix;
//create the memory for the matrix 3 by 4.
matrix = malloc(sizeof(int) * row * col);
// in momery the matrix is stored as (row1,col1), (row1, col2), (row1,col3)...(row4,col1),(row4,col2),(row4, col3)
// initialize the matrix as 0,1,2,3...11
for (int i = 0; i < row * col; ++i)
{
*(matrix + i) = i;
}
ProcessMatric(matrix, row, col);
free(matrix);
return 0;
}
In your main function you declare an NxN matrix A
int A[N][N];
As Yan pointed out, you are unable to declare the array in such a way because the compiler doesn't know the value of N. The value of N won't be determined until after the program has been compiled and is executing (i.e. during runtime). Beyond that, though, it seems like what you want to do is pass the 2d array. What you need to pass is A itself (e.g. values(A);, however you pass
values(A[N][N]);
mean_r(A[N][N]);
mean_c(A[N][N]);
What you've done is index both dimensions, so, normally what would happen is you would just be passing an int (whatever is in the Nth row and Nth column). However, indices are in the range [0, N-1] so A[N] is out-of-range. They key concept is that arrays (and other data structures) are passed by reference. When you declare A, contiguous space will be allocated to hold N * N * sizeof(int) and the virtual address for the starting location of that space is stored in A. As a result, your functions know what memory addresses to store stuff in so that you can access it with A[i][j] without having to pass a giant slab of memory.
Related
I'm new to C programming and have to write a small program where I should do stuff with a matrix (Input and solve a list of equations stored in a 2D Matrix). Individually the different functions of the program (input the matrix, calculate the solution, output the matrix) are no problem. In this (shortened) version of the code, the void* getMatrix creates a matrix and assigns some values to each position in the matrix. I can access these in the main function with no problem.
But how can I pass this matrix (or better: a pointer to the matrix) to another function and access and edit it there?
I am not allowed to pass the values of the matrix, but instead have to use a pointer to the storage location of it.
Code:
#include <stdio.h>
#include <stdlib.h>
void* getMatrix(int *nPoint);
void doStuffWithMatrix(/*Pass matrix*/);
int main() {
int n = 8;
int *nPoint = &n;
float (*matrix)[*nPoint] = getPointer(nPoint);
//Print out the matrix
printf("\n");
for (int i = 0; i < *nPoint; i++) {
printf("| ");
for (int j = 0; j < *nPoint+1; j++) {
printf("%-5g | ", matrix[i][j]);
}
printf("\n");
}
doStuffWithMatrix(matrix);
free(*matrix);
}
void* getMatrix(int *nPoint) {
//Create 2D Matrix
float (*matrix)[*nPoint] = malloc(sizeof(float[*nPoint][*nPoint + 1]));
//Temporary value assign
for (int i = 0; i < *nPoint; i++) {
for (int j = 0; j < *nPoint+1; j++) {
matrix[i][j] = 10 * (i + 1) + (j + 1);
}
}
return matrix;
}
void printMatrix(/*Pass matrix*/) {
//Do Stuff
}
The function doStuffWithMatrix is just a placeholder and obviously doesn't work.
Note: I coded in Java before and thats why I put the { in the same line.
Return the address of first element of matrix in int* getMatrix and same can be passed into function by using Yourfunction(getMatrix(nPoint));
I have to use a static two-dimensional array and a dynamic matrix as a part of my college task.
So, I've created them, and now trying to fill and then print them to a console, but getting "segmentation fault". That's how I'm trying to achieve it:
#include "arrayutils.h"
#include <stdlib.h>
#include <stdio.h>
#define ROWS 5
#define COLUMNS 7
int main3() {
/*init static array*/
double twodimarray[ROWS][COLUMNS];
/*init dynamic array*/
double **matrix = (double**) malloc(sizeof(double*) * ROWS);
for(int i = 0; i < ROWS; i++) *(matrix + i) = (double*)malloc(sizeof(double) * COLUMNS);
for(int i = 0; i < ROWS; i++){
dfillarran(*(matrix + i), COLUMNS);
dfillarran(twodimarray[i], COLUMNS);
}
puts("Dynamic matrix :");
printmx(matrix, ROWS,COLUMNS);
puts("Static array:");
printmx(twodimarray, ROWS, COLUMNS);
/*freeing mem*/
for(int i = 0; i < ROWS; i++) free(*(matrix + i));
free(matrix);
}
Error is definitely in function printmx(), but I can't understand why; It works for dynamic matrix, and fails only for static one, but static array name - is a pointer to array of pointers, where each one is pointing array of values, just like dynamic one!
There is code of my printmx() function from arrayutils.h:
/**Print Matrix*/
void printmx(double** mx, int rows, int col){
for(int i = 0; i < rows; i++) {
for(int j = 0; j < col; j++){
printf("%.lf ", *(*(mx + i)+j));
}
putchar('\n');
}
putchar('\n');
}
Funcion that fills arrays with random values can be found here, in arrayutils.c, that I've created for all other tasks that use same functions like filling and printing arrays, but I don't think, that problem is there..
Probably, I'm wrong somewhere in theory, and still not getting the difference between static and dynamic matrix, please correct me :)
p.s.There is a screenshot of the error:
The function printmx may not be called for the two objects of different types.
The array twodimarray is a two dimensional array that when is passed to the function has the type double ( * )[COLUMNS].
While matrix is a pointer of the type double **.
So my assignment is to add matrices (they don't have to be square but the two matrices will always be the same size) by dynamically allocating the space for a 2-D array, and I used a double pointer. My function to get the user-inputted matrices is as follows:
void matrixEntry(const int rowNum, const int colNum, const char
matrixNum, int** matrix) {
int i, j, k;
matrix = (int**) malloc(rowNum * sizeof(int*));
for (k = 0; k < rowNum; ++k) {
matrix[i] = (int*)malloc(colNum * sizeof(int));
}
printf("Enter Matrix %c\n", matrixNum);
for (i = 0; i < rowNum; ++i) {
for (j = 0; j < colNum; ++j) {
scanf("%d", &matrix[i][j]);
}
}
}
where I call it in main twice as such:
matrixEntry(rowNum, colNum, matA, matrixOne);
matrixEntry(rowNum, colNum, matB, matrixTwo);
However, when I run the program I'm only allowed to enter the first row of Matrix A before the program stops running. I think this is because I didn't allocate enough space for the 2nd row, but I'm not sure where my mistake is. My thought process when allocating the space was that
matrix = (int**) malloc(rowNum * sizeof(int*));
allocated the space for the rowNum number of rows, and then the for loop allocated the space for the number of columns. Is this correct?
I have a 2D array in which many elements are zero. For example:
int array[10][10];
memset(array, 0, 100 * sizeof(int));
array[0][0] = 3;
array[2][8] = 5;
array[4][0] = 4;
How could I print the non-zero (only positive) elements in descending (or ascending) order. I was thinking about something like this:
int xpos, ypos;
while (getMaximumInArray(array, &xpos, &ypos))
{
printf("x=%i y=%i val=%i\n", xpos, ypos, array[xpos][ypos]);
array[xpos][ypos] = 0; // set to 0 to make sure we find the next biggest value.
}
However this makes me loop through the array many times (as much as there are non-zero elements). Would there be a better (ie less operations) way to do this?
EDIT : I forgot to specify that I would like to use the positions in my output; so I need not only the sorted values; but also their indices...
A simple way to make this more efficient is to simply sort the values. Sorting - or copying while sorting - has runtime complexity of O(n log n) which is an improvement over your O(n*n). An easy and efficient way to do that is to copy the non-zero values to a std::multiset and then iterate through it.
Update regarding your edit:
No problem. Simply store an object that contains the value and the indices in the set and supply a comparison functor that uses only the value.
You could create new array and then sort it.
For example:
int array[10][10];
array[0][0] = 3;
array[2][8] = 5;
array[4][0] = 4;
int positive[100];
int k = 0;
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
if(array[i][j] > 0){
positive[k++] = array[i][j];
}
}
}
sort(positive, positive + k);
for(int i = 0; i < k; i++){
printf("%d", positive[i]);
}
There are multiple approaches to this. Denis Gavrus proposed using an array, which is fine, but you can use a vector if you want to be more memory efficient:
Also, if you need to keep your values and their position, you'll need to store them in a struct/class (the ELEMENT struct), which will need a separate comparison class/function.
Here is the container and the comparison function:
struct ELEMENT{ ///Containing the value and the coordinates
int val, i, j;
};
bool cmp(ELEMENT a, ELEMENT b){
return a.val<b.val;
}
And here is the code that processes your data:
const int L=10; ///In case you want to modify the matrix dimensions
int array[L][L]; ///A really bad name for anything
vector<ELEMENT> v; ///The vector containing the sorted values
for(int i=0; i<L; i++) ///Initialize the matrix with 0
for(int j=0; j<L; j++)
array[i][j]=0;
array[0][0] = 3; ///Your values...
array[2][8] = 5;
array[4][0] = 4;
for(int i=0; i<L; i++)
for(int j=0; j<L; j++)
if(array[i][j]!=0)
v.push_back({array[i][j], i, j}); ///Insert into v the non-zero values and the coordinates
sort(v.begin(), v.end(), cmp);
for(ELEMENT i:v)///Your output
printf("%d at position (%d, %d)\n",i.val, i.i, i.j);
Also, you could use a priority queue:
The comparison class for the priority queue:
class cmp{ ///Containing the functor for the priority queue
public:
bool operator()(ELEMENT a, ELEMENT b){
return a.val<b.val;
}
};
The code that does stuff:
const int L=10; ///In case you want to modify the matrix dimensions
int array[L][L]; ///A really bad name for anything
priority_queue<ELEMENT, vector<ELEMENT>, cmp> v; ///The priority queue containing the sorted values
for(int i=0; i<L; i++) ///Initialize the matrix with 0
for(int j=0; j<L; j++)
array[i][j]=0;
array[0][0] = 3; ///Your values...
array[2][8] = 5;
array[4][0] = 4;
for(int i=0; i<L; i++)
for(int j=0; j<L; j++)
if(array[i][j]!=0)
v.push({array[i][j], i, j}); ///Insert into v the non-zero values
for(; !v.empty(); v.pop())
printf("%d at position (%d, %d)\n",v.top().val, v.top().i, v.top().j);
I have a 2 dimensional array dynamically allocated in my C code, in my function main. I need to pass this 2D array to a function. Since the columns and rows of the array are run time variables, I know that one way to pass it is :
-Pass the rows and column variables and the pointer to that [0][0] element of the array
myfunc(&arr[0][0],rows,cols)
then in the called function, access it as a 'flattened out' 1D array like:
ptr[i*cols+j]
But I don't want to do it that way, because that would mean a lot of change in code, since earlier, the 2D array passed to this function was statically allocated with its dimensions known at compile time.
So, how can I pass a 2D array to a function and still be able to use it as a 2D array with 2 indexes like the following?
arr[i][j].
Any help will be appreciated.
See the code below. After passing the 2d array base location as a double pointer to myfunc(), you can then access any particular element in the array by index, with s[i][j].
#include <stdio.h>
#include <stdlib.h>
void myfunc(int ** s, int row, int col)
{
for(int i=0; i<row; i++) {
for(int j=0; j<col; j++)
printf("%d ", s[i][j]);
printf("\n");
}
}
int main(void)
{
int row=10, col=10;
int ** c = (int**)malloc(sizeof(int*)*row);
for(int i=0; i<row; i++)
*(c+i) = (int*)malloc(sizeof(int)*col);
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
c[i][j]=i*j;
myfunc(c,row,col);
for (i=0; i<row; i++) {
free(c[i]);
}
free(c);
return 0;
}
If your compiler supports C99 variable-length-arrays (eg. GCC) then you can declare a function like so:
int foo(int cols, int rows, int a[][cols])
{
/* ... */
}
You would also use a pointer to a VLA type in the calling code:
int (*a)[cols] = calloc(rows, sizeof *a);
/* ... */
foo(cols, rows, a);
You really can't do this without changing a lot of code. I suggest to wrap this in a structure which contains the limits and then use regexp search'n'replace to fix the accesses.
Maybe use a macro like AA(arr,i,j) (as in Array Access) where arr is the structure.
As far as I know, all you can pass to a function is a pointer to the first element of an array. When you pass an actual array to a function, it is said that "the array decays into a pointer" so no information about the size(s) of the pointed array remains.
A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.
I believe you will be able to find more information about this on the C FAQ.
Numerical recipes in C (a book dealing mostly in matrices) suggests a way to do this cleanly and still deal with 2D matrices. Check out the section 1.2 "Matrices and 2D arrays" and the method convert_matrix().
Essentially what you need is to allocate a set of pointers to point to your row vectors. And pass this to your function along with the number of rows and columns.
A 2-d array in C is just an array of arrays. Here ya go:
void with_matrix(int **matrix, int rows, int cols) {
int some_value = matrix[2][4];
}
int main(int argc, char **argv) {
int **matrix;
... create matrix ...
with_matrix(matrix, rows, cols);
}
int cols = 4;
int rows = 3;
char** charArray = new char*[rows];
for (int i = 0; i < rows; ++i) {
charArray[i] = new char[cols];
}
// Fill the array
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
charArray[i][j] = 'a';
}
}
// Output the array
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
cout << charArray[i][j];
}
cout << endl;
}