0

/*Write a program to calculate sum of diagonal elements of square matrix using function. The function should return total sum to calling function. Program tested on debain testing with gcc version 9.3.0 */

The program works fine when used without function but there is problem i.e the passed array does not have all the elements of the original array and so the sum is incorrect.

#include <stdio.h>
#include <stdlib.h>

int sum(int a[10][10],int d);

int main(){

    int r,c;
    puts("Enter the dimension of square matrix");
    scanf("%d %d",&r,&c);
    if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix
    int a[r][c];
    puts("Enter the elements of the matrix");
    for(int i=0; i<r; ++i){
        for(int j=0; j<c; ++j){
            printf("Enter a[%d][%d] element = ",i+1,j+1);
            scanf("%d",&a[i][j]);
        }
    }

    int result = sum(a,r);

    printf("Sum of diagonal elements = %d \n",result);
    return 0;
}

int sum(int a[10][10],int d){
//for a square matrix no of diagonal element = row/col of matrix
    int result=0;
    for(int i=0; i<d; ++i){
        result=result+a[i][i];
    }

    return result;
}
3
  • 4
    you need to input 10 for r and 10 for c for this to have any chance of working. Commented May 11, 2020 at 13:14
  • Will it be bad practice to make r and c global i.e. adding int r,c; above function prototype of sum? (if not then it will fix the problem) Commented May 11, 2020 at 13:52
  • Yes, it is bad practice... and it would not solve your problem anyway. Commented May 11, 2020 at 13:55

6 Answers 6

2

Your code has two problems:

  1. sum function receive 10x10 array. Your code can receive matrix in any size. What happens if you ask for 2x2 matrix, then sum treat it as 10x10 array and try to access to [2][2]? that is undefined behavior. You should not declare size of array in sum arguments.

  2. You can not receive array size as input and then declare an array that way. You should allocate dynamic memory. I encourage you to read more about dynamic memory allocation

Look at the following changes:

#include <stdio.h>
#include <stdlib.h>

int sum(int a[][],int d);

int main(){

    int r,c;
    puts("Enter the dimension of square matrix");
    scanf("%d %d",&r,&c);
    if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix

    //allocate memory
    int* a = (int*)malloc(sizeof(*a)*r);
    for(int i=0;i<r;i++){
        a[i] = (int*)malloc(sizeof(int)*c)
    }
    puts("Enter the elements of the matrix");
    for(int i=0; i<r; ++i){
        for(int j=0; j<c; ++j){
            printf("Enter a[%d][%d] element = ",i+1,j+1);
            scanf("%d",&a[i][j]);
        }
    }

    int result = sum(a,r);

    printf("Sum of diagonal elements = %d \n",result);

    //Free memory
    for(int i=0;i<r;i++)
        free(a[i])
    free(a)
    return 0;
}

int sum(int a[][d],int d){
//for a square matrix no of diagonal element = row/col of matrix
    int result=0;
    for(int i=0; i<d; ++i){
        result=result+a[i][i];
    }

    return result;
}
Sign up to request clarification or add additional context in comments.

3 Comments

function does not receive junk, nothing is added to make a 10x10 array, but reading out of the array the behavior is undefined. I encourage you to add a proposal correcting the OP code
int sum(int a[][], int d) will not compile.
@KamilCuk I'm too used to pass it as pointer :( I'll change it
1

When you create a true 2D array, all dimensions but the first one are used in actual index computation. You have two options here:

  1. Use a static maximum size for the matrix (say 10):

    int sum(int a[][10],int d);
    
    int main(){
    
        int r,c;
        puts("Enter the dimension of square matrix");
        scanf("%d %d",&r,&c);
        scanf("%d %d",&r,&c);
        if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix
        if (r > 10) {puts("Size must be at most 10"); exit(0);} // check size
        int a[r][10];             // Force a well know row size
        ...
    int sum(int a[][10],int d){
    //for a square matrix no of diagonal element = row/col of matrix
        ...
    
  2. Pass the dynamic dimension in the function call before the array:

    int sum(int d, int a[][d]);
    
    int main(){
    
        int r,c;
        puts("Enter the dimension of square matrix");
        scanf("%d %d",&r,&c);
        if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix
        int a[r][c];
        ...
        int result = sum(r, a);
        ...
    int sum(int d, int a[][d]){
    //for a square matrix no of diagonal element = row/col of matrix
    

Comments

1

As noted, you have a problem with feeding data into a wrongly sized static array for any values of r and c other than 10 and 10.
There are several ways this can be refactored to address this problem, one being dynamic memory memory allocation:

Change This:

int sum(int a[10][10],int d);

int main(){

    int r,c;
    puts("Enter the dimension of square matrix");
    scanf("%d %d",&r,&c);
    if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix
    int a[r][c];  

To this:

int sum(int **a,int d);

int main(){

    int r,c;
    puts("Enter the dimension of square matrix");
    scanf("%d %d",&r,&c);
    if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix
    int **a = calloc(c, sizeof(int *));
    if(a)
    {
        for(int i = 0;i<c;i++)
        {
            a[i] = calloc(r, sizeof(int));
        }
    }

Then change the function prototype below:

int sum(int a[10][10],int d){

To:

int sum(int **a,int d){

Each element created using calloc must be freed once it is no longer needed.

eg :

        for(int i = 0;i<c;i++)
        {
            free(a[i]);
        }
        free(a);

Comments

0

What are you entering for r and c? If it's not 10 and 10, then no, this code doesn't have a hope of working.

Also, if the array is required to be a square matrix, why ask for number of rows and columns? Just ask for one value and apply it to both dimensions:

int r;
...
scanf( "%d", &r );
...
int a[r][r];

Since you are creating a as a VLA in main, you need to declare it as a VLA in sum as well:

int sum( int r, int a[r][r] ) // r must be declared first.
{
  ...
}

and then change your call appropriately:

int result = sum( r, a );

Comments

0
#include <stdio.h>
#include <stdlib.h>

int sum(int *a,int r);

int main(){

    int r,c;
    puts("Enter the dimension of square matrix");
    scanf("%d %d",&r,&c);
    if (r != c) {puts("Not a square matrix");exit(0);}//check if square matrix
    int a[r][c];
    puts("Enter the elements of the matrix");
    for(int i=0; i<r; ++i){
        for(int j=0; j<c; ++j){
            printf("Enter a[%d][%d] element = ",i+1,j+1);
            scanf("%d",&a[i][j]);
        }
    }

    int result = sum((int *)a,r);

    printf("Sum of diagonal elements = %d \n",result);
    return 0;
}

int sum(int *a,int r){
//for a square matrix no of diagonal element = row/col of matrix
    int result=0;
    for(int i=0; i<r; i++){
        result=result+(*(a+ i*r) + i);
    }
return result;
}

1 Comment

Does not work in every case. For instance let dimension be 2*2 and the elements be 4 3 2 1 the result should be 5 but it gives 7 where as if values are entered as 1 2 3 4 then it gives 5.
0

The basic idea is to flatten the 2D array. For instance, one 2D array of 3 rows and 5 columns has its elements in the same order as a 1D array of 15 elements.

int a2[3][5] = {{0, 1, 2, 3, 4}, {1, 2, 3, 4, 5}, {4, 5, 6, 7, 8}};

has the exact same sequence as

int a1[15] = {0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8};

though a1 and a2 have incompatible types.

So... how do you flatten an array?

You can simply use the address of a[0][0] (of type int*) and assume all elements follow sequentially. Also pass dimension info so you can calculate indexes inside the function.

#include <stdio.h>

void foo(int *flattened, int rows, int cols) {
    printf("original[2][3] is %d\n", flattened[2*cols + 3]);
}

int main(void) {
    int one[14][14]; one[2][3] = 42;
    foo(&one[0][0], 14, 14);

    int two[4][100]; two[2][3] = 42;
    foo(&two[0][0], 4, 100);

    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.