32

I need some help counting the rows and columns of a two dimensional array. It seems like I can't count columns?

#include <stdio.h>

int main() {

char result[10][7] = {

    {'1','X','2','X','2','1','1'},
    {'X','1','1','2','2','1','1'},
    {'X','1','1','2','2','1','1'},
    {'1','X','2','X','2','2','2'},
    {'1','X','1','X','1','X','2'},
    {'1','X','2','X','2','1','1'},
    {'1','X','2','2','1','X','1'},
    {'1','X','2','X','2','1','X'},
    {'1','1','1','X','2','2','1'},
    {'1','X','2','X','2','1','1'}

};

int row = sizeof(result) / sizeof(result[0]);
int column = sizeof(result[0])/row;

printf("Number of rows: %d\n", row);
printf("Number of columns: %d\n", column);

}

Output:
Number of rows: 10
Number of columns: 0

Wickerman
  • 367
  • 2
  • 4
  • 8
  • 8
    `int column = sizeof(result[0])/sizeof(result[0][0]);` – BLUEPIXY Dec 07 '15 at 12:57
  • 1
    Since they are static, why would you want to count them anyway? Simply define constants for row and col size, instead of using "magic numbers". – Lundin Dec 07 '15 at 13:36

7 Answers7

21

That's a problem of integer division!

int column = sizeof(result[0])/row;

should be

int column = 7 / 10;

and in integer division, 7/10==0.

What you want to do is divide the length of one row, eg. sizeof(result[0]) by the size of one element of that row, eg. sizeof(result[0][0]):

int column = sizeof(result[0])/sizeof(result[0][0]);
Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • 3
    This is wrong. Here you divide 7 (number of elements on first row) by 1 (number of characters on `result[0][0]`). – emi Dec 07 '15 at 13:23
  • 5
    Why is that wrong? sizeof (result) = 70, sizeof(result[0]) = 7, sizeof(result[0][0]) = 1, so the number of rows = 70/7 = 10 is correct and the number of columns = 7/1 = 7 is also correct. Even if you changed the type from char to int (assuming int = 32bits), sizeof (result) = 280, sizeof (result[0]) = 28, sizeof (result[0][0]) = 4, so, as you can notice again, the number of rows = 280/28 = 10 is correct and the number of columns = 28/4 = 7 is also correct. – ZeZNiQ Feb 14 '20 at 13:59
16

It's much more convenient (and less error prone) to use an array length macro:

#include <stdio.h>

#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))

int main(void)
{
    char result[10][7];

    printf("Number of rows: %d\n", LEN(result));
    printf("Number of columns: %d\n", LEN(result[0]));
    return 0;
}
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
  • Why the integer cast on the `LEN` macro? Aren't arrays homogeneous data structures, i.e., the nominator will always be a multiple of the denominator? Also, shouldn't the division return an `unsigned integer`, or `size_t`, which is already some integer type? – Rafa Viotti May 03 '17 at 00:37
  • 1
    @Rafa We can do without the cast if we change the format specifier `%d` to `%lu`. When *LEN* is used in a `for` loop guard we then need to use a cast or declare the index variables with type *size_t*. – August Karlstrom May 03 '17 at 08:07
  • Disagree with the "less error-prone"; the idea is nice, but dangerous; there's many ways an array can be implicitly converted to a pointer type, and one of them is especially dangerous: someone trying to iterate through rows and doing something like `LEN(result++)` in a loop. – Marcus Müller Jan 20 '21 at 11:05
  • @MarcusMüller Yes, having expressions with side-effects is ugly and error-prone, and your example shows why it should be avoided. Even if you use the `sizeof` operator directly you still need to know if you have a pointer or an array. – August Karlstrom Jan 20 '21 at 13:06
10

This works for me (comments explains why):

#include <stdio.h>

int main() {

   char result[10][7] = {

       {'1','X','2','X','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'1','X','2','X','2','2','2'},
       {'1','X','1','X','1','X','2'},
       {'1','X','2','X','2','1','1'},
       {'1','X','2','2','1','X','1'},
       {'1','X','2','X','2','1','X'},
       {'1','1','1','X','2','2','1'},
       {'1','X','2','X','2','1','1'}

   }; 

   // 'total' will be 70 = 10 * 7
   int total = sizeof(result);

   // 'column' will be 7 = size of first row
   int column = sizeof(result[0]);

   // 'row' will be 10 = 70 / 7
   int row = total / column;

   printf("Total fields: %d\n", total);
   printf("Number of rows: %d\n", row);
   printf("Number of columns: %d\n", column);

}

And the output of this is:

Total of fields: 70
Number of rows: 10
Number of columns: 7

EDIT:

As pointed by @AnorZaken, passing the array to a function as a parameter and printing the result of sizeof on it, will output another total. This is because when you pass an array as argument (not a pointer to it), C will pass it as copy and will apply some C magic in between, so you are not passing exactly the same as you think you are. To be sure about what you are doing and to avoid some extra CPU work and memory consumption, it's better to pass arrays and objects by reference (using pointers). So you can use something like this, with same results as original:

#include <stdio.h>

void foo(char (*result)[10][7])
{
   // 'total' will be 70 = 10 * 7
   int total = sizeof(*result);

   // 'column' will be 7 = size of first row
   int column = sizeof((*result)[0]);

   // 'row' will be 10 = 70 / 7
   int row = total / column;

   printf("Total fields: %d\n", total);
   printf("Number of rows: %d\n", row);
   printf("Number of columns: %d\n", column);

}

int main(void) {

   char result[10][7] = {

       {'1','X','2','X','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'X','1','1','2','2','1','1'},
       {'1','X','2','X','2','2','2'},
       {'1','X','1','X','1','X','2'},
       {'1','X','2','X','2','1','1'},
       {'1','X','2','2','1','X','1'},
       {'1','X','2','X','2','1','X'},
       {'1','1','1','X','2','2','1'},
       {'1','X','2','X','2','1','1'}

   };

   foo(&result);

   return 0;
}
emi
  • 2,786
  • 1
  • 16
  • 24
  • 2
    Code only answers without explaination are often very unhelpful for future visitors. Consider editing your Answer to provide further information/insight about your solving process. – Magisch Dec 07 '15 at 13:08
  • 4
    Code is autoexplanatory to me, but understand you. Now editing the answer. – emi Dec 07 '15 at 13:11
  • Just pointing out that this doesn't work on arrays received as function arguments, specifically `total = sizeof result;` won't work: it will generate a warning and evaluate to the size of a single element instead of the size of the whole array. So either VLA is required (and u pass row and column argument) or you have to pass either the row or total count as an argument (column can still be determined with sizeof). – AnorZaken Oct 25 '17 at 18:30
  • Hi @AnorZaken. If you pass the variable as a pointer to where the data resides, a `sizeof` on it will return the size of the pointer to the variable, not the one of the variable itself. In that case, you can try to do a `sizeof` to the data pointed by the pointer, with something like: `total = sizeof(*result);` – emi Oct 26 '17 at 19:03
  • @emi what I mean is that `int foo(char result[10][7]) { int total = sizeof(result); }` will not work. The value of `total` will be `1` in that case. (Of course that might seem a silly use-case since you know the size if you specified it in the function argument declaration, but still... it could have relevance for code maintenance purposes.) – AnorZaken Oct 28 '17 at 10:38
  • 1
    @AnorZaken Just edited the answer to answer your specific question. – emi Oct 28 '17 at 10:59
  • Well documented! Thanks! @emi – Sayed Sadat Dec 20 '21 at 06:26
0
    // gets you the total size of the 2d array 
    printf("Arrays Total size: %ld\n",sizeof(result));

    // gets you the cumulative size of row which is 5 columns * sizeof(int)
    printf("1 row cumulative size: %ld\n",sizeof(result[0]));

    // division of total array size with cumulative size of row gets you total number of rows
    printf("total number of rows: %ld\n",sizeof(result)/sizeof(result[0]));

    // and total number of columns you get by dividing cumulative row size with sizeof(char)
    printf("total number of columns: %ld\n",sizeof(result[0])/sizeof(char));
nomi
  • 1
  • 2
0

Use the macros shown in below code to get any dimension size of 1D, 2D or 3D arrays. More macros can be written similarly to get dimensions for 4D arrays and beyond. (i know its too late for Wickerman to have a look but these're for anyone else visiting this page)

// Output of the following program
// [
/*

Demo of the advertised macros :
----------------------------------------------
sizeof(int) = 4
sizeof(Array_1D) = 12
ELEMENTS_IN_1D_ARRAY(Array_1D) = 3
sizeof(Array_2D) = 24
ELEMENTS_IN_2D_ARRAY(Array_2D) = 6
ROWS_IN_2D_ARRAY(Array_2D) = 2
COLUMNS_IN_2D_ARRAY(Array_2D) = 3
sizeof(Array_3D) = 96
ELEMENTS_IN_3D_ARRAY(Array_3D) = 24
MATRICES_IN_3D_ARRAY(Array_3D) = 4
ROWS_IN_3D_ARRAY(Array_3D) = 2
COLUMNS_IN_3D_ARRAY(Array_3D) = 3

Array_3D[][][] Printed :
----------------------------------------------
 001 002 003
 011 012 013
---------------
 101 102 103
 111 112 113
---------------
 201 202 203
 211 212 213
---------------
 301 302 303
 311 312 313
---------------

Wickerman's problem solved :
----------------------------------------------
sizeof(result) = 70
ELEMENTS_IN_2D_ARRAY(result) = 70
ROWS_IN_2D_ARRAY(result) = 10
COLUMNS_IN_2D_ARRAY(result) = 7

*/
// ]

// ====================================================================================================
// Program follows
// ====================================================================================================

// Array Size Macros
// [
#define ELEMENTS_IN_1D_ARRAY(a1D)   ( sizeof( a1D       ) / sizeof( a1D[0]          )) // Total no. of elements in 1D array
#define ELEMENTS_IN_2D_ARRAY(a2D)   ( sizeof( a2D       ) / sizeof( a2D[0][0]       )) // Total no. of elements in 2D array
#define ROWS_IN_2D_ARRAY(a2D)       ( sizeof( a2D       ) / sizeof( a2D[0]          )) // No. of Rows in a 2D array
#define COLUMNS_IN_2D_ARRAY(a2D)    ( sizeof( a2D[0]    ) / sizeof( a2D[0][0]       )) // No. of Columns in a 2D array
#define ELEMENTS_IN_3D_ARRAY(a3D)   ( sizeof( a3D       ) / sizeof( a3D[0][0][0]    )) // Total no. of elements in 3D array
#define MATRICES_IN_3D_ARRAY(a3D)   ( sizeof( a3D       ) / sizeof( a3D[0]          )) // No. of "Matrices" (aka "Slices"/"Pages") in a 3D array
#define ROWS_IN_3D_ARRAY(a3D)       ( sizeof( a3D[0]    ) / sizeof( a3D[0][0]       )) // No. of Rows in each "Matrix" of a 3D array
#define COLUMNS_IN_3D_ARRAY(a3D)    ( sizeof( a3D[0][0] ) / sizeof( a3D[0][0][0]    )) // No. of Columns in each "Matrix" of a 3D array
// ]

#define PRINTF_d(s) (printf(#s " = %d\n", (int)(s)))    // Macro to print a decimal no. along with its corresponding decimal expression string,
                                                        // while avoiding to write the decimal expression twice.

// Demo of the Array Size Macros defined above
// [
main()
{
    // Sample array definitions
    // [
    int Array_1D[3] = {1, 2, 3};    // 1D array

    int Array_2D[2][3] =            // 2D array
    {
        {1,  2,  3},
        {11, 12, 13}
    };

    int Array_3D[4][2][3] =         // 3D Array
    {
        {
            {1,   2,   3},
            {11,  12,  13}
        },
        {
            {101, 102, 103},
            {111, 112, 113}
        },
        {
            {201, 202, 203},
            {211, 212, 213}
        },
        {
            {301, 302, 303},
            {311, 312, 313}
        }
    };
    // ]

    // Printing sizes and dimensions of arrays with the advertised Array Size Macros
    printf(
    "Demo of the advertised macros :\n"
    "----------------------------------------------\n");
    PRINTF_d(sizeof(int));
    PRINTF_d(sizeof(Array_1D));
    PRINTF_d(ELEMENTS_IN_1D_ARRAY(Array_1D));
    PRINTF_d(sizeof(Array_2D));
    PRINTF_d(ELEMENTS_IN_2D_ARRAY(Array_2D));
    PRINTF_d(ROWS_IN_2D_ARRAY(Array_2D));
    PRINTF_d(COLUMNS_IN_2D_ARRAY(Array_2D));
    PRINTF_d(sizeof(Array_3D));
    PRINTF_d(ELEMENTS_IN_3D_ARRAY(Array_3D));
    PRINTF_d(MATRICES_IN_3D_ARRAY(Array_3D));
    PRINTF_d(ROWS_IN_3D_ARRAY(Array_3D));
    PRINTF_d(COLUMNS_IN_3D_ARRAY(Array_3D));

    // Printing all elements in Array_3D using advertised macros
    // [
    int x, y, z;

    printf(
    "\nArray_3D[][][] Printed :\n"
    "----------------------------------------------\n");

    for(x = 0; x < MATRICES_IN_3D_ARRAY(Array_3D); x++)
    {
        for(y = 0; y < ROWS_IN_3D_ARRAY(Array_3D); y++)
        {
            for(z = 0; z < COLUMNS_IN_3D_ARRAY(Array_3D); z++)
                printf("%4.3i", Array_3D[x][y][z]);
            putchar('\n');
        }
        printf("---------------\n");
    }
    // ]

    // Applying those macros to solve the originally stated problem by Wickerman
    // [
    char result[10][7] = {
        {'1','X','2','X','2','1','1'},
        {'X','1','1','2','2','1','1'},
        {'X','1','1','2','2','1','1'},
        {'1','X','2','X','2','2','2'},
        {'1','X','1','X','1','X','2'},
        {'1','X','2','X','2','1','1'},
        {'1','X','2','2','1','X','1'},
        {'1','X','2','X','2','1','X'},
        {'1','1','1','X','2','2','1'},
        {'1','X','2','X','2','1','1'}
    };

    printf(
    "\nWickerman's problem solved :\n"
    "----------------------------------------------\n");
    PRINTF_d(sizeof(result)); // radha_SIZEOF_2D_ARRAY
    PRINTF_d(ELEMENTS_IN_2D_ARRAY(result)); // radha_SIZEOF_2D_ARRAY
    PRINTF_d(ROWS_IN_2D_ARRAY(result));
    PRINTF_d(COLUMNS_IN_2D_ARRAY(result));
    // ]
}
// ]
0

The other answers explain the concept really well but aren't beginner friendly; so here is my version of the same -

    #include <stdio.h>

    void main() {

      int arr [][3] = { {1,2,3 },
                       {4,5,6} };

      
        int size_row = sizeof(arr)/sizeof(arr[0]);
        int size_col = sizeof(arr[0])/sizeof(arr[0][0]);

        printf("Length of row : %d\n",size_row); *Output 24*
        printf("Length of column : %d",size_col); *Output 3*

        printf("\nTotal size of array : %d",sizeof(arr)); *Output 24*
        printf("\nSize of entire first row : %d",sizeof(arr[0])); *Output 12*
     printf("\nSize of first element of first row : %d",sizeof(arr[0][0])); *Output 3*

}
0
#include<stdio.h>
int main(){
printf("\nSize of 2-D Array:\n");
int arr[20][30]={{1,2,3,4,5},{2,1,6,7,8},{3,1,6,7,8}};
int row=sizeof(arr)/sizeof(arr[0]);
int col=sizeof(arr[0])/sizeof(arr[0][0]);
printf("Number of Row: %d",row);
printf("\nNumber of Col: %d",col);
return 0;
}
  • 1
    Can you explain what this code offers that has not already been given in several of the other (much older) answers? – Adrian Mole Jan 09 '23 at 04:30