C++ 通过引用传递的不一致性-这个通过引用传递的简单示例是如何工作的?

C++ 通过引用传递的不一致性-这个通过引用传递的简单示例是如何工作的?,c++,function,parameter-passing,C++,Function,Parameter Passing,我有一个简单的问题,希望通过引用传递背后的潜在逻辑 这里有一个代码(我们称之为代码1): void fn(内部和外部) { a=6; } int main() { int b=5; fn(b); cout对于大多数意图和目的,引用只是一个伪装的指针。不同的语法,效果(大部分)相同。对于大多数意图和目的,引用只是伪装的指针。不同的语法,效果(大部分)相同。在此函数中: void fn(int &a) { a=6; } 术语“&a”并不意味着“变量a”的地址。它意味着“一个称为a”的引用。

我有一个简单的问题,希望通过引用传递背后的潜在逻辑

这里有一个代码(我们称之为代码1):

void fn(内部和外部)
{
a=6;
}
int main()
{
int b=5;
fn(b);

cout对于大多数意图和目的,引用只是一个伪装的指针。不同的语法,效果(大部分)相同。

对于大多数意图和目的,引用只是伪装的指针。不同的语法,效果(大部分)相同。

在此函数中:

void fn(int &a) {
a=6;
}
术语“&a”并不意味着“变量
a
”的地址。它意味着“一个称为
a
”的引用。代码1和代码2实际上是相同的(但请注意,代码2中的函数可以传递一个无效指针,这对于代码1来说(几乎)是不可能的)。

在该函数中:

void fn(int &a) {
a=6;
}

术语“&a”并不意味着“变量
a
”的地址。它意味着“一个称为
a
”的引用。代码1和代码2实际上是相同的(但请注意,代码2中的函数可以传递一个无效指针,这对于代码1来说(几乎)是不可能的).

从概念上讲,在第一种情况下,同一变量有两个标签:
b
,在
main()
范围内可见;和
a
,在
fn
范围内可见

您不必担心编译器在“幕后”如何实现这个概念

<>如果你在精神上促进编译器的“幕后”动作,来真正地想象C++的原理,例如“引用是伪装的指针”,那么它会让你对什么是一个非常简单的概念感到困惑:给变量赋予多个名字。 作为函数参数没有什么特别之处;例如,您可以在
main()中编写:

这完全等同于:

int c;
int &a = c;

在这两种情况下,都有一个带有两个标签的
int
变量,
a
c

从概念上讲,在第一种情况下,相同的变量有两个标签:
b
,在
main()
范围内可见;和
a
,在
fn
范围内可见

您不必担心编译器在“幕后”如何实现这个概念

<>如果你在精神上促进编译器的“幕后”动作,来真正地想象C++的原理,例如“引用是伪装的指针”,那么它会让你对什么是一个非常简单的概念感到困惑:给变量赋予多个名字。 作为函数参数没有什么特别之处;例如,您可以在
main()中编写:

这完全等同于:

int c;
int &a = c;

在这两种情况下,都有一个带有两个标签的
int
变量,
a
c

您想要引用的唯一原因是a)指针通常过于通用和强大,b)我们喜欢语法糖。让编译器来阻止理解指针的沉重负担。@Deduplicator我从来没有买过参数a。这会使poiNTER看起来像黑魔法,不鼓励学习它们。如果您实际上不需要对指针本身执行算术运算,它将消除一个概念级别的间接寻址。对于大约4-5颗星,您应该对此表示感谢……否则,这肯定只是为了糖。@重复数据消除器您可能希望在di上指向不同的对象不同的时间。@deplicator你说过,如果你不需要执行指针运算,这只适用于sugar。但是如果你想用同一个指针指向不同的对象,你也需要一个指针。引用不能被重置。你想要引用的唯一原因是a)指针通常过于通用和强大,b)我们喜欢语法上的sugar。让编译器来阻止理解指针的沉重负担。@Deduplicator我从来没有买过参数a。它使指针看起来像是黑魔法,不鼓励学习它们。如果你实际上不需要对指针本身执行算术,它消除了一个概念级别的间接寻址。大约4-5星,你应该感谢对于这一点……否则,它肯定只适用于sugar。@重复数据消除程序您可能需要在不同的时间指向不同的对象。@重复数据消除程序您说过,如果您不需要执行指针算术,它只适用于sugar。但如果您要用同一指针指向不同的对象,您也需要一个指针。引用无法重置“对于代码1来说这(几乎)是不可能的”,这主要是语义上的区别。所有编译器都将引用作为下面的指针来实现,如果您有一个类似于void fn2(int*a){fn(*a);}的函数,它将编译此函数,只需将地址传递出去,而不需要“取消引用”。因此,有效地传递无效引用就像传递无效指针一样容易。语言纯粹主义者会说,无效指针上的解引用表达式是未定义的行为,因此后面的任何内容都没有意义。但这只是一个学术术语,程序员看不到。“这(几乎)不可能用于代码1”这主要是语义上的区别。所有编译器都将引用作为下面的指针来实现,如果您有一个类似
void fn2(int*a){fn(*a);}
的函数,它将编译此函数,只需传递地址,而不需要“取消引用”。因此,有效地传递无效引用就像传递无效指针一样容易。语言纯粹主义者会说,无效指针上的解引用表达式是未定义的行为,因此后面的任何内容都没有意义。但这只是一个学术术语,程序员看不到。
int a;
int &c = a;
int c;
int &a = c;