传球达阵和数组指针之间的差异成C函数 [英] Difference between passing array and array pointer into function in C
问题描述
什么是C中的两个函数的区别?
无效F1(双A []){
// ...
}无效F2(双*一){
// ...
}
如果我是调用一个相当长的阵列上的功能,就这两个功能不同的行为,他们将采取在堆栈上更多的空间?
首先,一些的 standardese :
6.7.5.3功能说明符(包括原型)的结果
...结果
7参数的声明为''的阵类型''应调整到'合格的指针
键入',其中类型修饰符(如果有的话)在[
和] $ C的规定$ C>的
数组类型推导。如果关键字静态
也出现在[
和]
的
阵列型推导,然后为每个呼叫的功能,相应的值
实际参数应提供访问数组的第一个元素至少有尽可能多的
由大小前pression指定的元素。
块引用>因此,简而言之,任何函数参数声明为
T一[]
或T一[N]
终止处理的如同的它被宣布为T * A
。那么,为什么数组参数当作好像他们被宣布为指针?这里的原因:
6.3.2.1左值,数组和功能代号的结果
...结果
3除非它是的sizeof
运营商或一元和
运算符的操作数,或者是
字符串用于初始化数组,有型'的前pression'的阵类型'是
转换为具有类型的前pression''指针类型'指向的初始元素
数组对象,而不是一个左值。如果数组对象有注册存储类中,
行为是不确定的。
块引用>由于以下code:
INT主要(无效)
{
INT ARR [10];
富(ARR);
...
}在调用
富
,数组前pression改编
不是一个操作数要么的sizeof
或&安培;
,所以它的类型是隐式由10元素的数组转换INT
到指针INT
根据6.2.3.1/3。因此,富
将收到一个指针值,而不是一个数组值。由于6.7.5.3/7的,你可以写
富
为无效美孚(int类型的[])//或者int a [10]
{
...
}但它会作为PTED间$ P $
无效美孚(INT *一)
{
...
}因此,这两种形式是相同的。
在6.7.5.3/7最后一句与C99引入,基本上意味着,如果你有一个参数声明像
无效美孚(INT一个[静态10])
{
...
}对应
A
必须是一个数组的实际参数的至少的10个元素。What is the difference between the two functions in C?
void f1(double a[]) { //... } void f2(double *a) { //... }
If I were to call the functions on a substantially long array, would these two functions behave differently, would they take more space on the stack?
解决方案First, some standardese:
6.7.5.3 Function declarators (including prototypes)
...
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the[
and]
of the array type derivation. If the keywordstatic
also appears within the[
and]
of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.So, in short, any function parameter declared as
T a[]
orT a[N]
is treated as though it were declaredT *a
.So, why are array parameters treated as though they were declared as pointers? Here's why:
6.3.2.1 Lvalues, arrays, and function designators
...
3 Except when it is the operand of thesizeof
operator or the unary&
operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.Given the following code:
int main(void) { int arr[10]; foo(arr); ... }
In the call to
foo
, the array expressionarr
isn't an operand of eithersizeof
or&
, so its type is implicitly converted from "10-element array ofint
" to "pointer toint
" according to 6.2.3.1/3. Thus,foo
will receive a pointer value, rather than an array value.Because of 6.7.5.3/7, you can write
foo
asvoid foo(int a[]) // or int a[10] { ... }
but it will be interpreted as
void foo(int *a) { ... }
Thus, the two forms are identical.
The last sentence in 6.7.5.3/7 was introduced with C99, and basically means that if you have a parameter declaration like
void foo(int a[static 10]) { ... }
the actual parameter corresponding to
a
must be an array with at least 10 elements.这篇关于传球达阵和数组指针之间的差异成C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!