C中多维数组的内部数组的元素数

Number of elements of the inner arrays of a multidimentional array in C

我是 C 的新手,通过在线阅读我了解到使用 sizeof() 我可以拥有以字节为单位分配给它的内存,如果我将它除以其中的元素或数据类型,我可以有数组元素的数量。

我正在尝试将此逻辑与二维多维数组一起使用,但内部数组出现问题。

这是一个代码示例:

#include <stdio.h>

#define ARRAYLEN(arr) (sizeof(arr) / sizeof(arr[0]))

int main(void) {
    int input[][20] = {
        {90, 1349, 430, 198, 677, 1869, 1692, 1098, 761, 677, 1004 ,0},
        {163, 642 ,2445, 1032, 2738 ,1591 ,3950 ,1600 ,651, 0},
        {1730 ,3067 ,1956, 723 ,1307 ,417 ,2838 ,1486 ,3114 ,3698 ,1881 ,0},
        {2337, 5131 ,1527 ,5042 ,953, 0},
        {80, 389, 413 ,209 ,219, 100 ,191, 419, 181 ,473 ,271 ,0},
        {22 ,3900 ,4057, 439 ,2642, 1447 ,3553, 2244, 3328, 3924, 1486, 400, 2394 ,0},
        {2870, 621 ,3779, 3508, 3729, 2985, 1083, 1384, 3782 ,2606, 637, 0},
        {1400, 108 ,472 ,1411, 10, 453, 1631, 1331, 0},
        {808 ,1584, 2545, 2294, 1983, 842 ,447, 807 ,3711, 1067, 490, 0},
        {435 ,14 ,261, 395, 340, 340, 25, 114, 178 ,52 ,232 ,19, 54, 0},
        {6181 ,2026, 4061, 7796 ,5192 ,958, 4190, 965 ,2642, 5082, 2579, 1872 ,0},
        {2030, 106, 579, 36, 1147 ,111 ,1393 ,459, 209, 1847, 1171, 415, 725, 1245, 0}
    };

    printf("%d", ARRAYLEN(input));
    printf(" ");
    printf("%d", ARRAYLEN(input[0]));

    printf(" ");
    printf("%d", sizeof(input[0]) / sizeof(int));

    return 0;
}

第一个 printf() returns 12 是正确的,但是第二个 printf()(和第三个)return 20是我分配给它的内存,而不是每个元素的元素数量,这是我正在寻找的,以便在 for 循环中使用。

谁能解释一下我该怎么做?或者我做错了什么?

我到处都找不到 answer/explanation。

提前致谢

你有一个 12 行的数组,每行 20 个元素。行数由您提供的初始化行数定义。元素个数由数字20决定。

(sizeof(input) / sizeof(input[0]))给出的大小是行数

(sizeof(input[0]) / sizeof(input[0][0]))给出的大小是一行中的元素个数

(sizeof(input) / sizeof(input[0][0]))给出的大小是整数,即行x列。

以下代码打印数组:

for (int i=0; i<ARRAYLEN(input); i++) {
    for (int j=0; j<ARRAYLEN(input[0]); j++) {
        printf("%d ",input[i][j]);
    }
    printf("\n");
}

您的程序在 sizeof(size_t) != sizeof(int) 的体系结构上具有潜在的未定义行为。在 printf 格式字符串中使用 %zu 或将参数转换为 (int).

您还应该更仔细地括起 ARRAYLEN 宏参数。

这是修改后的版本:

#include <stdio.h>

#define ARRAYLEN(arr) (sizeof(arr) / sizeof((arr)[0]))

int main(void) {
    int input[][20] = {
        {90, 1349, 430, 198, 677, 1869, 1692, 1098, 761, 677, 1004 ,0},
        {163, 642 ,2445, 1032, 2738 ,1591 ,3950 ,1600 ,651, 0},
        {1730 ,3067 ,1956, 723 ,1307 ,417 ,2838 ,1486 ,3114 ,3698 ,1881 ,0},
        {2337, 5131 ,1527 ,5042 ,953, 0},
        {80, 389, 413 ,209 ,219, 100 ,191, 419, 181 ,473 ,271 ,0},
        {22 ,3900 ,4057, 439 ,2642, 1447 ,3553, 2244, 3328, 3924, 1486, 400, 2394 ,0},
        {2870, 621 ,3779, 3508, 3729, 2985, 1083, 1384, 3782 ,2606, 637, 0},
        {1400, 108 ,472 ,1411, 10, 453, 1631, 1331, 0},
        {808 ,1584, 2545, 2294, 1983, 842 ,447, 807 ,3711, 1067, 490, 0},
        {435 ,14 ,261, 395, 340, 340, 25, 114, 178 ,52 ,232 ,19, 54, 0},
        {6181 ,2026, 4061, 7796 ,5192 ,958, 4190, 965 ,2642, 5082, 2579, 1872 ,0},
        {2030, 106, 579, 36, 1147 ,111 ,1393 ,459, 209, 1847, 1171, 415, 725, 1245, 0}
    };

    printf("%d %d %d\n",
        (int)ARRAYLEN(input),
        (int)ARRAYLEN(input[0]),
        (int)(sizeof(input[0]) / sizeof(int)));

    return 0;
}

输出为 12 20 20,符合预期:

  • 12是数组的元素个数input:12行20int.
  • 根据定义,
  • 20 是数组 input[0] 中元素的数量。
  • 20 也是数组中元素的数量 input[0] 因为 int 是其元素的类型。

部分或全部子数组的初始值设定项中的元素较少这一事实不会改变它们的大小,每个子数组有定义 int input[][20] 中指定的 20 个元素,其余元素元素被初始化为 0。子数组的数量由编译器从初始化程序中确定。

您的问题可以简化为:

int array[10] = {1,2,3};

ARRAYLEN(array) == 10

如果您明确指定数组的大小(int x[N] 而不是 int x[]),则数组将始终具有您指定的大小,而不管 curly 内部的初始化器数量牙套。

没有初始化器的元素用零初始化。

也就是说

没有区别
int array[10] = {1,2,3};

int array[10] = {1,2,3,0,0,0,0,0,0,0};

此外,正如其他人指出的那样,您的宏应该定义为

#define ARRAYLEN(arr) (sizeof(arr) / sizeof((arr)[0]))

如果宏参数恰好是一个表达式而不是一个简单的数组名称,以避免运算符优先级出现问题。

你从这个宏中得到的值应该用 %zu 打印出来,因为它是 size_t 类型,而不是 int.