【C++】引用和指针

时间:2024-10-28 13:23:54

C++中的引用和指针

  • C++中的引用和指针
    • 一、引用类型(Reference)
      • 1.1 引用的赋值
      • 1.2 引用作为函数参数
      • 1.3 被const修饰的引用
    • 二、指针
      • 2.1 空指针
      • 2.2 void* 指针

C++中的引用和指针

C++中有一个不同于C的指针传递方式,即在本文中所介绍的引用,此处的引用指的是左值引用。

一、引用类型(Reference)

引用类型实际上是给已存在的变量起一个新的名字,不会产生新的变量(变量即是对象),所操纵的变量是同一个。

因此,引用在定义的时候,就必须被初始化,不能定义一个空的引用。

int c = 5;
int &r = c;     // 等价于 int& r = c;  为对象c起一个别名r
cout << "r = " << r << ", " << endl;
c = 100;
int &q = r;		// 等价于 int& q = r;	再重新为被绑定的对象c起一个别名 q
cout << "&c = " << &c << ", &r = " << &r << ", &q = " << &q <<endl;
cout << "c = " << c << ", r = " << r << ", q = " << q <<endl;

初始化完成之后,引用和它的初始值对象就一直绑定在一起了。之后,不能再让引用重新绑定到另一个对象上。

所以,c 和 r 所代表的是用一个对象,地址空间也是同一个。

上面的例子打印结果:

r = 5,
&c = 0x527e7ffcb4, &r = 0x527e7ffcb4, &q = 0x527e7ffcb4
c = 100, r = 100, q = 100

1.1 引用的赋值

上面说到,引用是给已存在的重新起了一个别名,那么为引用赋值,实际上就是把值赋值给绑定的变量。在上面的例子中也可以发现,修改了原来对象c的值,与之对应的其他引用也会修改,因为它们都是对应着同一个对象。

1.2 引用作为函数参数

和c语言相比,c++采用引用的方式,在函数中,不需要新增变量,即可直接修改变量的内容。

在c语言中,使用指针的方式来修改变量内容,需要新增一个指针变量,把该变量的地址赋值给指针变量,再通过指针来修改变量内容。

#include <iostream>
using namespace std;

void FuncRefer(int &ref)
{
    cout << "[" << __FUNCTION__ << "]: ";
    cout << "&ref = " << &ref << endl;
    ref = 2;
}

void FunPtr(int *ptr)
{
    cout << "[" << __FUNCTION__ << "]: ";
    cout << "&ptr = " << &ptr << endl;
    *ptr = 3;
}

int main()
{
    int a = 10;
    cout << "[" << __FUNCTION__ << "]: ";
    cout << "a = " << a << ", &a = " << &a << endl;
    
    FunPtr(&a);
    FuncRefer(a);

    cout << "[" << __FUNCTION__ << "]: ";
    cout << "a = " << a << "," << endl;
    return 0;
}

输出结果:

[main]: a = 10, &a = 0xecf1fffa6c
[FunPtr]: &ptr = 0xecf1fffa40
[FuncRefer]: &ref = 0xecf1fffa6c
[main]: a = 2,

在上面的例子中,可以发现在使用指针FunPtr的方式中,会新建一个指针变量。而使用引用FuncRefer的时候,则是直接使用对变量a进行修改。

使用引用作为参数的方式,简化了指针的操作,易于理解。

在c++中可以使用引用的方式交换数字:

void swap(int &a, int &b)
{
    int temp = 0;
	temp = a;
    a = b;
    b = temp;
}

示例:

int main()
{
    a = 1; b = 99;
    cout << "a = " << a << ", b = " << b  << "," << endl;
    swap(a,b);
    cout << "a = " << a << ", b = " << b  << "," << endl;
    return 0;
}

结果:

a = 1, b = 99,
a = 99, b = 1,

1.3 被const修饰的引用

使用const修饰的引用,同样不能够通过该引用修改绑定的对象。

int d = 12;
const int &n = d;  
n = 100;  // 错误,不能够通过const引用来修改值,
int m = n; // 正确

二、指针

指针的内容和C语言的大都一致:可以参考前面的指针的文章:C语言指针

指针不同于引用,指针本身就是一个对象,有自己的地址和内存单元,在指针的生命周期内可以先后指向不同的对象。其次,指针无须在定义时赋初值。

因此,也可以有指针的引用类型。

a = 10;
int* p = &a;
int* &ref = p;
cout << "a = " << a << ", &a = " << &a << endl;
cout << "p = " << p << ", ref = " << ref  << "," << endl;

输出:

a = 10, &a = 0x424e1ff6fc
p = 0x424e1ff6fc, ref = 0x424e1ff6fc,

2.1 空指针

空指针不指向任何对象,可以使用 nullptr 来初始化指针。若使用NULL的化,则需要添加头文件 cstdlib 。

int* p = nullptr;

2.2 void* 指针

void* 是一种特殊的指针类型,可用于存放任意对象的地址。