我是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循环上使用的元素。
有人可以解释我该怎么做吗?还是我做错了?
我在任何地方都找不到答案/解释。
预先感谢
答案 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
。