C++ 指针、二级指针、引用传递、值传递综合示例

#include <iostream>

using namespace std;

void PassByValue(int a){
    // 值传递。无法修改原值
    a = 10;
    return;
}

void PassByReference(int &a){
    // 引用传递,修改原值
    // 这种形式直接实参为 int 变量,或者实参为 int* 解引用得到的 int.
    a = 10;
    return;
}

void PtrPassByValue(int b){
    // 值传递。无法修改原值
    b = 20;
    return;
}

void PtrPassByPtrValue(int *b){
    // 值传递。无法修改指针原值,可修改指针所指变量。
    *b = 25;
    return;
}

void PtrPassByPtrValueAndChangePtr(int *b){
    // 值传递。无法修改指针原值,可修改指针所指变量。
    int c = 30;
    b = &c;
    return;
}


void PtrPassByPtrRefAndChangePtr(int *&b){
    // 想写指针的别名。
    // C风格是用 **, C++ 用 *&
    // C++中交换指针的问题 http://blog.csdn.net/zhang_alongzd/article/details/52937684
    int c = 35;
    b = &c;
    return;
}

void PtrPassByPtrRefAndChangePtr2(int *&b){
    int c = 35;
    int *d = &c;
    b = d;
    return;
}

void PtrPassByPtrRefAndChangePtr3(int *&b, int *c){
    // 引用传递。指针的别名,修改指针b。
    b = c;
    return;
}

void PtrPassByPtrToPtrValueAndChangePtr(int **b, int *c){
    // 值传递。指针的指针。
    *b = c;
    return;
}

int main(){
    int a = 5;
    int *b = &a;
    cout << "Value of a: " << a << endl; // 5
    PassByValue(a);
    cout << "After calling PassByValue: " << a << endl; // 5. 传值调用拷贝给函数形参,无法修改原值。
    PassByReference(a);
    cout << "After calling PassByReference: " << a << endl; // 10. 传引用调用,函数形参成为 a 的别名

    cout << "Value of b: " << *b << endl; // 10. b 一直指向 a,此时解引用后为 a 的值。
//    PtrPassByValue(b); // wrong, int* and int don't match
    PtrPassByValue(*b);
    cout << "After calling PtrPassByValue: " << *b << endl; // b 解引用后是一个 int 值,传值调用拷贝给函数形参,无法修改原值

    PtrPassByPtrValue(b);
    cout << "After calling PtrPassByPtrValue: " << *b << endl; // 25. b 是 int*,传值调用,将 b 的值,也就是指针地址拷贝给了形参,可修改指针指向的值。

    PtrPassByPtrValueAndChangePtr(b);
    cout << "After calling PtrPassByPtrValueAndChangePtr: " << *b << endl; // 25. 前段分析同上。此时改指针指向的内容,也就是改变指针所存储的地址值,因为形参指针与实参指针没有关联,是互相独立的,修改无效。这与 PassByValue(a) 的道理一样。

//    PtrPassByPtrValueAndChangePtr(&b); // wrong, int* and int** mismatch. 直觉地传指针地址失败。

//    PtrPassByPtrRefAndChangePtr(b);
//    cout << "After calling PtrPassByPtrRefAndChangePtr: " << *b << endl; // 1.

    PtrPassByPtrRefAndChangePtr2(b);
    cout << "After calling PtrPassByPtrRefAndChangePtr2: " << *b << endl; // 1. 与上面这种直接取地址的一样。。因为局部变量 int d 被销毁了?

    int cc = 100;
    int *c = &cc;
    PtrPassByPtrRefAndChangePtr3(b, c);
    cout << "After calling PtrPassByPtrRefAndChangePtr3: " << *b << endl; // 100. 成功修改 b 指针。上面值错了可能是销毁. 但是指针的确是改了。

    b = &a;
    cout << "Reset b to a: " << *b << endl; // 25
    PtrPassByPtrToPtrValueAndChangePtr(&b, c);
    cout << "After calling PtrPassByPtrToPtrValueAndChangePtr: " << *b << endl;


    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013614126/article/details/76263972