【问题标题】:C: Size of two dimensional arrayC:二维数组的大小
【发布时间】:2015-12-07 12:54:30
【问题描述】:

我需要一些帮助来计算二维数组的行和列。我好像不能数列?

#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

【问题讨论】:

  • int column = sizeof(result[0])/sizeof(result[0][0]);
  • 既然它们是静态的,为什么还要计算它们呢?只需为行和列大小定义常量,而不是使用“幻数”。

标签: c arrays dimensional


【解决方案1】:

这是整数除法的问题!

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

【讨论】:

  • 这是错误的。在这里,您将 7(第一行的元素数)除以 1(result[0][0] 上的字符数)。
  • 为什么错了? sizeof(result) = 70, sizeof(result[0]) = 7, sizeof(result[0][0]) = 1,所以行数=70/7=10正确,列数=7 /1 = 7 也是正确的。即使您将类型从 char 更改为 int(假设 int = 32bits), sizeof (result) = 280, sizeof (result[0]) = 28, sizeof (result[0][0]) = 4,所以,如你可以再次注意到,行数 = 280/28 = 10 是正确的,列数 = 28/4 = 7 也是正确的。
【解决方案2】:

使用数组长度宏更方便(并且更不容易出错):

#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 宏上进行整数转换?数组不是同质数据结构,即,提名者总是分母的倍数吗?另外,除法不应该返回 unsigned integersize_t,这已经是某种整数类型了吗?
  • @Rafa 如果我们将格式说明符 %d 更改为 %lu,我们可以不使用演员表。当 LEN 用于 for 循环保护时,我们需要使用强制转换或声明类型为 size_t 的索引变量。
  • 不同意“不易出错”的说法;这个想法很好,但很危险;有很多方法可以将数组隐式转换为指针类型,其中一种特别危险:有人试图遍历行并在循环中执行LEN(result++) 之类的操作。
  • @MarcusMüller 是的,带有副作用的表达式是丑陋且容易出错的,您的示例说明了为什么应该避免它。即使您直接使用sizeof 运算符,您仍然需要知道您是否有指针或数组。
【解决方案3】:

这对我有用(cmets 解释了为什么):

#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 会将其作为副本传递,并在两者之间应用一些 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;
}

【讨论】:

  • 没有解释的仅代码答案通常对未来的访问者没有帮助。考虑编辑您的答案,以提供有关您的解决过程的更多信息/见解。
  • 代码对我来说是不言自明的,但理解你。现在编辑答案。
  • 只是指出这不适用于作为函数参数接收的数组,特别是 total = sizeof result; 将不起作用:它将生成警告并评估单个元素的大小而不是整个数组的大小。所以要么需要 VLA(并且你传递行和列参数),要么你必须传递行数或总计数作为参数(仍然可以使用 sizeof 确定列)。
  • 嗨@AnorZaken。如果您将变量作为指向数据所在位置的指针传递,则其上的 sizeof 将返回指向变量的指针的大小,而不是变量本身的大小。在这种情况下,您可以尝试对指针指向的数据执行sizeof,例如:total = sizeof(*result);
  • @AnorZaken 刚刚编辑了答案以回答您的具体问题。
【解决方案4】:
    // 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));

【讨论】:

    【解决方案5】:

    使用下面代码中显示的宏来获取 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));
        // ]
    }
    // ]
    

    【讨论】:

    • 嗨,请在您的答案中添加一些解释,以使其更可靠
    • @MehrdadEP 认为代码很明显,所以没有添加任何解释。现在添加了 cmets 和输出。希望对您有所帮助。
    【解决方案6】:

    其他答案很好地解释了这个概念,但对初学者不友好;所以这是我的版本-

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

    【讨论】:

      猜你喜欢
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 2020-01-18
      • 2017-01-05
      相关资源
      最近更新 更多