在参数声明中指定数组大小的意义是什么? [英] What is the point of specifying the size of an array in a parameter declaration?

查看:69
本文介绍了在参数声明中指定数组大小的意义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <stdio.h>

int a[] = {1,2};

void test(int in[3]){
  //
}
 
int main() {
 test(a); 
 return 0;
}

在上面的代码中, int in [3] int * in 相同.数字 3 并没有任何作用,甚至大小都不正确,但是即使编译器也不会抱怨.那么,是否有理由在C语言中接受此语法,或者我缺少功能?

In the above code int in[3] is the same as int *in. The number 3 doesn't really do anything and it's not even the correct size, but even so the compiler doesn't complain. So is there a reason this syntax is accepted in C or I'm missing a functionality?

推荐答案

当数组参数声明包含恒定大小时,它唯一的目的是作为读者的文档,方法是向读者指示该函数期望的数组大小.对于常量表达式 n ,编译器将数组声明(例如 int in [n] )转换为 int * in ,此后没有任何内容.与编译器的差异,因此 n 的值不受任何影响.

When an array parameter declaration contains a constant size, the only purpose it can serve is as documentation for readers, by indicating to them what size array the function expects. For a constant expression n, the compiler converts an array declaration such as int in[n] to int *in, after which there is no difference to the compiler and so nothing is affected by the value of n.

最初在C语言中,函数参数由初始函数声明之后的声明列表指定,例如:

Originally in C, function parameters were specified by a list of declarations after the initial function declaration, such as:

int f(a, b, c)
int a;
float b;
int c[3];
{
    … function body
}

我猜想这些声明中允许使用数组大小​​仅仅是因为它们使用了与其他声明相同的语法.编写排除这些大小的编译器代码和文档要比简单地允许它们出现而忽略它们要困难得多.当引入函数原型中的参数类型声明时( int f(int a,float b,int c [3])),我猜想应用了相同的推理.

I conjecture that array sizes were permitted in these declarations simply because they used the same grammar as other declarations. It would have been harder to write compiler code and documentation that excluded the sizes than to simply allow them to occur but to ignore them. When declaring paramter types inside function prototypes (int f(int a, float b, int c[3])) was introduced, I conjecture the same reasoning applied.

但是:

  • 如果声明包含 static ,如 int in [static n] ,则在调用函数时,相应的参数必须至少指向 n 元素,根据C 2018 6.7.6.3 7.编译器可以使用此元素进行优化.
  • 如果数组大小不是常数,则在调用该函数时,编译器可能会对其进行求值.例如,如果函数声明是 void test(int in [printf("Hi")]),则在调用函数时,GCC 10.2和Apple Clang 11.0都将输出"Hi".(但是,对于我来说,尚不清楚C标准是否需要此评估.)
  • 此调整仅针对实际数组参数发生,而不针对其中的数组进行.例如,在参数声明 int x [3] [4] 中,将 x 的类型调整为 int(*)[4] .4仍然是大小的一部分,并且会影响使用 x 的指针算术.
  • 将参数声明为数组时,元素类型必须完整.相反,声明为指针的参数不必指向完整类型.例如,如果尚未完全定义 struct foo ,但是 struct foo * x 未定义,则 struct foo x [3] 会生成诊断消息.
  • If the declaration contains static, as in int in[static n], then, when the function is called, the corresponding argument must point to at least n elements, per C 2018 6.7.6.3 7. Compilers may use this for optimization.
  • If the array size is not a constant, it may be evaluated by the compiler when the function is called. For example, if the function declaration is void test(int in[printf("Hi")]), then both GCC 10.2 and Apple Clang 11.0 print "Hi" when the function is called. (However, it is not clear to me the C standard requires this evaluation.)
  • This adjustment occurs only for the actual array parameter, not arrays within it. For example, in the parameter declaration int x[3][4], the type of x is adjusted to be int (*)[4]. The 4 remains a part of the size and has effects on pointer arithmetic with x.
  • When a parameter is declared as an array, the element type must be complete. In contrast, a parameter declared as a pointer need not point to a complete type. For example, struct foo x[3] yields a diagnostic message if struct foo has not been fully defined, but struct foo *x does not.

这篇关于在参数声明中指定数组大小的意义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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