在声明以外的时间初始化C数组?

时间:2012-03-05 15:02:02

标签: c arrays initialization

我在C中知道我可以做到以下几点。

int test[5] = {1, 2, 3, 4, 5};

现在这在声明数组时才合法。但是我想知道为什么以后这样做不合法?但是后来在程序中执行以下操作是不合法的。

test[5] = {10, 20, 30, 40, 50}; 

或类似的东西。为什么是这样?我知道这不合法,我不是在抱怨,但有人可以给我一个更技术性的解释,说明为什么我不能这样做? (即不要只说C规范不允许它或类似的东西)

我假设它必须对内存在数组的堆栈上分配的时间做一些事情,所以在这一点上C可以自动填充我的值,但是为什么以后不能这样做呢? / p>

谢谢你们

5 个答案:

答案 0 :(得分:19)

这不仅仅是数组,你不能在定义之外的任何地方为任何提供初始化程序。人们有时会将int i; i = 0;之类的第二个陈述称为“初始化i”。事实上,它正在分配给i,它之前保存了一个不确定的值,因为它没有被初始化。称这种“初始化”很少令人困惑,但就语言而言,那里没有初始化器。

分配和初始化是与语言不同的东西,即使它们都使用=字符。数组不可分配。

数组不可分配的原因在其他地方有所涉及,例如Why does C++ support memberwise assignment of arrays within structs, but not generally?。简短的回答是“历史原因”。我不认为为什么语言无法更改以允许数组赋值有任何技术上的原因。

有一个次要问题,语法上{1, 2, 3, 4, 5}是一个初始化器,而不是数组文字,因此即使数组是可分配的,也不能用于赋值。我不确定为什么C89没有数组文字,可能只是没有人需要它们。 C99通常引入“复合文字”的语法,特别是数组文字:(int[]) {1, 2, 3, 4, 5}。您仍然无法从中分配数组。

答案 1 :(得分:6)

关键是使用int array[]={ } 声明初始化您已创建的对象。

之后

int array[5];
array[0] = 1, array[1] = 2, ...

您正在做的是将几个值分配给一个单个数组条目:

array[5] = {1,2,3,4,5}; // array[5] can only contain one value

这是合法的:

array[5] = 6;

希望这是有道理的。只是语法问题。

答案 2 :(得分:3)

请注意,C99复合文字允许您“将数组传递给函数”:

int your_func(int *test)
{
    ...use test as an array...
}

void other_func(void)
{
    int x = rand();
    if (your_func((int[]){ 0, 1, 2, x, 3, 4 }) > 0 ||
        your_func((int[]){ 9, x, 8, 7, 6, 5 }) > 0)
        ...whatever...
}

这与重新初始化具有不同值的数组不同,但它可能足够接近它适合您。

答案 3 :(得分:3)

以下是解决方案

//Declaration
int a[5];
int a_temp[5] = {1, 2, 3, 4, 5 };
memcpy(a, a_temp, sizeof(a));
//Now array a have values 1, 2, 3, 4, 5

答案 4 :(得分:0)

表面上的原因是数组几乎无处不在地转换为指向第一个元素的指针。如果你有两个数组

double A[5];
double B[5];

中的表达式

A = B;

两者都已转换为指针。左侧的A特别不是“左值”,因此您无法分配给它。

这听起来像是一个蹩脚的借口,但我的猜测是,从历史上看,它就是这样发生的。 C(以及带有它的C ++)被困在早期的语法选择中,如果你想与遗留代码保持兼容,那么可能没有太多的方法。

相关问题