I'm trying to write a program that creates a 2D array using user inputs from main function arguments and then calls a function that fills that 2D array by using pointers.
Next, we call the second function that prints all the elements of that said 2D array.
Lastly, we call the third function that sums up all the elements of the array and prints the total
The problem is that I'm filling another array somewhere else in the memory & not the one in the main. So basically, I did what's called a call by value and I'm trying to do a call by reference, but failing really hard at it.
here's what I've done so far (some code may seem enigmatic since it was used for debugging)
#include <stdio.h>
void entmat(int a ,int b, double (*M)[b])
{
int i ,j;
printf("entmat: %p\n",M);
//double** pM=M;
for (i=0 ;i<a ;i )
{
for (j=0 ;j<b;j )
{
printf("enter a value for column %d of the raw %d ",j 1,i 1);
scanf ("%f",*(*(M i) j));//*(*(M i) j)
printf("The value of the column %d of the raw %d is %f \n",j 1,i 1,*(*(M i) j));
//pM ;
}
}
}
void readmat(int a ,int b, double (*M)[b])
{
int i ,j;
printf("readmat: %p\n",M);
for (i=0 ;i<a ;i )
{
for (j=0 ;j<b;j )
{
printf("The value of the column %d of the raw %d is %f \n",j 1,i 1,*(*(M i) j));
}
}
}
void sumavr(int a ,int b, double (*M)[b])
{
int i ,j;
printf("sumavr: %p\n",M);
double avg ,s=0;
for (i=0 ;i<a ;i )
{
for (j=0 ;j<b;j )
{
s=s M[i][j];
}
avg = s/j;
printf("the somme of the raw %d is %f and the average is %f \n",i,s,avg);
}
}
int main (int argc, char *argv[])
{
int a,b,i,j;
printf("enter the number of lignes ");
scanf("%d",&a);
printf("enter the number of columne ");
scanf("%d",&b);
double M[a][b];
printf("main: %p\n",M);
entmat(a,b,M);
for (i=0 ;i<a ;i )
{
for (j=0 ;j<b;j )
{
printf("The value of the column %d of the raw %d is %f \n",j 1,i 1,*(*(M i) j));
}
}
readmat(a,b,M);
sumavr(a,b,M);
return 0;
}
CodePudding user response:
Using 'a', 'b', 'i' and 'j' when referring to 'rows' and 'cols' makes it difficult to read and understand code. Appropriate names for variables and functions is just the beginning.
Defining an array of elements reserves a contiguous block of memory ('stack' in the case of local variables). Functions cannot determine the dimensions of an array, so, as you've done, functions must receive the dimensions as parameters. In the case of a block of memory being accessed as a 2D array, the numbers of both 'rows' and 'cols' must be passed to any function. With this information, the final piece is to pass the address of the first (0th) element of the array. This is done in the code below.
#include <stdio.h>
void entmat( int rows, int cols, double *pM ) {
printf( "entmat: %p\n", pM );
for( int r = 0; r < rows; r )
for( int c = 0; c < cols; c ) {
printf( "value at [%d,%d]? ", r 1, c 1 );
scanf ( "%lf", pM r*cols c ); // notice how an element's offset is calculated
}
}
void printmat( int rows ,int cols, double *pM ) {
printf( "printmat: %p\n", pM );
for( int r = 0; r < rows; r ) {
for( int c = 0; c < cols; c )
// now we want the 'value', not the 'address'
printf( "value at [%d,%d] = %.2lf ", r 1, c 1, *(pM r*cols c) );
puts( "" );
}
}
void sum_avg_mat( int rows ,int cols, double *pM ) {
printf( "sumavr: %p\n", pM );
for( int r = 0; r < rows; r ) {
double sum = 0.0; // initialise for this row
for( int c = 0; c < cols; c )
sum = sum *(pM r*cols c); // 'value(s)' again
double avg = sum / cols; // calc to print
printf("Row %d: sum(%.2lf), average (%.2lf)\n", r, sum, avg );
}
}
int main() {
int rows, cols;
printf( "enter the number of lignes " );
scanf( "%d",&rows );
printf( "enter the number of columne " );
scanf( "%d",&cols );
// double M[rows][cols];
double M[5][5]; // old compiler doesn't have VLA capability
printf( "main: %p\n", &M[0][0] ); // Notice '&' ("take the address of")
entmat( rows, cols, &M[0][0] );
printmat( rows, cols, &M[0][0] );
sum_avg_mat( rows, cols, &M[0][0] );
return 0;
}
enter the number of lignes 3
enter the number of columne 3
main: 0019FE6C
entmat: 0019FE6C
value at [1,1]? 1
value at [1,2]? 2
value at [1,3]? 3
value at [2,1]? 4
value at [2,2]? 5
value at [2,3]? 6
value at [3,1]? 7.5
value at [3,2]? 7.7
value at [3,3]? 7.2
printmat: 0019FE6C
value at [1,1] = 1.00 value at [1,2] = 2.00 value at [1,3] = 3.00
value at [2,1] = 4.00 value at [2,2] = 5.00 value at [2,3] = 6.00
value at [3,1] = 7.50 value at [3,2] = 7.70 value at [3,3] = 7.20
sumavr: 0019FE6C
Row 0: sum(6.00), average (2.00)
Row 1: sum(15.00), average (5.00)
Row 2: sum(22.40), average (7.47)
CodePudding user response:
This call of printf
printf("main: %p\n",M);
must be written like
printf("main: %p\n", ( void * )M);
This call of scanf
scanf ("%f",*(*(M i) j));//*(*(M i) j)
is incorrect. Must be
scanf ("%f",*(M i) j;
The initializations of the variable s must be placed in the outer for loop
for (i=0 ;i<a ;i )
{
double avg ,s=0;
for (j=0 ;j<b;j )
{
s=s M[i][j];
}
avg = s/j;
printf("the somme of the raw %d is %f and the average is %f \n",i,s,avg);
}