在c ++入门书中,本书说的是当参考初始化时,它无法改变。但我发现了一个问题,这里是编码:
int a[]={1,2,3,4};
for(auto &c:a)cout<<c;
然后,输出是a的元素。但是c是这里的引用,为什么它可以与数组的不同元素绑定?我不明白。
答案 0 :(得分:2)
参考不会被反弹。相反,在循环的每次迭代中都会初始化一个新引用。
你的书应该提到这是一个基于范围的 for
循环,如果我正在写它,我只会在之前涵盖标准{{ 1}}循环,其中迭代数组的代码将写为:
for
正如您所看到的,远程版本只是一种更方便和可读的方式来迭代一系列值(因此名称)。在这里,您将遍历int a[]={1,2,3,4};
for (int i = 0; i < 4; ++i) cout << a[i];
数组的所有元素。
在&#34; classic&#34;版本,您使用索引进行迭代。在远程版本中,所有发生的事情都是a
在每次迭代时被绑定为c
的引用。
对于它的价值,原因为什么引用无法改变/反弹只是因为语言的设计方式。这是区分引用和指针的主要功能之一。
答案 1 :(得分:2)
参考没有反弹;每次迭代都会创建一个新引用。代码:
int a[]={1,2,3,4};
for(auto &c:a)cout<<c;
实际上相当于:
int a[]={1,2,3,4};
for (auto _i = std::begin(a), _e = std::end(a); _i != _e; ++_i) {
auto &c = *_i;
cout << c;
}
(变量_i
和_e
是匿名的,编译器生成的详细信息,您无法直接访问。)
请注意,c
在每次迭代结束时超出范围,并在下一次迭代时返回到范围内,并带有新的绑定引用。
答案 2 :(得分:2)
基于范围的循环在这方面略显混乱(尽管意图通常更清晰)。
您可能会合理地认为:
for(auto &c:a)
应该等同于:
for (auto &c = /*something*/; c != /*something*/; ++c)
但它不是 - 正如你所说的那样,它不可能,因为这会改变引用a
所指的c
的哪个元素...每次循环。
它实际上转换为:
for (auto _iter = std::begin(a); _iter != std::end(a); ++_iter)
{
auto &c = *_iter;
// your loop body goes here
}
其中_iter
是隐藏变量的占位符,您无法真正访问(我只是展示它以说明实际发生的事情)。
现在,在这段代码中,应该清楚的是,每次输入循环体时,都会为当前元素创建一个新的本地引用 - 它恰好每次都被称为c
,但它&#39 ; s总是不同的c
。
答案 3 :(得分:1)
由于缺乏允许它的语法,参考文献无法发生重大变化:
int A = 1;
int B = 2;
int&C = A;
C = B;
最后一行不能使C成为B的引用;它实际上将A设置为2。
现在,我确定设计师是否真的想要,他们可以添加一种语法来重置引用 - 但是,不需要这样的功能,因此它从未添加过。