【发布时间】:2016-10-06 02:51:54
【问题描述】:
下面是 written 添加花哨的 * 星形语法以在函数原型中声明数组类型的基本原理 - 只是在我们进入问题之前进行澄清:
函数原型可以有可变长度的参数 使用特殊语法的数组类型(第 6.7.5.2 节),如
int minimum(int,int [*][*]);这个名字和其他C原型一致 不需要指定参数。
但我非常有信心,我们可以通过仅使用像这样的未指定大小的普通数组来获得相同的效果(这里重写上面引用中给出的名为 minimum 的函数示例,我完全相信相同的功能(除了使用size_t 而不是int 作为第一个参数,这在这种情况下并不重要):
#include <stdio.h>
int minimum(size_t, int (*)[]);
int (main)()
{
size_t sz;
scanf("%zu", &sz);
int vla[sz];
for(size_t i = 0; i < sz; ++i)
vla[i] = i;
minimum(sizeof(vla) / sizeof(*vla), &vla);
int a[] = { 5, 4, 3, 2, 1, 0 };
minimum(sizeof(a) / sizeof(*a), &a);
}
int minimum(size_t a, int (*b)[a])
{
for(size_t i = 0; i < sizeof(*b) / sizeof(**b); ++i)
printf("%d ", (*b)[i]);
return printf("\n");
}
因为我很确定标准中的某个地方指出 2 个数组只有在它们的大小相等时才兼容,而不管它们是否可变。
我的观点也得到证实,minimum 定义不会抱怨“冲突类型”,因为它的某些参数具有不兼容的类型(我认为两者都不是这样)这些数组的大小在编译时未指定 - 我指的是 minimum 的第二个参数。
除此之外,你能指出一个[*] 的单个用例,不能用普通的未指定大小的数组替换吗?
使用 clang 和 gcc 编译上述代码时没有任何警告。它还会产生预期的输出。
对于任何不了解 C 的人(或任何认为他/她知道 C 的人)- 类型数组的函数参数被隐式转换为“指向其元素类型的指针”。所以这个:
int minimum(int,int [*][*]);
调整为:
int minimum(int,int (*)[*]);
然后我认为它也可以写成:
int minimum(int,int (*)[]);
没有任何后果,并且具有与上述 2 种形式相同的行为。从而使[*] 表格过时。
【问题讨论】:
-
int (*)[]不是 VLA。你得到哪个编译器错误?您是否尝试过至少编译?你想说啥?看起来像是讨论的开始。这不是讨论论坛。 -
@Olaf 我要求一个用例,其中函数原型的星形数组语法不能使用未指定大小的普通数组替换。是的,
int (*)[]不是 VLA,但你的意思是什么? -
@Olaf 我知道我指的是在函数原型中声明具有未指定大小的 VLA 时的语法。在咆哮之前最好先阅读我的整个问题。
-
请提供minimal reproducible example 您的意思。您的代码中没有使用
[*][*]的工作示例。如果您的编译器出现问题,请再次非常仔细地阅读标准。 (它遵循相同的正确逻辑,例如将数组转换为函数参数的“指向第一个元素的指针”。 -
@Olaf 我相信所需要的一切都已经在问题中了。
[*][*](或者更确切地说是(*)[],[][]在这种情况下)的“工作”示例已经存在,我只是在问我为什么要使用[*][*]或(*)[*]代替。跨度>
标签: c arrays language-lawyer c99