通过引用函数实际传递的内容是什么?
void foo(int &a,int &b)
当我写
foo(p,q)
实际传递给函数的是什么。它是p和q的地址吗?
答案 0 :(得分:6)
实际传递给函数的是引用。命名参数b
成为参数对象q
的同义词。
编译器可能如何实现这一点,调用者在调用之前将q
的地址放在堆栈上或寄存器中,并且被调用者使用该值来实现对b
的所有访问。但是将它描述为“实际传递”指针可能会产生误导,因为参数传递是C ++语言级别的概念,并且在该级别它与传递指针的概念不同。例如,当您传递指针时,您可以传递空指针,但是当您传递引用时,您无法(有效地)。所以说他们是一回事是错的。
也就是说,实现编译器的人可能会将其描述为“实际传递指针”,并且您知道它们的含义。为了进行比较,如果char
变量占用调用约定中的4字节堆栈槽,则可能会说编译器“实际传递了一个int”。所以这取决于“实际”应该是什么意思。
答案 1 :(得分:3)
其他答案提到了引用和指针之间的语义差异。
实际上,我曾经使用过的每一个编译器都以相同的方式实现它们 - 传递一个引用实际上是在程序集级别传递一个指针。这在任何标准中都没有规定,在所有地方都是如此。
之前提出的问题是:What's the low-level difference between a pointer an a reference?
答案 2 :(得分:2)
它确实传递了一个引用类型 - 它有点像地址,但并不完全。实际地址是指针。引用不如指针强大,但可以说更安全。 Wikipedia很好地描述了指针和引用之间的差异。
答案 3 :(得分:1)
您正在传递一个引用,它不是指针,而不是地址 - 但它类似。
参考文献的“确切”内容并非一成不变。该标准没有规定处理参考的机制 - 只是使用它们的后果。 通常,它们将被实现为指针。
示例:
int foo(int& a, int& b) { a = b; }
// Usage
int x, y;
foo(x, y);
这可能会生成相同的机器代码:
int foo(int* a, int* b) { *a = *b; }
// Usage
int x, y;
foo(&x, &y);
但是不能保证这一点,并且两者不相同(尽管它们提供类似的功能)。
当您获取引用的地址时,您将获得与其引用的对象相同的地址。例如:
void foo(int& x) { std::cout << &x << std::endl; }
int y;
std::cout << &y << std::endl;
foo(); // This will print the same as above.
答案 4 :(得分:0)
通过引用传递的方式由编译器定义。无论如何,它们都以int&
传递,这是C ++中的实际类型。试试这个:
int x = 10;
int& y = x;
x = 100;
您认为y的价值是什么?引用不是指针,而是变量的别名。您的编译器应用于int&
的相同机制用于通过引用参数传递。
鉴于以下计划:
void byRef(int& x)
{
return;
}
void byVal(int x)
{
return;
}
void byPtr(int * x)
{
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 0;
byRef(x);
byVal(x);
byPtr(&x);
return 0;
}
为byRef
和byPtr
电话生成的MSVC90程序集完全相同:
lea eax, [x]
push eax
call byRef ;or byPtr
add esp, 4