没有大小的C数组定义是什么意思?

mm5n2pyu  于 2023-04-19  发布在  其他
关注(0)|答案(5)|浏览(169)

示例:

int main()
{
    int array[];
}

它只是一个未初始化的指针吗?还是一个默认大小很小的数组?
哪些编译器支持这种语法,为什么?我认为这是一个混乱的处方。
这里还提到:
Can I declare an array in C without declaring its size and element?

gfttwv5a

gfttwv5a1#

为了使这个声明有效,需要存在一个初始化器列表:
int array[] = { ... }; .
否则数组 * 不完整 *,C176.7.6.2:
如果不存在大小,则数组类型是不完整类型。
局部作用域中不完整的数组类型不是有效的声明,符合条件的编译器将引发诊断消息。不完整的数组类型仅在某些特殊情况下允许:

  • 函数声明可能包含不完整的数组类型,因为它被调整为指向第一个元素的指针。调整后,数组不应该有不完整的类型(也不是具有不完整元素类型的数组类型)。

因此,void func (int array[])是有效的,并且等价于void func (int* array)

  • struct的最后一个成员可以是不完整的数组类型,即所谓的 * 灵活数组成员 *。
  • 作为在任何函数之外声明的文件作用域数组,其类型稍后在同一转换单元中完成,或者当它具有外部链接(extern等)时,引用另一转换单元中的数组。
u3r8eeie

u3r8eeie2#

正如其他答案所指出的,在这种情况下,代码在C中是非法的。
但是,如果声明包括初始化,则数组具有适当的大小:

int array[] = {10, 20, 30}; // array has size 3

一个特殊的情况是初始化为空:

int array[] = {}; // array has size 0

在这种情况下,数组的大小为0。这在C中是不允许的,但有些编译器支持这种情况。

int main()
{
    int array[] = {};
    printf("%zu", sizeof(array));
}

gcc编译:OK,打印0
gcc -pedantic编译:错误:零或负大小数组
由MS Visual Studio编译:错误:无法分配常量大小为0的数组
大小为零的数组大多是无用的;它提供了与灵活数组成员相同的功能,但它是非标准的-仅支持与一些旧代码的兼容性。

c8ib6hqw

c8ib6hqw3#

代码中出现的int array[];结构(换句话说:作为独立数组)在C中是非法的。
假设它是法律的的:

**Q:**是否只是一个未初始化的指针?
**A:**数组不是指针。如果这样的声明是法律的的,它将是一个大小为零的数组。如果你将array分配给指针,指针将指向大小为0的内存段。顺便说一下,后者实际上可以通过使用malloc(0)来实现,但这是另一回事。
**Q:**是否为默认大小较小的数组?
**A:*C中没有默认大小。顺便问一下, 默认大小 * 是什么?
**Q:**哪些编译器支持这种语法,为什么?
**A:**AFAIK没有健全的C编译器支持这一点有一个很好的理由。

ao218c7q

ao218c7q4#

int array[];使用不完整的数组类型声明array
在函数内部(即在 block scope),不允许声明未声明为extern的变量,并且没有初始化器,但声明了不完整的数组类型。
函数外部(即在 * 文件范围 *),允许声明未声明为extern且没有初始化器但使用不完整数组类型声明的变量作为变量的 * 临时定义 *。如果变量的类型在转换单元结束时仍然不完整(即在本汇编结束时),它将被 * 隐式初始化 *,初始化器{0}使它有一个元素(但它的大小不能用sizeof来测量,因为在使用sizeof的地方类型仍然不完整)。

mwyxok5s

mwyxok5s5#

我认为这是一个混乱的处方
这正是为什么在语言中设计不允许这样做的原因。所以没有编译器会支持这种情况。数组的大小必须通过在数组声明中提供大小来知道,或者通过立即初始化来导出大小。
https://en.cppreference.com/w/cpp/language/array#Arrays_of_unknown_bound

相关问题