指针和引用的区别和联系

为了更好的理解指针和引用,我们下面来介绍一下指针传递和引用传递。当指针和引用作为函数的函数是如何传值的呢?

  • 指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
  • 引用传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

从概念上讲。指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。

而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。

在C++中,指针和引用经常用于函数的参数传递,然而,指针传递参数和引用传递参数是有本质上的不同的:

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(这里是在说实参指针本身的地址值不会变)

而在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:

程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。


最后,总结一下:


联系:

●都是地址的概念;

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。

区别:

●指针是一个实体,而引用仅是个别名;

●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;

●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有     的,  前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变

●引用不能为空,指针可以为空;

●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;

●指针和引用的自增(++)运算意义不一样;

●引用是类型安全的,而指针不是 (引用比指针多了类型检查)





指针引用在编程中都用于间接访问操作内存中的数据,但它们在定义、初始化、可变性以及使用场景等方面存在显著的区别指针是一种变量,其值为另一个变量的地址,即内存地址。指针可以在声明后初始化为空,并且可以重新赋值指向不同的变量。这意味着指针可以在程序执行期间改变其所指向的对象。此外,指针可以被设置为`NULL`,表示它不指向任何有效的对象。当使用指针时,需要通过解引用操作符`*`来访问指针所指向的值。指针还可以进行算术运算,例如自增操作,这使得指针非常适合用于遍历数组等数据结构的操作。指针的大小通常取决于系统的架构,而不是它所指向的数据类型[^4]。 相比之下,引用更像是一个变量的别名,它必须在声明时初始化,并且一旦初始化后不能改变。这意味着引用始终绑定到初始化时指定的对象上。引用不能为`NULL`,因此在使用引用时不需要担心空引用的问题。由于引用直接操作被引用的变量,所以不需要解引用操作符。引用的大小与被引用的变量相同,因为引用本质上是一个别名[^4]。 在C++中,相比于指针更推荐使用引用,特别是在函数参数传递返回值的情况下,因为引用提供了更清晰的语法并且避免了空指针的风险。然而,在需要动态内存分配或者处理数组时,通常会使用指针。另外,当需要返回函数内部局部变量的引用时应当特别小心,因为这会导致悬空引用的问题[^5]。 下面是一个简单的例子,展示了如何声明使用指针引用: ```cpp int main() { int value = 10; int* ptr = &value; // 指针指向value的地址 int& ref = value; // 引用ref绑定到value // 通过指针修改value的值 *ptr = 20; // 通过引用修改value的值 ref = 30; return 0; } ``` 在这个例子中,无论是通过指针还是引用,都可以成功地修改`value`的值。但是需要注意的是,如果尝试返回一个局部变量的引用,那么这个引用将在函数返回后变成无效,因为局部变量的生命期随着函数的结束而结束。 综上所述,选择使用指针还是引用取决于具体的应用场景。如果需要一个能够改变指向不同对象的机制,并且可能需要处理空指针的情况,则应使用指针。如果希望确保总是有一个有效的对象被引用,并且希望获得更加直观的语法,则应使用引用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值