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

时间:2018-06-30 15:08:50

标签: c arrays multidimensional-array sizeof

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

我正在尝试将这种逻辑用于2D多维数组,但是内部数组存在问题。

这是一个代码示例:

#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()返回正确的12,但是第二个printf()(和第三个)返回20,这是我分配给它的内存每个元素都有的元素数量,这就是我想要在for循环上使用的元素。

有人可以解释我该怎么做吗?还是我做错了?

我在任何地方都找不到答案/解释。

预先感谢

3 个答案:

答案 0 :(得分:0)

您有一个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");
}

答案 1 :(得分:0)

您的程序在sizeof(size_t) != sizeof(int)的体系结构上可能具有未定义的行为。在您的%zu格式字符串中使用printf或将参数强制转换为(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行,每行20个int
  • 20是根据定义的数组input[0]中的元素数。
  • 20再次是数组input[0]中元素的数量,因为int是其元素的类型。

对于某些或所有子数组,初始化器中元素较少的事实并没有改变它们的大小,每个子数组都有定义int input[][20]中指定的20个元素,其余元素为初始化为0。子数组的数量由编译器从初始化程序确定。

答案 2 :(得分:0)

您的问题可以简化为:

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

ARRAYLEN(array) == 10

如果您显式指定数组的大小(int x[N]而不是int x[]),则数组将始终具有您指定的大小,而不管花括号内的初始化程序数量如何。

不带有初始化器的元素以零初始化。

换句话说,两者之间没有区别

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