C语言:二维数组的大小

34

我需要帮助统计二维数组的行和列。似乎我无法计算列?

#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);

}

输出:
行数:10
列数:0


8
int column = sizeof(result[0])/sizeof(result[0][0]); - BLUEPIXY
1
既然它们是静态的,为什么你还要对它们进行计数呢?只需定义行和列大小的常量,而不是使用“魔数”。 - Lundin
7个回答

22

这是整数除法的问题!

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

应该是这样的

int column = 7 / 10;

在整数除法中,7/10==0

你想要做的是将一行的长度,例如sizeof(result[0]),除以该行元素的大小,例如sizeof(result[0][0])

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

3
这是错误的。在这里,你将7(第一行中元素的数量)除以1( result [0] [0] 字符数)。 - emi
5
为什么这是错误的?sizeof(result) = 70,sizeof(result[0]) = 7,sizeof(result[0][0]) = 1,因此行数=70/7 = 10是正确的,列数=7/1 = 7也是正确的。即使您将类型从char更改为int(假设int = 32位),sizeof(result) = 280,sizeof(result[0]) = 28,sizeof(result[0][0]) = 4,因此,正如您再次注意到的那样,行数=280/28 = 10是正确的,并且列数=28/4 = 7也是正确的。 - ZeZNiQ

16

使用数组长度宏要方便得多(而且容易出错的情况会更少):

#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;
}

为什么在LEN宏上要进行整数转换?数组不是同质数据结构吗,即分子始终是分母的倍数吗?此外,除法不应该返回一个无符号整数或已经是某种整数类型的size_t吗? - Rafa Viotti
1
@Rafa 如果我们将格式说明符%d更改为%lu,则可以省略强制转换。 当LEN用于for循环保护时,我们需要使用强制转换或使用类型size_t声明索引变量。 - August Karlstrom
不同意“更少出错”的说法;这个想法很好,但也很危险;有很多种方式可以将数组隐式转换为指针类型,其中一种尤其危险:有人试图通过迭代行并在循环中执行类似于LEN(result++)的操作。 - Marcus Müller
@MarcusMüller是的,具有副作用的表达式很丑陋和容易出错,你的例子说明了为什么应该避免使用它。即使您直接使用sizeof运算符,仍然需要知道您是否有指针或数组。 - August Karlstrom

10

这对我有效(注释解释了为什么):

#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);

}

这个的输出结果是:

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

编辑:

如@AnorZaken所指出的那样,将数组作为参数传递给函数并打印sizeof的结果会输出另一个total。这是因为当你将数组作为参数传递时(而不是指向它的指针),C语言会在中间应用一些魔法,并将其作为副本传递,因此你传递的不是完全相同的东西。为确保自己的操作以及避免额外的CPU工作和内存消耗,最好通过引用(使用指针)来传递数组和对象。因此,你可以使用以下代码,与原始代码产生相同的结果:

#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;
}

2
仅提供代码答案而不解释通常对未来的访问者非常无益。请考虑编辑您的答案,提供有关解决过程的更多信息/见解。 - Magisch
4
对我来说,代码是自我解释的,但我能理解你。现在正在编辑答案。 - emi
嗨@AnorZaken。如果您将变量作为指向数据所在位置的指针传递,那么对其进行sizeof操作将返回指向变量的指针的大小,而不是变量本身的大小。在这种情况下,您可以尝试对指针指向的数据进行sizeof操作,例如:total = sizeof(*result); - emi
1
@AnorZaken 刚刚编辑了答案以回答您特定的问题。 - emi
文档很清晰!谢谢!@emi - Sayed Sadat
显示剩余2条评论

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
你能解释一下这段代码提供了什么,而其他(早期的)答案中已经没有给出的吗? - Adrian Mole

0

其他回答已经很好地解释了这个概念,但对于初学者来说可能有些困难,所以我会提供我的版本:

    #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
    // 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));

0
使用下面代码中显示的宏来获取1D、2D或3D数组的任何维度大小。类似地编写更多宏以获取4D数组及以上的维度。 (我知道现在对于Wickerman来说已经太晚了,但这些是为其他访问此页面的人准备的)
// 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));
    // ]
}
// ]

1
嗨,请在您的答案中添加一些解释,使其更可靠。 - mehrdadep
@MehrdadEP 觉得代码很明显,所以没有添加任何解释。现在已经添加了注释和输出。希望这有所帮助。 - kaali-keshav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接