一、二级指针:

变量 = 内存地址 + 存储值;

指针 = 内存地址 + 变量内存地址;

二级指针 = 内存地址 + 指针内存地址;

多级指针 = 内存地址 + 上一级内存地址;

void morePointer() {
    int n = 190;
    int * pointer = &n;
    int ** pointerL2 = &pointer;

    printf("n -> %d\n", n);
    printf("pointer -> %p\n", pointer);
    printf("pointerL2 -> %p\n", pointerL2);

    printf("*pointerL2 == pointer == &n ? -> %d (1 true 0 false), *pointerL2 -> %p\n", *pointerL2 == pointer, *pointerL2);
    printf("**pointerL2 == *pointer == n ? -> %d (1 true 0 false), **pointerL2 -> %d\n", **pointerL2 == n, **pointerL2);
}

int main() {
    morePointer();
    return 0;
}

 二、参数传递

数据传递方式:

1、值传递

2、地址传递

// 使用值传递
void valueSwap(int n1, int n2) {
    int temp = n1;
    n1 = n2;
    n2 = temp;

    printf("in function valueSwap n1 = %d, n2 = %d\n", n1, n2);
}

// 使用地址传递
void addrSwap (int * n1, int * n2) {
    int temp = *n1;
    *n1 = *n2;
    *n2 = temp;
    printf("in function addrSwap a = %d, b = %d\n", *n1, *n2);
}

void testForSwap() {
    int a = 200;
    int b = 100;
    valueSwap(a, b);
    printf("in function testForSwap a = %d, b = %d\n", a, b);

    addrSwap(&a, &b);
    printf("in function testForSwap a = %d, b = %d\n", a, b);
}

int main() {
    testForSwap();
    return 0;
}

三、数组名作为函数参数

一个需求,定义一个函数用来遍历传递进来的数组

void printArray(int * arr, int size) { // 使用指针,允许是变量地址,但也可以是数组名称
    for (int i = 0; i < size; ++i) {
        printf("element -> (%d), and mem-addr -> %p\n", arr[i], &arr[i]);
    }

    printf("sizeof is pointer or array itself ? -> %d\n", sizeof(arr));
}

// 为了明确参数传递的是什么数据,建议是数组就传递数组
void printArrayV2(int array[], int length) {
    for (int i = 0; i < length; ++i) {
        printf("element -> (%d), and mem-addr -> %p\n", array[i], &array[i]);
    }

    printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array));
}

// 封装获取数组长度的方法
int getSize(int array[]) {
    return sizeof(array) / sizeof(int);
}

// 封装数组遍历的方法:
void printArrayV3(int array[]) {
    for (int i = 0; i < getSize(array) ; ++i) {
        printf("el -> %d, mem-addr -> %p\n", array[i], &array[i]);
    }
    printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array));
}

int main() {
    int array[10] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
    printArray(array, 10);

    printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array));

    int array2[9] = { 2 };
    printArrayV2(array2, sizeof(array2) / sizeof(int));
    printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array2));

    int array3[3] = { 100 };
    printArrayV3(array3);
    printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array3));
    return 0;
}

 四、指针做函数的返回类型

// 定义一个全局变量
int g_a = 100;

int * returnTypeUsage() {
    int a = 100; // 定义局部变量

    {
        int a = 100; // 代码块中的局部变量

        {
            int a = 100; // 块中块的局部变量
        }
    }
}

// 封装一个获取地址的函数
int* getMemAddr() {
    return &g_a;
}

int main() {
    int *p = getMemAddr();

    *p = 33000;

    printf("g_a -> %d\n", g_a);
    return 0;
}