指针变量和引用变量之间的区别是什么?
当前回答
除非我需要以下任何一项,否则我会使用参考资料:
空指针可以用作哨兵价值,通常是一种廉价的方式避免函数重载或使用嘘声。你可以在指针上做算术。例如,p+=偏移量;
其他回答
我对引用和指针有一个类比,将引用看作对象的另一个名称,将指针看作对象的地址。
// receives an alias of an int, an address of an int and an int value
public void my_function(int& a,int* b,int c){
int d = 1; // declares an integer named d
int &e = d; // declares that e is an alias of d
// using either d or e will yield the same result as d and e name the same object
int *f = e; // invalid, you are trying to place an object in an address
// imagine writting your name in an address field
int *g = f; // writes an address to an address
g = &d; // &d means get me the address of the object named d you could also
// use &e as it is an alias of d and write it on g, which is an address so it's ok
}
塔林♦ 说:
不能像使用指针那样获取引用的地址。
事实上你可以。
我引用了另一个问题的答案:
C++常见问题解答说得最好:与指针不同,一旦引用绑定到对象,就不能将其“重新放置”到另一个对象。引用本身不是一个对象(它没有标识;获取引用的地址可以获得引用的地址;记住:引用是它的引用)。
什么是C++参考(针对C程序员)
引用可以被视为具有自动间接寻址的常量指针(不要与指向常量值的指针混淆!),即编译器将为您应用*运算符。
所有引用都必须使用非空值初始化,否则编译将失败。既不可能获得引用的地址——地址运算符将返回被引用值的地址——也不可能对引用进行算术运算。
C程序员可能不喜欢C++引用,因为当发生间接寻址时,或者当参数通过值或指针传递而不查看函数签名时,C++引用将不再明显。
C++程序员可能不喜欢使用指针,因为它们被认为是不安全的——尽管引用实际上并不比常量指针更安全,但在大多数情况下除外——缺乏自动间接寻址的便利性,并且具有不同的语义内涵。
考虑C++常见问题解答中的以下语句:
即使引用通常使用底层汇编语言,请不要将引用视为指向对象的有趣指针。引用是对象。它是不是指向对象的指针,也不是对象的副本。它是对象
但如果引用真的是对象,那么怎么会有悬空引用呢?在非托管语言中,引用不可能比指针更“安全”——通常没有办法跨范围可靠地别名值!
为什么我认为C++引用有用
来自C背景的C++引用可能看起来有点傻,但在可能的情况下,仍应使用它们而不是指针:自动间接寻址很方便,在处理RAII时引用变得特别有用,但这并不是因为任何已知的安全优势,而是因为它们使编写惯用代码不那么困难。
RAII是C++的核心概念之一,但它与复制语义进行了非平凡的交互。通过引用传递对象可以避免这些问题,因为不需要复制。如果语言中没有引用,则必须使用指针,这样使用起来更麻烦,从而违反了语言设计原则,即最佳实践解决方案应该比替代方案更容易。
另一个区别是,可以有指向void类型的指针(这意味着指向任何对象的指针),但禁止引用void。
int a;
void * p = &a; // ok
void & p = a; // forbidden
我不能说我真的很满意这种特殊的差异。我更希望它能被允许有意义地引用任何有地址的东西,否则引用行为相同。它将允许使用引用定义一些C库函数的等价物,如memcpy。
如果你不熟悉以抽象的甚至学术的方式学习计算机语言,那么语义上的差异可能会显得深奥难懂。
在最高级别上,引用的概念是它们是透明的“别名”。你的计算机可能会使用一个地址来使它们工作,但你不必担心:你应该将它们视为现有对象的“另一个名称”,语法反映了这一点。它们比指针更严格,因此编译器可以在您将要创建悬挂引用时比在您将创建悬挂指针时更可靠地警告您。
除此之外,指针和引用之间当然还有一些实际差异。使用它们的语法明显不同,您不能“重新定位”引用、引用虚无或引用指针。
推荐文章
- cplusplus.com给出的错误、误解或坏建议是什么?
- 找出质数最快的算法是什么?
- c++枚举类可以有方法吗?
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- 将析构函数设为私有有什么用?
- main()中的Return语句vs exit()
- 为什么c#不提供c++风格的'friend'关键字?
- 如果不是内存地址,C指针到底是什么?
- 在函数的签名中添加关键字
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 为什么在标准容器中使用std::auto_ptr<>是错误的?
- 用比较double和0
- 在c#中创建一个对象的副本
- 保护可执行文件不受逆向工程的影响?
- 在c++中字符串前面的“L”是什么意思?