这些之间是否存在某种微妙的差异:
void a1(float &b) {
b=1;
};
a1(b);
和
void a1(float *b) {
(*b)=1;
};
a1(&b);
它们都是相同的(或者看起来似乎来自main()),但第一个显然更短,但我看到的大多数代码都使用第二种表示法。有区别吗?也许万一它是一些对象而不是浮动?
答案 0 :(得分:51)
两者都是一样的,但是一个使用引用,一个使用指针。
See my answer here for a comprehensive list of all the differences。
答案 1 :(得分:23)
是。 *
符号表示堆栈上传递的是指针,即某些地址。 &
表示它是一个参考。效果相似但不完全相同:
我们来看两个案例:
void examP(int* ip);
void examR(int& i);
int i;
如果我致电examP
,我会写
examP(&i);
获取项目的地址并将其传递到堆栈中。如果我拨打examR
,
examR(i);
我不需要它;现在编译器“以某种方式”传递一个引用 - 这实际上意味着它获取并传递i
的地址。在代码方面,然后
void examP(int* ip){
*ip += 1;
}
我必须确保取消引用指针。 ip += 1
做了一些非常不同的事情。
void examR(int& i){
i += 1;
}
始终更新i
。
如需了解更多信息,请阅读“按引用致电”与“按价值分配”。 &
概念通过引用提供C ++调用。
答案 2 :(得分:5)
在带引用的第一个示例中,您知道b
不能为NULL。使用指针示例,b
可能是NULL指针。
但是,请注意 可以通过引用传递NULL对象,但它很笨拙,被调用的程序可以认为这样做是错误的:
a1(*(float *)NULL);
答案 3 :(得分:3)
在第二个示例中,调用者必须在变量名前加上“&”传递变量的地址。
这可能是一个优点 - 调用者不会无意中修改变量,方法是在他们认为变量超过值时将其作为引用传递。
答案 4 :(得分:3)
除了语法糖之外,唯一真正的区别是函数参数是指针为null的能力。因此,如果指针版本正确处理空案例,则它可以更具表现力。 null case也可以附加一些特殊含义。参考版本只能在没有null功能的情况下对指定类型的值进行操作。
答案 5 :(得分:1)
在您的示例中,两个版本的功能相同。
第一个优点是它在呼叫方面是透明的。想象一下它如何寻找运营商:
cin >> &x;
交换调用看起来很丑陋
swap(&a, &b);
您要交换a和b。它看起来比你第一次拿地址好多了。顺便说一句,bjarne stroustrup写道,引用的主要原因是在呼叫方面增加了透明度 - 特别是对于运营商而言。另外看看它是否不再明显是否如下
&a + 10
将a的内容添加10,调用它的运算符+,或者是否将10添加到指向a的临时指针。添加它是不可能的,你不能只为内置操作数(如指针和整数)重载运算符。参考文献清楚地说明了这一点。
如果您希望能够设置“null”,则指针非常有用:
a1(0);
然后在a1中,该方法可以将指针与0进行比较,并查看指针是否指向任何对象。
答案 6 :(得分:0)
值得注意的一个重要区别是外面发生了什么,你要么:
a1(something);
或:
a1(&something);
我喜欢通过引用传递参数(总是一个常量:) :)当它们没有在函数/方法中修改时(然后你也可以在里面传递自动/临时对象)并通过指针传递它们来表示和警告代码的用户/读者调用参数可能并且可能在内部有意修改的方法。