C++:函数/方法声明中与号“&”和星号“*”之间的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/596636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++: difference between ampersand "&" and asterisk "*" in function/method declaration?
提问by Slava V
Is there some kind of subtle difference between those:
它们之间是否存在某种微妙的区别:
void a1(float &b) {
b=1;
};
a1(b);
and
和
void a1(float *b) {
(*b)=1;
};
a1(&b);
?
?
They both do the same (or so it seems from main() ), but the first one is obviously shorter, however most of the code I see uses second notation. Is there a difference? Maybe in case it's some object instead of float?
他们都做同样的事情(或者从 main() 看来是这样),但第一个显然更短,但是我看到的大部分代码都使用第二个符号。有区别吗?也许万一它是某个对象而不是浮动?
采纳答案by Brian R. Bondy
Both do the same, but one uses references and one uses pointers.
两者都做同样的事情,但一个使用引用,一个使用指针。
See my answer here for a comprehensive list of all the differences.
回答by Charlie Martin
Yes. The *
notation says that what's being pass on the stack is a pointer, ie, address of something. The &
says it's a reference. The effect is similar but not identical:
是的。该*
符号表示传递到堆栈上的是一个指针,即某物的地址。该&
说这是一个参考。效果相似但不完全相同:
Let's take two cases:
我们来看两个案例:
void examP(int* ip);
void examR(int& i);
int i;
If I call examP
, I write
如果我打电话examP
,我写
examP(&i);
which takes the address of the item and passes it on the stack. If I call examR
,
它获取项目的地址并将其传递到堆栈上。如果我打电话examR
,
examR(i);
I don't need it; now the compiler "somehow" passes a reference -- which practically means it gets and passes the address of i
. On the code side, then
我不需要它;现在编译器“以某种方式”传递了一个引用——这实际上意味着它获取并传递i
. 在代码方面,然后
void examP(int* ip){
*ip += 1;
}
I have to make sure to dereference the pointer. ip += 1
does something very different.
我必须确保取消引用指针。 ip += 1
做一些非常不同的事情。
void examR(int& i){
i += 1;
}
always updates the value of i
.
总是更新 的值i
。
For more to think about, read up on "call by reference" versus "call by value". The &
notion gives C++ call by reference.
要了解更多信息,请阅读“按引用调用”与“按值调用”。这个&
概念通过引用给出了 C++ 调用。
回答by Greg Hewgill
In the first example with references, you know that b
can't be NULL. With the pointer example, b
might be the NULL pointer.
在第一个带有引用的示例中,您知道它b
不能为 NULL。对于指针示例,b
可能是 NULL 指针。
However, note that it ispossible to pass a NULL object through a reference, but it's awkward and the called procedure can assume it's an error to have done so:
但是,请注意,这是可以通过引用传递一个空对象,但它的尴尬和被调用过程可以认为这是一个错误已经这样做了:
a1(*(float *)NULL);
回答by finnw
In the second example the callerhas to prefix the variable name with '&' to pass the address of the variable.
在第二个示例中,调用者必须在变量名前加上“&”以传递变量的地址。
This may be an advantage - the caller cannot inadvertently modify a variable by passing it as a reference when they thought they were passing by value.
这可能是一个优势 - 当调用者认为他们是按值传递时,他们不会无意中通过将变量作为引用传递来修改变量。
回答by jmucchiello
Aside from syntactic sugar, the only real difference is the ability for a function parameter that is a pointer to be null. So the pointer version can be more expressive if it handles the null case properly. The null case can also have some special meaning attached to it. The reference version can only operate on values of the type specified without a null capability.
除了语法糖之外,唯一真正的区别是作为指针的函数参数能够为空。因此,如果指针版本正确处理空情况,则它可以更具表现力。null case 也可以附加一些特殊的含义。参考版本只能对没有空功能的指定类型的值进行操作。
回答by Johannes Schaub - litb
Functionally in your example, both versions do the same.
在您的示例中,两个版本的功能相同。
The first has the advantage that it's transparent on the call-side. Imagine how it would look for an operator:
第一个的优点是它在呼叫方是透明的。想象一下它会如何寻找运算符:
cin >> &x;
And how it looks ugly for a swap invocation
以及交换调用看起来如何丑陋
swap(&a, &b);
You want to swap a and b. And it looks much better than when you first have to take the address. Incidentally, bjarne stroustrup writes that the major reason for references was the transparency that was added at the call side - especially for operators. Also see how it's not obvious anymore whether the following
你想交换 a 和 b。它看起来比您第一次必须获取地址时要好得多。顺便说一句,bjarne stroustrup 写道,引用的主要原因是在呼叫端添加的透明度 - 特别是对于操作员。也看看下面是否不再明显
&a + 10
Would add 10 to the content of a, calling the operator+ of it, or whether it adds 10 to a temporary pointer to a. Add that to the impossibility that you cannot overload operators for only builtin operands (like a pointer and an integer). References make this crystal clear.
将向 a 的内容添加 10,调用它的 operator+,或者是否将 10 添加到指向 a 的临时指针。再加上您不能只为内置操作数(如指针和整数)重载运算符的可能性。参考资料清楚地说明了这一点。
Pointers are useful if you want to be able to put a "null":
如果您希望能够放置“null”,则指针很有用:
a1(0);
Then in a1 the method can compare the pointer with 0 and see whether the pointer points to any object.
然后在 a1 中,该方法可以将指针与 0 进行比较,并查看指针是否指向任何对象。
回答by RnR
One big difference worth noting is what's going on outside, you either have:
值得注意的一大区别是外面发生了什么,你要么有:
a1(something);
or:
或者:
a1(&something);
I like to pass arguments by reference (always a const one :) ) when they are not modified in the function/method (and then you can also pass automatic/temporary objects inside) and pass them by pointer to signify and alert the user/reader of the code calling the method that the argument may and probably is intentionally modified inside.
我喜欢通过引用传递参数(总是一个常量 :) )当它们在函数/方法中没有被修改(然后你也可以在里面传递自动/临时对象)并通过指针传递它们以表示和提醒用户/调用方法的代码的读者,参数可能并且可能在内部被有意修改。