作为函数参数的大小数组的目的是 C 和 C++?

What is the purpose of sized array as function argument is c and c++?

考虑以下函数:

void func1(int unsized_array[]){}
void func2(int sized_array[10]){}
void func3(int *pointer){}

根据以下结果:

    std::cout << std::is_same<decltype(func1), decltype(func2)>::value << std::endl;
    std::cout << std::is_same<decltype(func2), decltype(func3)>::value << std::endl;
    std::cout << std::is_same<decltype(func3), decltype(func1)>::value << std::endl;

这3个函数的类型是一样的。同样在函数内部func2sizeof运算符没有提供数组元素全部合并的大小。

那么大小数组作为函数参数(如 func2)的目的是什么?

  1. 因为数组声明符通常可能有大小表达式(如定义数组而不是在参数中或声明包含数组作为子部分的参数时,例如指向array),将它从语法中排除比将它无害地留在其中需要更多的工作。 (C 中有许多结构可以产生无效果,例如没有副作用的语句表达式 (3*4;)、没有副作用的逗号表达式的左操作数、具有空值的函数或循环body, 等等。要排除对语言没有影响的东西需要做很多工作。)

  2. 参数中的数组大小确实会在 static 关键字出现时改变其含义; void func2(int asd[static 10]) 声明一个函数,该函数必须传递指向至少十个元素中第一个元素的指针,这与其他声明的含义不同。 (这会使从数组参数声明的语法中排除大小表达式的问题更加复杂,因为有必要禁止裸大小而不是带有 static 的大小。)

  3. 数组大小可能是对函数实现者和函数用户有用的文档。

  4. 计算数组大小。例如,如果定义为 void func2(int asd[printf("Hello")]) {},那么在调用该函数时将打印“Hello”。 (一些编译器可能不会这样做;C 标准对此不明确。)

  5. 如果编译器发现函数使用的元素数量多于规定的元素数量或调用者传递的元素数量少于规定的数量,则编译器可以使用大小表达式发出警告。 (除非使用 static,否则 Clang 11 似乎不执行前者也不执行后者。)

没有任何意义,因为它们都腐烂为同一类型,正如您正确识别的那样。对于 C++,此行为继承自 C。

就像将 const 添加到非引用参数和其他关键字不会改变任何外部内容一样,它们都会导致 void(int) 签名。

void foo1(int a) {}
void foo2(const int a) {}
void foo3(volatile int a) {}

但是您可以得到一些实际有效的东西,而不是 int[10]

void func2(int(&asd)[10]) {}

这将只接受大小为 10 的 int 数组。您现在还可以使用 sizeof 在编译时获取数组大小,这对于 int[10] 是不可能的显然。