在下面的程序中,数组
ar
的长度在main上是正确的,但在temp
中显示的是指向ar
的指针的长度,该指针在我的计算机上为2(以sizeof(int)
为单位)。 #include <stdio.h>
void temp(int ar[]) // this could also be declared as `int *ar`
{
printf("%d\n", (int) sizeof(ar)/sizeof(int));
}
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", (int) sizeof(ar)/sizeof(int));
temp(ar);
return 0;
}
我想知道如何定义函数,以便在函数中正确读取数组的长度。
#1 楼
没有确定函数内部长度的“内置”方法。但是,您传递arr
,sizeof(arr)
将始终返回指针大小。因此,最好的方法是将元素数量作为单独的参数传递。或者,您可以使用特殊的值,例如0
或-1
来指示结束(例如字符串中的char []
,它们只是sizeof(arr)/sizeof(int) - 1
)。但是,当然,'逻辑'数组大小为q4312079q
评论
这是一个有趣的建议!我将尝试这样做。在我的程序中,数组中的值必须为正,因此我将添加负值。但是问题是这样的:如何在不知道数组中有多少元素的情况下,如何在数组末尾添加负值?
–makhlaghi
13年7月11日在9:59
在您的示例中,您将声明int ar [] = {1,2,3,-1};。在更复杂的情况下,您可以在填充之前,使用-1在循环中初始化完整的数组。
– Ingo Leonhardt
13年7月11日10:00
'逻辑'数组大小为sizeof(arr)/ sizeof(int)-1 NO数组大小为:sizeof(arr)/ sizeof(int),将-1用作最高索引。
–吉列什·乔汉(Grijesh Chauhan)
13年7月11日在10:06
@Grijesh这就是为什么我写“逻辑”的原因。考虑一下strlen(),其中也不计算“ \ 0”。
– Ingo Leonhardt
13年7月11日在10:08
#2 楼
不要使用函数,请使用宏://Adapted from K&R, p.135 of edition 2.
#define arrayLength(array) (sizeof((array))/sizeof((array)[0]))
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", arrayLength(ar));
return 0;
}
您仍然不能在像
temp
这样的函数中使用此宏,在该函数中将数组作为参数传递由于其他人提到的原因。如果要传递一种数据类型,也可以定义一个既具有数组又具有容量的类型:
typedef struct
{
int *values;
int capacity;
} intArray;
void temp(intArray array)
{
printf("%d\n", array.capacity);
}
int main(void)
{
int ar[]= {1, 2, 3};
intArray arr;
arr.values = ar;
arr.capacity = arrayLength(ar);
temp(arr);
return 0;
}
这需要花费较长的时间设置,但是如果您发现自己将其传递给许多功能,则很有用。
评论
谢谢,但是该宏也无法在该函数中使用。如果我希望在main()中完成此工作,那么从一开始就没有问题。
–makhlaghi
13年7月11日在10:07
@astroboy很公平,我也提出了另一个建议。
–weston
13年7月11日在10:24
这是一个有趣的方法。我一定会考虑的。再次感谢。
–makhlaghi
13年7月11日在10:27
#3 楼
正如其他人所说的,明显的解决方案是将数组的长度作为参数传递,也可以将此值存储在数组的开头。#include <stdio.h>
void temp(int *ar)
{
printf("%d\n", ar[-1]);
}
int main(void)
{
int ar[]= {0, 1, 2, 3};
ar[0] = sizeof(ar) / sizeof(ar[0]) - 1;
printf("%d\n", ar[0]);
temp(ar + 1);
return 0;
}
#4 楼
当您编写size(ar)
时,您传递的是指针而不是数组。 指针和一个int的大小为4或8-取决于ABI(或者,如@ H2CO3所述-完全不同),因此您得到的是
sizeof(int *)/sizeof int
(对于4/4 = 1 32位计算机,对于64位计算机,则为8/4 = 2),该值是1或2(或其他值)。请记住,在C中,将数组作为参数传递给函数,您正在传递指向数组的指针。如果要传递数组的大小,则应将其作为单独的参数传递。
评论
谢谢你的解释。我知道,我只是想看看在不添加参数的情况下,是否真的无法在函数内部执行此操作。
–makhlaghi
13年7月11日在10:01
@Maroun Maroun我首先写了相同的答案,但由于没有答案,因此删除了,请阅读我对问题的评论。
–吉列什·乔汉(Grijesh Chauhan)
13年7月11日在10:03
“指针和一个int的大小为4或8”-或完全不同。无需做出错误的假设就可以很好地解释这一点。
–user529758
13年7月11日在10:27
@ H2CO3可以说您可以有两个不同的值来阐明我的观点,这足够了,但是,我将添加它,这样会更好。
– Maroun
13年7月11日在10:31
“您正在将指针传递给数组。”不太正确。如果将数组传递给函数,则它“衰减”到指向其第一个元素的指针。按地址,这与指向数组的指针相同,按类型,它肯定不是。
–alk
17年12月30日在17:43
#5 楼
我认为您无法使用函数来执行此操作。它总是返回指针的长度,而不是整个数组的长度。#6 楼
您需要将数组包装成一个结构:#include<stdio.h>
struct foo {int arr[5];};
struct bar {double arr[10];};
void temp(struct foo f, struct bar g)
{
printf("%d\n",(sizeof f.arr)/(sizeof f.arr[0]));
printf("%d\n",(sizeof g.arr)/(sizeof g.arr[0]));
}
void main(void)
{
struct foo tmp1 = {{1,2,3,4,5}};
struct bar tmp2;
temp(tmp1,tmp2);
return;
}
评论
最好的方法是添加一个额外的参数,该参数采用数组的大小,即void temp(int * ar,size_t len);据我了解,@ Th3Cuber他希望长度作为结果。
因为sizeof操作员计算机的大小在编译时是这样,所以它不能是动态的。您必须明确地传递它。在这里阅读:sizeof是一个编译时运算符
strlen()仅适用于字符串,不适用于整数数组,这不正确吗?
@Ishmeet strlen计算\ 0之前的字符数,而不是数组的容量。