2012-01-03 54 views
-4

可能重复:
C sizeof a passed array调用的功能

,而不是发送的sizeof:

void main() 

    int x[] = {1, 2, 3, 1, 3, 0, 6}; 
    dupes(x, sizeof x/sizeof x[0]); 
... 
} 

int dupes(int a[], int n) 
... 
... 

为什么不能我只用数组来调用它:

int main() 
{ 
    int x[] = {1, 2, 3, 1, 3, 0, 6}; 
    dupes(x); 
... 
} 
int dupes(int a[]) 
{ 
    int n = sizeof a/sizeof a[0]; 

当我这样做的大小总是得到1 - 它不能是1 casue我发送7个元素的数组!

+1

投票关闭并否决由于Sveta26复制粘贴到所有的答案同样的评论,似乎不关心什么实际答案说。 – unwind 2012-01-03 13:27:08

回答

0

这是因为当你将一个数组传递给一个函数时,它会被复制到一个指针中,并且关于它的大小的信息会丢失。在被调用的函数中,它只是一个普通的指针。

所以(a)的变大小4(因为其指针)和sizeof(A [0])也是4(因为它的一个整数),所以n等于1

+0

好吧,所以我怎么能从函数内部定义它,并只使用数组指针进行调用? – Sveta26 2012-01-03 13:19:51

+1

没有办法从指针中获取数组的大小,您必须通过 – 2012-01-03 13:22:31

0

sizeof a [0];重建数组的第一个元素

并且当您传递数组时,它将返回数组第一个元素的地址,因此您还必须指定长度。

在内部横穿阵列如下:

int a[]={1,2,3}; 

when you pass a[] as a function argument it sends the address of the element a[0]也就是1的内部地址,并计算出[1]作为

address of a[0] + size of int (type of an array)

当键入sizeof(a[]) it will return the sizeof(int pointer) as a[0] contains the internal address(integer pointer).

+0

好吧,那么我怎么能从函数内部定义它,并只使用数组指针进行调用? – Sveta26 2012-01-03 13:20:14

+0

如果你知道数组的长度,你可以使用指针来遍历它,但是对于这个“小心,因为你正在做内存操作”,请参考http://www.programmersheaven.com/mb/CandCPP/159211/159211/using-一个指针遍历该数组索引/ – 2012-01-03 13:25:06

3

sizeof不是一个函数,它是一个编译器操作符(所以你不要“调用”sizeof,你只需使用sizeof运营商)。编译器无法知道函数dupes的正式参数a的大小(并且视为int* a,即指针正式)。

sizeof总是在编译时计算。

+0

好吧,那么我怎么能从函数内部定义它,并只使用数组指针进行调用? – Sveta26 2012-01-03 13:22:02

+0

您必须在某处放置数组的(运行时)维度。你如何给予你(作为第二个参数,作为常规常量,作为结构成员,在全局变量中......)。处理器不知道什么是阵列!我强烈建议花几个小时**阅读一本好的C编程书籍** – 2012-01-03 13:24:34

+2

“'sizeof'总是在编译时计算出来的”。始终只有在sizeof表达式中没有VLA。使用VLA,如果数组大小的值影响'sizeof'表达式的值,那么将评估数组表达式。 – ouah 2012-01-03 13:32:18

1

当数组传递给函数时,数组衰减为指向其第一个元素的指针。 sizeof只适用于传递实际原始数组。

在其他语言中,数组引用始终与它们一起携带长度,但C哲学反对这种隐藏的性能损失,因此您必须自己通过该长度。

+0

好吧,所以我怎么能从函数内部定义它,并只使用数组指针进行调用? – Sveta26 2012-01-03 13:21:44

+0

@ Sveta26:你不能。你可以考虑做的不是通过一个单独的长度属性来标记输入的结束,而是使用特殊的终止符值来标记最后一个元素。这是他们如何处理标准库中的字符串。 – hugomg 2012-01-03 13:39:15

1

该原型在C:

int dupes(int a[]) 
{ 

} 

等效于此原型:

int dupes(int *a) 
{ 

} 

您数组参数a被转换为指针int

关于函数声明,这出现在6.7.5.3p7在C99标准

一个参数作为“”“类型的数组”的声明,应调整至 “”合格指针为类型“” ,其中类型限定符(如果有的话)是 在数组类型派生[和]中指定的那些。

C中的数组是二等公民,您不能将数组传递给函数。您只需将指针传递给数组的第一个元素即可。

所以当你计算sizeof a时,结果是指针的大小而不是数组的大小。

在你的函数体sizeof a/sizeof a[0]实际计算的:sizeof (int *)/sizeof (int)它产生在你的系统1,因为int *的大小是一样的int的系统中的大小。

+0

ok的大小,那么我如何从函数内部定义它并仅使用数组指针进行调用? – Sveta26 2012-01-03 13:21:53

+0

使用'int dupes(int a [],size_t n)'是要走的路。 – ouah 2012-01-03 13:28:54

0

这是因为您无法直接将数组传递给函数。您只能将指针传递给此类数组中的元素。

在功能参数时,[]确实平均阵列,这意味着一个指针

int dupes(int a[]) 

是完全相同

int dupes(int *a) 

当使用的阵列为一体的名称一个值,它实际上意味着指向该数组中的1.元素的指针。指针就是这个指针。它不知道它指向给定大小的数组。

因此,例如, int *a = x;将分配一个指向x中的第一个元素的指针,以a - 同样的事情,当您调用一个函数时,dupes(x)将传递一个指针指向x中的第一个元素作为dupes函数的参数。这跟调用dupes(&x[0])

在dupes()函数里面,它的参数只是一个指针。因此sizeof x/sizeof x[0]等于sizeof(int*)/sizeof(int),如果指针的大小与int相同,则为1。 (但是,由于您向数组中的元素传递了指针,因此您可以增加该指针以访问其他元素,例如,x + 2将使x指向3.元素(从1开始计数),因为阵列。如果您取消引用该指针,则会得到它的值:*(x + 2)。并记住,作为值,x[2]相同*(x + 2)

+0

好吧,那么我怎么能从函数内部定义它,并只使用数组指针进行调用? – Sveta26 2012-01-03 13:21:32

+0

@ Sveta26如果你必须只传递一个参数,“数组”,你必须弄清楚别的。例如您可以将该大小存储在您在该函数中读取的全局可变数据中。或者你可以存储一个特殊值作为数组中的最后一个元素,例如-1,并且函数计算它在找到-1之前遍历了多少个元素。 – nos 2012-01-03 13:37:21

0

当型“T N元件阵列”的表达出现在大多数情况下,它是隐式转换为类型的表达式“指针T”和它的值是数组中第一个元素的地址。当数组表达式是sizeof和一元运算符&的操作数时,或者是用于在声明中初始化数组的字符串文字时,才会出现此规则的唯一例外情况。

当调用dupes,表达x从型“int 7个元素的数组”到“指针int”转换,所以dupes函数接收指针值,而不是阵列。在函数参数声明的上下文中,T a[N]T a[]相当于T *a

所以在dupes功能,sizeof a/sizeof a[0]相当于sizeof (int *)/sizeof (int),而你的情况是1