0

I have the following 2D array:

int censusData[4][3] = {{87290, 77787, 55632},
                    {83020, 78373, 62314},
                    {95588, 87934, 705421},
                    {112456, 97657, 809767}};

I want to print values column-wise in that, after 3 passes of a loop, it would print:

87290 83020 95588 112456

77787 78373 87934 97657

55632 62314 705421 809767

Notice how it's the first element from each sub-array, then the 2nd, then the third..etc

I can easily access each subarray when going row-wise using this:

int* averageCityIncome(int size, int size_2, int arr[][size_2]){
    int* t_arr = malloc(4 * sizeof(int));
    for (int i = 0; i < size; i++){
        int avg = 0;
        for (int j = 0; j < size_2; j++){
            avg += arr[i][j];
        }
        avg /= size_2;
        t_arr[i] = avg;
    }

    return t_arr;
}

But now I'm trying to read column-wise as stated above and I so far have this:

int* averageIncome(int size, int size_2, int arr[][size_2]){
    int* t_arr = malloc(4 * sizeof(int));
    for (int i = 0; i < size_2; i++){
        for (int j = 0; j < size; j++){
            printf("%d\n", arr[i][j]);
        }
        printf("-----\n");
    }

    return t_arr;
}

But it doesn't seem to be working. I'm still pretty new to C, and it's difficult to wrap my mind around 2D arrays still. Any help would be greatly appreciated.

Lauren 835
  • 291
  • 2
  • 12

3 Answers3

1
#include <stdio.h>

int censusData[4][3] = {{87290, 77787, 55632},
                    {83020, 78373, 62314},
                    {95588, 87934, 705421},
                    {112456, 97657, 809767}};

int main() {

    int* t_arr = malloc(3 * sizeof(int));
    for(int i=0;i<3;i++){
        int avg = 0;
        for(int j=0;j<4;j++){
            //Keep the I fixed here now J is varying and its position of column
            //So you are reading all column values for ith row.
            avg+=censusData[j][i];
        }
        avg/=4;
        t_arr[i] = avg;
    }


    for(int i=0;i<3;i++){
        printf("%d,",t_arr[i]);
    }
    return 0;
}
Lakshman
  • 469
  • 5
  • 12
  • Could you please add what you stated in the comment as an explanation? This would make this answer self-standing. Also, note https://stackoverflow.com/q/31816095/4944425 – Bob__ Jun 15 '20 at 06:21
  • Code is missing to include `stdlib.h` for `malloc()`. – RobertS supports Monica Cellio Jun 15 '20 at 07:24
  • @RobertSsupportsMonicaCellio Please see ideone https://ideone.com/vrd27H its working, I am using C (gcc 8.3) – Lakshman Jun 15 '20 at 07:31
  • @Lakshman I don't know why it works in this case, but it shouldn't do so with GCC 8.3: https://stackoverflow.com/questions/1230386/why-do-i-get-a-warning-every-time-i-use-malloc/ Implicit functions are gone since C99 https://stackoverflow.com/a/9182835/12139179 – RobertS supports Monica Cellio Jun 15 '20 at 07:46
1

You simply need to swap i and j for the dimensions when addressing a certain element of the array in the caller.

int* averageIncome(int size, int size_2, int arr[][size_2]) {

    int* t_arr = calloc(4, sizeof(int));  // calloc to initialize the array elements to 0.

    if ( t_arr == NULL )
    {
        fputs("Error at memory allocation for t_arr!", stderr);
        exit(1);
    }

    int avg = 0;                          // definition of avg placed outside of the loop.

    for (int i = 0; i < size_2; i++) {

        for (int j = 0; j < size; j++) {

            printf("%d\n", arr[j][i]);       // j swapped with i.
            avg += arr[j][i];                // same here too.
        }
        printf("-----\n");

        t_arr[i] = avg / size;
        avg = 0;
    }

    return t_arr;
}

Example (Online):

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

#define ROWS 4
#define COLS 3

int* averageIncome(int size, int size_2, int arr[][size_2]) {

    int* t_arr = calloc(4, sizeof(int)); // calloc to initialize the array elements to 0.

    int avg = 0;                         // definition of avg placed outside of the loop.

    for (int i = 0; i < size_2; i++) {

        for (int j = 0; j < size; j++) {

            printf("%d\n", arr[j][i]);       // j swapped with i.
            avg += arr[j][i];                // same here too.
        }
        printf("-----\n");

        t_arr[i] = avg / size;
        avg = 0;
    }

    return t_arr;
}

int main (void) 
{
    int censusData[ROWS][COLS] = {
                                   {87290, 77787, 55632},
                                   {83020, 78373, 62314},
                                   {95588, 87934, 705421},
                                   {112456, 97657, 809767}
                                 };

    int* p = averageIncome(ROWS, COLS, censusData);

    for ( int i = 0; i < COLS; i++ )
    {
       printf("Average Income of %d. column is: %d\n", i + 1, p[i]);
    }

    return 0;
}

Output:

87290
83020
95588
112456
-----
77787
78373
87934
97657
-----
55632
62314
705421
809767
-----
Average Income of 1. column is: 94588
Average Income of 2. column is: 85437
Average Income of 3. column is: 408283

Side notes:

  • Always check the returned pointer from a memory-management for a null pointer if the allocation failed.

  • I used calloc() instead of malloc() to initialize all elements of the dynamically allocated array to 0.

  • The definition of avg should be placed before the nested loops, not within. Reset avg to 0 at the end of the outer loop.

  • avg /= size_2; t_arr[i] = avg; should be avg /= size; t_arr[i] = avg;. Note the replacement of size_2 with size.

  • avg /= size; t_arr[i] = avg; can be simplified by t_arr[i] = avg / size;.

0

You can loop over the columns first and then print the corresponding element of each row:

for (int col = 0; col < 3; ++col)
{
    for (int row = 0; row < 4; ++row)
    {
        printf("%d\n", censusData[row][col]);

        // Do other stuff here
    }

    printf("-----\n");
}

For each row, the colth element is printed. So for col = 0, censusData[0][0], censusData[1][0], censusData[2][0], censusData[3][0] will be printed.

In your code, you can just swap the positions of the two for loops to iterate over the columns first.

Smich
  • 345
  • 1
  • 7
  • 17