本文主要是介绍【Cpp巩固】引用与指针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【Cpp巩固】引用与指针
文章目录
- 【Cpp巩固】引用与指针
- 1.基本的语义差异
- 2.使用场景
- 3.可变性
- 4.语法和便利性
笔者在学习Cpp
的过程中老是会对指针和引用使用产生疑问,那本文就来详细对比一下指针和引用的区别。
1.基本的语义差异
- 指针是一个变量,存储的是另一个变量的内存地址,指针可以被重复赋值指向相同类型的其他变量,也可以指向空指针
nullptr
。 - 引用是一个已经存在的变量的别名,并且引用必须在声明的时候就进行初始化,引用一旦定义就和该变量绑定了,作为该变量的别名,就不能指向别的变量。
举个例子:
#include <iostream>
using namespace std;int main() {int a = 10;int* a_ptr = &a; // 声明一个指向a的指针int& a_ref = a; // 声明一个指向a的引用cout << "This address of a is :" << &a << endl;cout << "This address of a_ptr is: " << &a_ptr << endl;cout << "This address of a_ref is: " << &a_ref << endl;cout << "a: " << a << " a_ptr: " << *a_ptr << " a_ref: " << a_ref << endl;*a_ptr += 10; // 通过指针修改变量a的值cout << "a: " << a << " a_ptr: " << *a_ptr << " a_ref: " << a_ref << endl;a_ref += 10; // 通过引用修改变量a的值cout << "a: " << a << " a_ptr: " << *a_ptr << " a_ref: " << a_ref << endl;return 0;
}
Output:
This address of a is :000000D68E3CF7C4
This address of a_ptr is: 000000D68E3CF7E8
This address of a_ref is: 000000D68E3CF7C4
a: 10 a_ptr: 10 a_ref: 10
a: 20 a_ptr: 20 a_ref: 20
a: 30 a_ptr: 30 a_ref: 30
这个例子中创建了一个变量a
,然后创建了指向a
的指针a_ptr
,同时创建了指向a
的引用a_ref
,通过指针a_ptr
和引用a_ref
我们都能访问并且修改变量a
的值,a_ref
与变量a
的地址完全一样,可以视作a_ref
就是变量a
的另一个别名。
2.使用场景
- 指针可以在需要直接操作内存地址或者需要能够指向
NULL
的常见下使用,例如动态内存管理、数据结构的实现等。 - 引用通常用于函数的参数传递过程中,尤其是传递大对象的时候避免了复制成本,或者当你需要确保传递的参数总是指向一个有效的对象时。
我们可以使用指针来进行动态内存管理,举个例子:
#include <iostream>int main() {int size;std::cout << "Please Enter the Size of Elements: ";std::cin >> size;int* array = new int[size]; // 动态分配内存for (int i = 0; i < size; i++) { // 初始化数组array[i] = (i + 1);}std::cout << "Array Elements: " << std::endl;for (int i = 0; i < size; i++) {std::cout << array[i] << " ";}delete[] array;return 0;
}
Output:
Please Enter the Size of Elements: 10
Array Elements:
1 2 3 4 5 6 7 8 9 10
在这个例子中,指针 array
被用来指向一个动态分配的整数数组。通过使用 new
和 delete[]
,我们可以控制内存的分配和释放,这是引用无法完成的任务。
我们可以使用引用来进行大型的参数传递,举个例子:
#include <iostream>
#include <vector>void proccessVector(const std::vector<int>& vec) {std::cout << "Vector Elements: " << std::endl;for (int elem : vec) {std::cout << elem << " ";}return;
}int main() {std::vector<int> vec = { 1, 2, 3, 4, 5, 7, 8, 9, 10 };// 使用引用进行参数传递,避免参数复制proccessVector(vec);return 0;
}
在这个例子中,std::vector<int>
是一个可能包含大量数据的对象。通过使用引用,我们传递了一个到 processVector
函数的引用,避免了数据的复制。此外,使用 const
关键字确保函数内部不会修改向量的内容。
3.可变性
- 指针可以指向常量
const int* prt
,或者指针本身可以是常量int* const prt
,或者两者都是const int* const ptr
- 引用通常不称其为"常量引用",但是可以有指向常量的引用
cosnt int& ref
,这意味着不能通过修改其所指向的变量的值
#include <iostream>int main() {int x = 10;int y = 20;// 指针指向非常量数据int* ptr = &x;*ptr = 15;std::cout << "New value of x: " << x << std::endl;// 指针指向常量数据const int* ptrToConst = &y;// *ptrToConst = 25; // 错误,不能通过指向常量的指针修改数据// 常量指针int* const constPtr = &x;*constPtr = 25;// constPtr = &y; // 错误,不能修改常量指针的指向// 常量指针指向常量数据const int* const constPtrToConst = &y;// *constPtrToConst = 30; // 错误:不能修改y的值// constPtrToConst = &x; // 错误:常量指针不能改变指向return 0;
}
4.语法和便利性
- 指针的操作需要使用
*
(解引用)和->
(成员访问) - 引用的使用就像使用普通变量一样,不需要使用特殊的符号来进行访问
我们编写一个汽车类,然后使用指针和引用两种方式来操作这个汽车类的实例,举个例子:
#include <iostream>
class Car {public:void start() {std::cout << "Car started!" << std::endl;}
};int main() {Car mycar;Car* carPtr = &mycar;Car& carRef = mycar;// 使用指针访问成员函数carPtr->start();// 使用引用访问成员函数carRef.start();return 0;
}
Output:
Car started!
Car started!
这篇关于【Cpp巩固】引用与指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!