一级指针和二级指针做函数参数的区别

先说结论:一级指针做函数参数,只能改变其所指地址中存储的变量的值,无法改变指针本身的值,即不能改变原实参的指向;

二级指针做函数参数,仍然无法改变指针本身的值,但是可以改变二级指针指向的一级指针的指向。

一级指针做函数参数,传入的是原来指针的副本,也就是形参的地址和原来实参地址是不同的,但形参和实参的值(也就是指向的地址一样),所以可以在函数内部改变指向地址所存储的变量。

#include<iostream>
using namespace std;


void func1 (int x) {
    int tmp = x;
    x = tmp + 1;
}

void func2 (int* x) {
    cout << "x: " << x << ", *x: " << *x << ", &x: " << &x << endl;
    int tmp = *x;
    *x = tmp + 1;//改变指针所指向地址内存储变量的值,没有改变指针本身的内容
}

void func3 (int** x) {
    int tmp = **x;
    **x = tmp + 1;
}

int main()
{
    // int a,b;
    // while(cin>>a>>b)cout<<(a+b)<<endl;
    
    int a = 1;
    int* b = &a;//b存的是a的地址,也就是b=&a
    int** c = &b;//c存的是b的地址,也就是c=&b;   a=*b=**c
    cout << "a: " << a << ", &a: " << &a << endl;

    cout << "b: " << b << ", *b: " << *b << ", &b: " << &b << endl;
    cout << "c: " << c << ", *c: " << *c << ", **c: " << **c << endl;

    func2(b);

    cout << "b: " << b << ", *b: " << *b << ", &b: " << &b << endl;
    cout << "c: " << c << ", *c: " << *c << ", **c: " << **c << endl;
    
    
    return 0;
}

运行结果

可以看到在func2内输出的&x和 main中的&b不相等,在退出func2后,形参int* x的内存被释放,但是我们已经通过他改变了形参指向的地址0x7ffc3b4b572c中存储的a的值。

既然可以这么改,为什么还要引入二级指针呢?

上面说到,在func2内输出的&x和 main中的&b不相等,在退出func2后,形参int* x的内存被释放,如果我们在func2内部改变形参指针x本身的值,也就是改变他的指向,main中实参b的值会不会改变呢?答案是否定的,我们来验证一下。

上面我们在func2中令tmp=2,让x指向tmp,但是after *b和**c都没有改变。原因是退出func作用域,形参x已经被销毁,b的值本身没有被改变,函数内部也没有去改变b指向的内容。

如果想在函数内改变指针的指向该怎么做呢,二级指针就可以做到:

#include<iostream>
using namespace std;


void func1 (int x) {
    int tmp = x;
    x = tmp + 1;
}

void func2 (int* x) {
    cout << "func2 ing" << endl;
    cout << "x: " << x << ", *x: " << *x << ", &x: " << &x << endl;
    static int tmp = *x;
    tmp ++;
    cout << "tmp: " << tmp << ", &tmp: " << &tmp << endl;
    // *x = tmp + 1;//改变指针所指向地址内存储变量的值,没有改变指针本身的内容
    x = &tmp;//改变指针的指向
}

void func3 (int** x) {
    cout << "func3 ing" << endl;
    cout << "x: " << x << ", *x: " << *x << ", &x: " << &x << endl;
    static int tmp = **x;//写成static是因为,如果非static,后面*b和**c就是野值,因为tmp退出作用域被销毁了
    tmp ++;
    cout << "tmp: " << tmp << ", &tmp: " << &tmp << endl;
    *x = &tmp;
}

int main()
{
    // int a,b;
    // while(cin>>a>>b)cout<<(a+b)<<endl;
    
    int a = 1;
    int* b = &a;//b存的是a的地址,也就是b=&a
    int** c = &b;//c存的是b的地址,也就是c=&b;   a=*b=**c
    cout << "before" << endl;
    cout << "a: " << a << ", &a: " << &a << endl;
    cout << "b: " << b << ", *b: " << *b << ", &b: " << &b << endl;
    cout << "c: " << c << ", *c: " << *c << ", **c: " << **c << ", &c: " << &c << endl;

    // func2(b);
    func3(c);
    cout << "after" << endl;

    cout << "b: " << b << ", *b: " << *b << ", &b: " << &b << endl;
    cout << "c: " << c << ", *c: " << *c << ", **c: " << **c << ", &c: " << &c << endl;
    
    
    return 0;
}

运行结果:

以上内容只是个人测试分析得到的,如果有误辛苦指正~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值