C++中指针和引用的区别


C++中指针和引用的区别


一、定义和声明的方式

指针

定义:指针是一个变量,其值为另一个变量的地址,指针本身也占用内存空间。
声明:使用*符号进行声明

int a = 10;
int* p = &a; // 定义指针并初始化

引用

定义:引用是某个变量的别名,一旦引用被绑定到一个对象,就不能再指向其他对象。不占用存储空间。
声明:引用使用&符号进行声明

int a = 10;
int& ref = a; // 定义引用并绑定

二、是否可为空值

指针可以为 nullptr 或 NULL,表示不指向任何对象。但是引用必须绑定到有效对象,不能为空。

三、语法与操作

指针

指针使用 * 声明和解引用(如 int *p = &a; *p = 10;)。

当指针指向的对象为类时,可使用 -> 访问成员(如 p->member)。

引用

使用 & 声明,但无需显式解引用(如 int &r = a; r = 10;)。
当指针指向的对象为类时,可直接使用 . 访问成员(如 r.member)。

四、常量性

指针

1.指向常量的指针(const T*)

p 是一个指针,指向一个不可变的int常量。
可以改变指针p指向的地址,但不能通过p修改它指向的值。

const int a = 10;
const int* p1 = &a;         // 指向常量对象a
// *p1 = 40;              // ❌ 错误:不能通过 p1 修改 c
a = 40;                   // ✅ 合法:直接修改原对象
int b = 20;
p1 = &b;                    // 指向非 const 对象(但无法通过 p1 修改 b)

2.常量指针(T* const)

p 是一个常量指针,始终指向初始化时的地址。
即不能改变指针p的地址,但可以通过p修改它指向的值。

int c = 60;
int* const p2 = &c;         // ✅ 合法:指针地址不可变
*p2 = 70;                   // ✅ 合法:修改指向的对象
int d = 20;
// p2 = &d;                 // ❌ 错误:指针本身不可修改

3.指向常量的常量指针(const T* const)

p 是一个常量指针,既不能改变指针指向的地址,也不能修改它指向的值。
完全不可变,起到只读访问的作用。

const int e = 90;
const int* const p6 = &e;    // ✅ 合法
// *p3 = 100;               // ❌ 错误:不能通过 p3 修改 f
// p3 = &a;                 // ❌ 错误:不能改变指向

引用

通过引用无法修改原对象。

const int &r = 5;
// 等价于:
const int _temp = 5;      // 编译器生成临时变量
const int &r = _temp;     // 引用绑定到临时变量
//int &r1 = 5;                // ❌ 错误:非 const 引用不能绑定到右值
//r = 20;                    // ❌ 错误:通过引用无法修改原对象的值

五、常见应用场景

指针

1.动态内存分配:

指针用于分配和释放动态内存,尤其在需要动态确定数组大小或对象数量时。

int* p = new int[10]; // 动态分配内存
delete[] p; // 释放内存

2.数据结构实现:

用于实现链表、二叉树等需要动态链接节点的数据结构。

struct Node {
    int data;
    Node* next; // 指向下一个节点
};

引用

1.函数参数传递:

引用用于将变量作为参数进行传递,可防止传参时溢出,如果不希望更改变量的值,可以加上const。

void printValue(const int& value) {//常量引用保护值不被修改。
    std::cout << value;
}

2.函数返回值:

函数可以通过引用返回一个变量,使调用者直接操作返回值。

int& getValue(int& x) {
    return x; // 返回引用
}


总结

用指针:需动态内存管理、可选绑定、或实现复杂数据结构(如链表)。
用引用:需简化语法、避免拷贝、或强制绑定有效性(如函数参数传递)。

int x = 10;
int* ptr = &x;//指针指向x的地址
cout <<"x原始的值" << x << endl;
*ptr = 11;//修改指针指向的值
cout << "修改后x的值" << x << endl << endl;
ptr = nullptr;//指针可以指向空地址
//cout << *ptr << endl;//空地址不能访问

int y = 20;
int& ref = y;//引用指向y,引用是一个变量的别名
cout << "y原始的值" << y << endl;
ref = 21;//修改引用的值
cout << "修改后y的值" << y << endl;
//ref = nullptr;不能这样使用引用,引用不可以指向空地址,引用必须初始化,没有空引用这个概念

ptr = &y;//指针可以改变指向
cout << "指针改变指向后,原来变量的值不变" << x << endl;
ref = x;//这并不是改变 ref 的绑定,而是将 x 的值赋给 y,修改的是 y 的值
cout << "修改后y的值" << y << endl;

const int* p1 = &x;//指向常量的指针,指针指向的值不能改变,指针指向的地址可以改变
// *p1 = 12;不能修改指针指向的值
p1 = &y;//可以修改指针指向的地址
const int& r1 = x;//指向常量的引用,引用指向的值不能改变,引用指向的地址不能改变
//r1 = 13;不能修改引用指向的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值