指针:指针变量相对应的内存空间里存储的值恰好是某个内存地址
c++
int x = 5;
int *ptr = &x;
- ptr是一个指针变量名
- 通过指针获取这个指针指向的内存中的值称为解引用
- 空指针不能解引用
解引用(*就是解引用运算符)
int main() {
int a = 1;
// 创建指针b,存储a的地址
int *b = &a;
// 对指针b中存储的地址进行解引用
int c = *b;
// 输出结果为:1 0x61feb4 1
cout<<a<<" "<<b<<" "<<c
}
引用:表示某一对象的别名,是一种特殊的指针
类型标识符 &引用名=目标变量名
c++
int x = 5;
int &y = x;
对象和对象的引用都指向同一地址
类型标识符是指目标变量的类型
引用声明完毕后,相当于目标变量名有2个名称(目标原名称、引用名)
int main() {
int a = 1;
int &b = a;
b = 2;
cout<<a<<endl;
}
// 输出结果为2
引用的应用
- 函数参数引用传递
#include <iostream>
use namespace std;
// 引用传递的方式
void func (int &a) {
a = a + 10;
}
// 传统值传递的方式
void func1 (int a) {
a = a + 10;
}
int main() {
int a=5,b=5;
func(a);
func1(b);
cout<<a<<" "<<b<<endl;
}
- 常引用 使用引用并确保引用的安全性
int main() {
int a = 1;
const int &b = a;
// 通过引用修改变量,报错
b = 2;
}
代码例子
int a=10,*p;
int &b=a; // 引用,变量b和a指向同一个空间
p=&a; // 指针P存储变量a的地址
string s="c++";
string *ps=&s;
cout<<p<<endl; // 输出结果是指针p的值,变量a的地址
cout<<b<<endl; // 输入结果是变量b的值10
cout<<*p<<endl; // 输出结果是指针p指向的变量的值,即变量a的值10
cout<<ps<<endl; // 输出结果是指针ps的值,变量s的地址
cout<<*ps<<endl; // 输出结果是指针ps指向的变量的值,即变量s的值"c++"
区别
- 指针有自己的一块空间,而引用只是一个别名
- 使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小
- 指针可以被初始化为NULL,而引用必须被初始化而且必须是一个已有对象的引用
- 作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象
- 指针在使用中可以指向其他对象,但是引用只能是一个对象的引用,不能被改变
- 指针可以有多级指针(**P),而引用只有一级
- 指针和引用使用++运算符的意义不一样
- 如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄漏