2014-03-30 93 views
0

我有一个简单的问题,并希望通过引用传递背后的基础逻辑。通过引用传递的不一致性 - 通过引用传递的这个简单示例如何工作?

这里有一个代码(姑且称之为代码1):

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

int main() 
{ 
    int b = 5; 
    fn(b); 
    cout << b; 
} 

这里的另一个代码(代码2):

void fn(int* ptr) 
{ 
    *ptr = 6; 
} 

int main() 
{ 
    int b = 5; 
    fn(&b); 
    cout << b; 
} 

,按价值计算码通(代码3):

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

int main() 
{ 
    int b = 5; 
    fn(b); 
    cout << b; 
} 

这里是我的问题。直观上,我发现在传递值(Code3)的同时,这些值被复制,即只需要将自己的值复制到b。因此,作为一般规则,我发现传递的值总是被复制到被调用的函数(这里是fn)。即使使用指针代码(即Code2)Code 2的第一行确保int *ptr = &a;

我不明白这将如何在Code1中工作。说&a = b是没有意义的。这是一个例外,还是这符合与上述段落中讨论的情况一致的规则?

谢谢!

回答

2

在这个函数:

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

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

+0

“,这对代码1来说(几乎)是不可能的”这基本上是一种语义上的区别。所有的编译器都在下面实现引用作为指针,如果你有像'void fn2(int * a){fn(* a); }',它会编译这个函数,只是简单地传递地址,而不是“解除引用”。所以*有效*你可以像传递一个无效指针那样容易地传递一个无效的引用。一个语言纯粹主义者会说无效指针的解引用表达是未定义的行为,所以之后的任何东西都是没有意义的。但这只是一个学术技术性问题,对程序员来说是不可见的。 – newacct

2

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

+0

你想要引用的唯一原因是a)指针通常太过泛泛和强大,b)我们喜欢语法糖。让编译器消除理解指针的沉重负担。 – Deduplicator

+0

@Deduplicator我从来没有买过参数a。它使得指针看起来像是黑暗的魔法,并且阻止了解它们。 –

+0

如果您实际上不需要对指针本身执行算术运算,则会消除一个间接概念级别。在大约4-5星的时候,你应该为此感谢......否则,它肯定只有糖。 – Deduplicator

0

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

您不必担心编译器在“幕后”执行此概念的功能。

如果您从心理上推动编译器的“幕后”操作,以真正成为C++的想象原则, “引用是伪装的指针”,那么它会让你对实际上是一个非常简单的概念感到困惑:给变量赋予多个名字的能力。

作为函数参数没什么特别的;例如你可以在main()写:

int a; 
int &c = a; 

这是完全等同于:

int c; 
int &a = c; 

在这两种情况下,有一个int变量有两个标签,ac