C 函数:数组参数长度

问题描述 投票:0回答:1

这个问题建立在这个的基础上,它描述了以下内容如何等效:

int f(int a[10]) { ... } // the 10 makes no difference
int f(int a[]) { ... }
int f(int *a) { ... } 

在有关函数原型范围的文档中,提供了以下示例:

int f(int n, int a[n]); // n is in scope, refers to first param

这让我质疑以下内容在多大程度上是等效的:

// 1.
int f(int n, int a[n]) { ... }
int f(int n, int *a) { ... }
// my guess: exactly equivalent

// 2.
int x = 10; int f(int a[x]) { ... }
int x = 10; int f(int *a) { ... }
// my guess: exactly equivalent

// 3.
int f(int a[n], int n) { ... }
int f(int *a, int n) { ... }
// my guess: not equivalent: first f won't compile, second will

结论性问题:

  • 如果都编译,
    int f(int arr[n])
    int f(int *arr)
    总是等价的吗?
  • 为什么编译器要查找标识符
    n
    ,即使它的值不会被使用。
    • 我的猜测:在源代码中包含
      n
      的唯一原因是作为文档来指示数组应具有的最小长度。确保
      n
      在范围内并且具有正确的类型,确保此文档有意义
arrays c function arguments
1个回答
0
投票
  • 如果都编译,
    int f(int arr[n])
    int f(int *arr)
    总是等价的吗?

不。 C标准在这一点上是有缺陷的;它没有说明

n
中的
int arr[n]
是否被评估。

int arr[n]
名义上声明一个可变长度数组(假设
n
是某个对象的标识符,而不是常量的宏)。 C 标准规定对可变长度数组的大小进行评估,还规定参数声明
int arr[n]
自动调整为
int *arr
,但尚不清楚这些出现的顺序。 GCC 和 Clang 的不同之处这一点; Clang 计算数组大小,但 GCC 不计算。对于合格对象
n
,这没有什么区别,但是,如果
n
是易失性的,或者数组大小是其他具有副作用的表达式,那么它确实会产生影响。

  • 为什么编译器要查找标识符
    n
    ,即使它的值不会被使用。

编译器需要解析代码以确定其语法结构。如果那里有一个关键字,而不是一个标识符,编译器将不得不给你一个不同的错误消息。或者那里的关键字可以是

static
,在该位置有效。

© www.soinside.com 2019 - 2024. All rights reserved.