传球达阵和数组指针之间的差异成C函数 [英] Difference between passing array and array pointer into function in C

查看:157
本文介绍了传球达阵和数组指针之间的差异成C函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是C中的两个函数的区别?

 无效F1(双A []){
   // ...
}无效F2(双*一){
   // ...
}

如果我是调用一个相当长的阵列上的功能,就这两个功能不同的行为,他们将采取在堆栈上更多的空间?


解决方案

首先,一些的 standardese


6.7.5.3功能说明符(包括原型)的结果
...结果
7参数的声明为''的阵类型''应调整到'合格的指针
键入',其中类型修饰符(如果有的话)在 []
数组类型推导。如果关键字静态也出现在 []
阵列型推导,然后为每个呼叫的功能,相应的值
实际参数应提供访问数组的第一个元素至少有尽可能多的
由大小前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 keyword static 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[] or T a[N] is treated as though it were declared T *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 the sizeof 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 expression arr isn't an operand of either sizeof or &, so its type is implicitly converted from "10-element array of int" to "pointer to int" 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 as

void 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆