在声明以外的时间初始化C数组?
我在C中知道我可以做到以下几点。
int test[5] = {1, 2, 3, 4, 5};
现在,这在声明数组时才合法。 但是我想知道为什么以后这样做不合法? 但是后来在该计划中,执行以下操作是不合法的。
test[5] = {10, 20, 30, 40, 50};
或类似的东西。 为什么是这样? 我知道这不合法,我不是在抱怨,但有人可以给我一个更技术性的解释,为什么我不能这样做? (即不要只说C规范不允许它或类似的东西)
我假设它必须对内存在数组的堆栈上分配的时间做一些事情,所以在那一点C可以自动填充我的值,但那么为什么它不能在以后呢?
多谢你们
它不仅仅是数组,除了定义之外,你不能为任何点提供初始值。 人们有时会提到像int i; i = 0;
这样的第二个陈述int i; i = 0;
int i; i = 0;
作为“初始化i
”。 实际上它正在分配给i
,它之前保存了一个不确定的值,因为它没有被初始化。 称这种“初始化”很少令人困惑,但就语言而言,那里没有初始化器。
赋值和初始化是与语言不同的东西,即使它们都使用=
字符。 数组不可分配。
数组不可分配的原因在其他地方有所涉及,例如为什么C ++支持在结构中成员分配数组,但一般不支持? 。 简短的回答是“历史原因”。 我不认为为什么语言无法更改以允许数组赋值有任何技术上的原因。
还有一个次要问题,语法上{1, 2, 3, 4, 5}
是一个初始化器,而不是数组文字,因此即使数组是可分配的,也不能用于赋值。 我不确定C89为什么没有数组文字,可能只是没有人需要它们。 C99通常引入“复合文字”的语法,特别是数组文字: (int[]) {1, 2, 3, 4, 5}
。 您仍然无法从中分配数组。
关键是使用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;
希望这是有道理的。 只是语法问题。
请注意,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... }
这与重新初始化具有不同值的数组不同,但它可能足够接近它适合您。
这是解决方案
//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
表面上的原因是数组几乎到处都转换为指向第一个元素的指针。 如果你有两个数组
double A[5]; double B[5];
在诸如的表达中
A = B;
两者都已转换为指针。 左边的A
特别不是“左值”,因此您无法分配它。
这听起来像是一个蹩脚的借口,但我的猜测是,从历史上看,它就是这样发生的。 C(和它带有C ++)被困在早期的语法选择中,如果你想保持与遗留代码的兼容,那么可能没有多少办法。