c++ - 子数组分配:聚合对象错误预期使用“{...}”进行初始化
问题描述
对第 1 行的错误有什么好的解释?
/* Line 0 */ int foo[10][10];
/* Line 1 */ int foo_alias_compile_error[] = foo[0];
/* Line 2 */ int foo_alias_also_errors[10] = foo[0];
/* Line 3 */ int * foo_alias_works = foo[0];
第 2 行的错误并没有真正困扰我,因为我不需要能够重复自己并重新声明数组的大小。但是,第 1 行的错误(使用聚合对象初始化“{...}”)有点让我困惑。我知道这int foo_alias_compile_error[]
可能是“聚合对象”。我只是不明白为什么语言设置为不起作用。我理解为什么第 3 行有效,但它有点不具代表性——它是一个数组,所以我宁愿将它作为一个数组进行自我记录。
解决方案
人们可能希望将第 1 行视为为foo
. 然而,这不是 C++ 的工作方式。相反,赋值运算符 ( =
) 正在调用复制操作。因此,C++ 将第 1 行解释为将 的元素复制foo[0]
到一个名称不恰当的新数组中的指令foo_alias_compile_error
。
这不是本意——一个人想要一个参考,而不是一个副本。所以,C++ 碰巧因为一个不相关的原因导致了一个错误并从自己那里拯救了一个错误,这很好。
@FrançoisAndrieux 提出了一个可行的解决方案。这是一个更完整的示例,显示可以使用int (&foo_reference)[10] = foo[0];
.
int foo[10][10];
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
foo[i][j] = i + j * 10;
}
}
int (&foo_reference)[10] = foo[0];
for (int j = 0; j < 10; ++j) {
foo_reference[j] = 100 + j;
}
for (int i = 0; i < 10; ++i) {
printf("foo [0][%i] is %i\n", i, foo[0][i]);
printf("foo_refer[%i] is %i\n", i, foo_reference[i]);
}
输出片段
foo [0][0] is 100
foo_alias[0] is 100
foo [0][1] is 101
foo_alias[1] is 101
foo [0][2] is 102
foo_alias[2] is 102
foo [0][3] is 103
foo_alias[3] is 103
边注
值得一提的是,将数组作为参数的函数会隐式地将它们的数组参数转换为指针(如第 3 行所示)。所以,这就是为什么人们可能错误地认为像 Line 1 这样的东西应该工作的原因之一。
换句话说,下面的代码
void barz(int arg[]) {
arg[2] = 99999;
}
int another_array[] = {0, 1, 2, 3, 4};
barz(another_array);
printf("another_array[2] is %i\n", another_array[2]);
“正确”打印99999
,而不是2
.
推荐阅读
- javascript - 如何使用 CSS 或 JavaScript 使新的 Google 搜索看起来像旧的 Google 搜索?
- python - 我正在尝试计算某个值中有多少出现在字典中并将其输出到字典中
- python - Numpy 数组计算问题,int 类型,int32 与 int64
- azure - NotificationHub:有没有办法通过 PushChannel 检索/删除安装?
- woocommerce - Woocommerce 交换公司名称和名称
- ruby - 如何在 Clojure 中读取 Ruby 以 AES 256 CBC 加密的文件/文本
- python - 存储子图的非浪费方式
- python - 不断收到错误消息“已超出未经验证使用的每日限制。继续使用需要注册。”
- javascript - 如何将网站链接添加到随机图像生成器
- python - Azure CLI:UnicodeEncodeError:'ascii'编解码器无法在位置 598 编码字符 u'\u2018':序数不在范围内(128)