C++的指针和引用

指针就是指向变量的地址,而引用是变量的别名,通过指针或引用都可以修改变量的值,但两者的使用上会有一些差异,比如:

  1. 引用在定义的时候必须初始化,且只能指向一个变量,后续不能指向其它变量。而指针在定义的时候可以不初始化,且后续可以修改指向为其它地址;
  2. 引用的大小是所指向变量的大小,而指针的大小则是固定的,32位系统为4字节,64位系统位8字节;
  3. 引用比指针更安全,因为引用在定义的时候必须初始化,所以不可能为空,而指针可能为空,所以指针使用前必须判空;
  4. 引用可以直接使用,而指针需要用*;

还是通过代码来理解,定义了几个函数:

void print(int *pn)
{
    cout<<"print(int *pn): pn\t"<<pn<<endl;
    cout<<"print(int *pn): &pn\t"<<&pn<<endl;
    cout<<"print(int *pn): *pn\t"<<*pn<<endl;
    *pn = 12;
}

void print(int &pn)
{
    cout<<"print(int &pn): pn\t"<<pn<<endl;
    cout<<"print(int &pn): &pn\t"<<&pn<<endl;
    pn = 13;
}

void print2(int *&pn)
{
    cout<<"print2(int *&pn): *pn\t"<<*pn<<endl;
    cout<<"print2(int *&pn): &pn\t"<<&pn<<endl;
    cout<<"print2(int *&pn): pn\t"<<pn<<endl;
    *pn = 14;
}
	int n = 10;
    int *pn = &n;
    cout<<"例子1: 传指针 ---------->"<<endl;
    print(pn);

    cout<<__func__<<"\tpn\t"<<pn<<endl;
    cout<<__func__<<"\t&pn\t"<<&pn<<endl;
    cout<<__func__<<"\t*pn\t"<<*pn<<endl;

    cout<<"例子2: 传引用 ---------->"<<endl;
    print(*pn);

    cout<<__func__<<"\tpn\t"<<pn<<endl;
    cout<<__func__<<"\t&pn\t"<<&pn<<endl;
    cout<<__func__<<"\t*pn\t"<<*pn<<endl;

    cout<<"例子3: 传指针引用 ---------->"<<endl;
    print2(pn);

    cout<<__func__<<"\tpn\t"<<pn<<endl;
    cout<<__func__<<"\t&pn\t"<<&pn<<endl;
    cout<<__func__<<"\t*pn\t"<<*pn<<endl;

输出结果:

例子1: 传指针 ---------->
print(int *pn): pn	0x7ffeed4af9b4
print(int *pn): &pn	0x7ffeed4af828
print(int *pn): *pn	10
main	pn	0x7ffeed4af9b4
main	&pn	0x7ffeed4af9a8
main	*pn	12
例子2: 传引用 ---------->
print(int &pn): pn	12
print(int &pn): &pn	0x7ffeed4af9b4
main	pn	0x7ffeed4af9b4
main	&pn	0x7ffeed4af9a8
main	*pn	13
例子3: 传指针引用 ---------->
print2(int *&pn): *pn	13
print2(int *&pn): &pn	0x7ffeed4af9a8
print2(int *&pn): pn	0x7ffeed4af9b4
main	pn	0x7ffeed4af9b4
main	&pn	0x7ffeed4af9a8
main	*pn	14

在例子1中,print(int *pn)函数和main函数输出的&pn是不一样的,一个是0x7ffee9fa9838,一个是0x7ffee9fa99a8,因为print(int *pn)函数是传值,没错,传值,只是这个值是“指针”,它会生成一个指针的副本,因此print(int *pn)函数和main函数输出的&pn会不一样。

注意⚠️,还有一个容易忽视的错误,看代码:

void testPtr(int *pi)
{
    pi = new int;
    cout<<__func__<<"\t"<<pi<<endl;
}

int main() {
	int *pi = new int(100);
	cout<<"pi -> "<<pi<<endl;
	testPtr(pi);
	cout<<"pi -> "<<pi<<endl;
}

运行结果:

pi -> 0x7fa03b402ae0
testPtr	0x7fa03b402af0
pi -> 0x7fa03b402ae0

可能有人会认为在testPtr能够修改pi的值,但正如上面所说的,指针是传值,作为testPtr的参数时,是生成了一个指针的副本,因此在testPtr函数内,修改的是指针副本的值,而不是main函数中定义的pi的值。

还有一个关于引用的例子,看代码:

int &max(int &a, int &b)
{
    return a > b ? a : b;
}

    int n1 = 11, n2 = 12;
    cout<<++max(n1,n2)<<"\t"<<n1<<"\t"<<n2<<endl;

程序输出:

13	11	13

max函数返回的是n2的引用,因此++max(n1,n2)会修改n2的值⚠️。

参考
参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值