• 【C】指针进阶(上)


    指针进阶


    继上文, 指针,我们已经大致了解了以下四点:

    1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。

    2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。

    3. 指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。

    4. 指针的运算。

    那么这篇文章我们就指针来做深一步的讨论~

    字符指针

    字符指针是指向字符数据的指针。它可以用于操作字符串,即以字符数组的形式存储的一组字符。在指针的类型中我一种指针类型为字符指针 char* ;

    #include 
    
    int main() {
        char str[] = "Hello, World!"; // 字符数组,存储了字符串
        char* ptr = str; // 字符指针,指向字符数组的首地址
    
        printf("String: %s\n", ptr); // 通过字符指针输出字符串
    
        while (*ptr != '\0') { // 循环遍历字符数组中的每个字符,直到遇到结束符 '\0'
            printf("Character: %c\n", *ptr); // 输出当前字符
            ptr++; // 指针移动到下一个字符
        }
    
        return 0;
    }
    //输出结果
    String: Hello, World!
    Character: H
    Character: e
    Character: l
    Character: l
    Character: o
    Character: ,
    Character:
    Character: W
    Character: o
    Character: r
    Character: l
    Character: d
    Character: !
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    字符指针的本质就是将字符串的首地址放到了指针中

    需要注意的是,在操作字符指针和字符串时,需要确保字符串以结束符 '\0' 结尾,否则会导致意想不到的结果。在声明字符数组时,C语言会自动在字符串末尾添加结束符,因此我们可以使用上述方法遍历字符串

    另外,字符指针还可以用于字符串的处理,如拷贝、连接、比较等操作,同时还可以通过指针的偏移来修改字符串中的字符。

    例子

    所以再面试题中,有这么一道题:

    #include 
    int main()
    {
        char str1[] = "hello bit.";
        char str2[] = "hello bit.";
        const char *str3 = "hello bit.";
        const char *str4 = "hello bit.";
        if(str1 ==str2)
     printf("str1 and str2 are same\n");
        else
     printf("str1 and str2 are not same\n");
           
        if(str3 ==str4)
     printf("str3 and str4 are same\n");
        else
     printf("str3 and str4 are not same\n");
           
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这里的输出结果:

    str1 and str2 are not same
    str3 and str4 are same
    
    • 1
    • 2

    解析

    在这段代码中,我们声明了四个字符串变量 str1str2str3str4 来存储相同内容的字符串 “hello bit.”。其中,str1str2 是字符数组,而 str3str4 是字符指针。

    在比较 str1str2 的地址时,由于它们分别是不同的字符数组,它们的地址也是不同的,所以 str1 == str2 将被认为是不相等的。因此,输出结果会是 "str1 and str2 are not same"

    而在比较 str3str4 的地址时,它们都是指向相同字符串 "hello bit."的常量字符指针。由于代码中的字符串字面值在编译时就被分配了固定的内存地址,所以 str3str4 的值相等。因此,str3 == str4 将被认为是相等的。所以,输出结果会是 "str3 and str4 are same"

    指针数组

    概念

    指针数组是一个存放指针的数组

    再次强调!指针数组是数组!数组!数组!!!

    每个元素都是指针,指向不同的数据对象或变量。指针数组可以用于存储不同类型的指针,也可以存储指向相同类型的多个对象的指针


    要声明一个指针数组,需要指定指针的类型和数组的大小。

    例如,int *arr[5] 声明了一个包含 5 个指向整型数据的指针的数组。


    指针数组的元素可以通过索引访问。可以使用下标(从0开始)来指定要访问的元素。例如,对于指针数组 int *arr[5],可以使用 arr[0]arr[1] 等来访问其中的指针元素。


    指针数组的使用可以带来一些好处。

    例如,可以将多个指针作为参数传递给函数,可以方便地在代码中存储和处理多个指针对象。此外,指针数组还可以用于实现动态内存管理,例如创建和管理动态分配的对象的指针。

    #include 
    
    int main() {
        int num1 = 1;
        int num2 = 2;
        int num3 = 3;
        
        int* arr[3]; // 声明一个包含 3 个指向整型数据的指针的数组
        
        arr[0] = &num1; // 将 num1 的地址赋值给数组的第一个元素
        arr[1] = &num2; // 将 num2 的地址赋值给数组的第二个元素
        arr[2] = &num3; // 将 num3 的地址赋值给数组的第三个元素
        
        for (int i = 0; i < 3; i++) {
            printf("Element %d: %d\n", i, *(arr[i])); // 使用指针解引用来输出指针指向的值
        }
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出结果会是:

    Element 0: 1
    Element 1: 2
    Element 2: 3
    
    • 1
    • 2
    • 3

    在上述示例中,我们了一个包含 3 个指向整型数据的指针的数组 arr。然后,我们分别将 num1num2num3 的地址赋值给数组中的元素。最后,我们通过循环遍历指针数组,并使用指针解引用来输出指针指向的值。

    指针数组使用非常灵活,可以根据实际的需求来存储和操作不同类型的指针。

    数组指针

    既然知道了什么是指针数组,那么数组指针又是什么呢?

    是指针!指针!指针!(在地上打滚面红耳赤尖叫~)

    写法

    声明一个数组指针的格式为:

    datatype (*pointer_name)[size];
    /*
    datatype 是指向的数组元素的数据类型,
    pointer_name 是指针的名字,
    size 是数组的大小。
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 声明一个指向整型数组的指针:
    int (*ptr)[5];
    
    • 1

    这个指针指向一个包含 5 个整型元素的数组。

    1. 声明一个指向字符数组的指针:
    char (*ptr)[10];
    
    • 1

    这个指针指向一个包含 10 个字符元素的数组。

    1. 声明一个指向双精度浮点数数组的指针:
    double (*ptr)[7];
    
    • 1

    这个指针指向一个包含 7 个双精度浮点数元素的数组。

    1. 声明一个指向二维整型数组的指针:
    int (*ptr)[3][4];
    
    • 1

    这个指针指向一个包含 3 行 4 列的二维整型数组。

    注意事项

    括号是必需的,因为数组指针的优先级比*高。括号的存在可以确保指针指向整个数组,而不是数组的某个元素。


    实践

    int *p1[10];
    int (*p2)[10];
    //p1, p2分别是什么?
    
    • 1
    • 2
    • 3

    p1 是一个指针数组,包含 10 个指向整型变量的指针。每个指针可以指向一个整型变量。

    p2 是一个指向整型数组的指针。该数组包含 10 个整型元素。

    &数组名VS数组名

    &数组名数组名 在C语言中是有着不同的含义。区别如下:

    1. &数组名:使用 & 运算符加上数组名,可以获取数组的地址这意味着它会返回指向数组的指针,指针的类型为数组类型的指针

      例如,如果有一个名为 arr 的数组,那么 &arr 将返回指向数组 arr 的指针。

    2. 数组名:在大多数情况下,数组名将被解释为指向数组第一个元素的指针。所以当使用数组名时,它实际上是一个指向数组第一个元素的指针。

      例如,如果有一个名为 arr 的数组,那么 arr 将被解释为指向数组 arr 第一个元素的指针。这个指针的类型会根据数组元素类型而定。

    下面是一个示例来说明两者的区别:

    int arr[5] = {1, 2, 3, 4, 5};
    
    int *ptr1 = &arr;  // 这种写法是错误的,&arr是一个指向整个数组的指针,与int*不匹配
    
    int *ptr2 = arr;  // 正确,arr被解释为指向数组第一个元素的指针
    
    printf("ptr2[0] = %d\n", ptr2[0]);  // 输出第一个元素的值
    
    int (*ptr3)[5] = &arr;  // 正确,&arr是一个指向数组的指针,ptr3为指向整个数组的指针
    
    printf("(*ptr3)[0] = %d\n", (*ptr3)[0]);  // 输出第一个元素的值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    再举一个例子

    #include 
    int main()
    {
     int arr[10] = { 0 };
     printf("arr = %p\n", arr);
     printf("&arr= %p\n", &arr);
     printf("arr+1 = %p\n", arr+1);
     printf("&arr+1= %p\n", &arr+1);
     return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    输出结果为:

    arr = 0x7fff99774d50
    &arr= 0x7fff99774d50
    arr+1 = 0x7fff99774d54
    &arr+1= 0x7fff99774d74
    
    • 1
    • 2
    • 3
    • 4

    解释:

    • arr&arr 的值是相等的,它们都是数组第一个元素的地址。因为数组名被解释为指向数组第一个元素的指针,所以 arr&arr 的值是相同的。

    • arr+1 的值是数组中下一个元素的地址,即数组第二个元素的地址。因为 arr 是指向数组第一个元素的指针,当加上 1 后,指针向后移动了一个元素大小的距离。在这个例子中,整型元素的大小为 4 字节,所以 arr+1 的值比 arr 的值增加了 4

    • &arr+1 的值是整个数组之后的地址,也就是数组的尾部之后的地址。因为 &arr 是指向整个数组的指针,所以当加上 1 后,指针向后移动了整个数组的大小的距离。在这个例子中,整个数组的大小为 40 字节(数组中有 10 个整型元素,每个元素大小为 4 字节),所以 &arr+1 的值比 &arr 的值增加了 40

    总结一下,&数组名 返回指向整个数组的指针,表示的是数组的地址。而 数组名 返回指向数组第一个元素的指针。它们在类型上有所不同,对于指针的声明和使用会有所区别。

    使用

    #include 
    
    int main() {
        int arr[3][5] = {
            {1, 2, 3, 4, 5},
            {6, 7, 8, 9, 10},
            {11, 12, 13, 14, 15}
        };
        
        int (*ptr)[5]; // 声明一个指向包含 5 个整型元素的数组的指针
        ptr = arr; // 将数组的地址赋值给指针
        
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                printf("Element[%d][%d]: %d\n", i, j, (*ptr)[j]); // 使用指针解引用操作访问数组元素
            }
            ptr++; // 指针进行算术运算,指向下一个元素的地址
        }
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    输出结果会是:

    Element[0][0]: 1
    Element[0][1]: 2
    Element[0][2]: 3
    Element[0][3]: 4
    Element[0][4]: 5
    Element[1][0]: 6
    Element[1][1]: 7
    Element[1][2]: 8
    Element[1][3]: 9
    Element[1][4]: 10
    Element[2][0]: 11
    Element[2][1]: 12
    Element[2][2]: 13
    Element[2][3]: 14
    Element[2][4]: 15
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在上述示例中,我们声明了一个包含 3 行 5 列的二维数组 arr。然后,我们声明了一个数组指针 ptr,并将 arr 的地址赋值给它。接下来,我们使用双重循环遍历数组,并通过指针解引用操作和数组指针的算术运算,输出了数组的各个元素。

    数组指针的使用总结起来基本就是下面三种:

    在C语言中,数组指针是一种特殊的指针类型,它可以用来指向数组。通过数组指针,我们可以方便地访问数组中的元素。

    要声明一个数组指针,可以使用以下语法:

    类型 (*指针名)[数组长度];
    
    • 1

    其中,类型 表示数组元素的类型,指针名 是指针的名称,数组长度 是数组的长度。


    以下是几种常见的使用数组指针的方式:

    1. 数组指针作为函数参数:
    void printArray(int (*ptr)[5], int length) {
      for (int i = 0; i < length; i++) {
        printf("%d ", (*ptr)[i]);
      }
      printf("\n");
    }
    
    int main() {
      int arr[5] = {1, 2, 3, 4, 5};
      int (*ptr)[5] = &arr;
      printArray(ptr, 5);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这个例子中,printArray 函数接受一个指向长度为5的整型数组的数组指针作为参数。在 main 函数中,我们创建了一个指向 arr 数组的指针 ptr,然后将 ptr 作为参数传递给 printArray 函数。函数内部通过 (*ptr)[i] 的方式访问数组元素。

    1. 数组指针的数组:
    int main() {
      int arr1[5] = {1, 2, 3, 4, 5};
      int arr2[4] = {10, 20, 30, 40};
      int (*arrPtr[2])[5] = {&arr1, &arr2};
    
      for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 5; j++) {
          printf("%d ", (*arrPtr[i])[j]);
        }
        printf("\n");
      }
    
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这个例子中,我们声明了一个数组 arrPtr,它包含两个指针,这两个指针分别指向长度为5的整型数组。然后我们通过 (*arrPtr[i])[j] 的方式访问数组元素。

    1. 动态分配数组指针:
    int main() {
      int (*ptr)[5] = malloc(sizeof(int[5]));
    
      for (int i = 0; i < 5; i++) {
        (*ptr)[i] = i + 1;
      }
    
      for (int i = 0; i < 5; i++) {
        printf("%d ", (*ptr)[i]);
      }
      printf("\n");
    
      free(ptr);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这个例子中,我们使用 malloc 函数动态分配了一个长度为5的整型数组,并将返回的指针赋值给 ptr。通过 (*ptr)[i] 的方式访问数组元素。最后记得使用 free 函数释放内存。


    最后用我觉得数组指针的难点它与&数组名之间的区别,通俗来理解就是:数组指针是整个数组的地址,这本质上与&数组名是有区别的,&数组名是数组首元素的地址,不过这两者在遍历数组上基本是一样的,唯一区别就是数组指针它可以指定在任意一个元素开始遍历~

    数组传参和指针传参

    在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?

    一维数组传参

    当将一维数组传递给函数时,有三种常见的方式:

    1. 传递指针

      将数组名作为指针参数传递给函数。由于数组名本身就是数组首元素的地址,因此在函数中可以通过指针操作符 * 来访问数组元素。

    void printArray(int *arr, int size) {
        // 使用指针操作符 * 来访问数组元素
        for (int i = 0; i < size; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");
    }
    
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
        int size = sizeof(arr) / sizeof(arr[0]);
    
        // 传递数组名作为指针参数
        printArray(arr, size);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. 传递数组长度

      将数组名作为指针参数传递给函数,并使用额外的参数将数组的长度传递给函数。这种方式适用于在函数中需要知道数组长度的情况。

    void printArray(int *arr, int size) {
        // 使用传入的数组长度进行循环
        for (int i = 0; i < size; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");
    }
    
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
    
        // 传递数组名作为指针参数,同时传递数组长度
        printArray(arr, sizeof(arr) / sizeof(arr[0]));
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 使用固定长度的数组

      在函数定义中指定数组的长度,并将数组作为参数传递给函数。这种方式适用于固定长度的数组,并且可以在函数内部直接使用这个已知长度的数组。

    void printArray(int arr[], int size) {
        // 直接使用指定长度的数组
        for (int i = 0; i < size; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");
    }
    
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
    
        // 将数组作为参数传递给函数,同时传递数组长度
        printArray(arr, sizeof(arr) / sizeof(arr[0]));
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二维数组传参

    当将二维数组传递给函数时,同样有多种方式:

    1. 传递指针

      可以将二维数组的首行地址作为指针参数传递给函数。在函数中,可以使用指针操作符 * 和数组下标来访问二维数组元素。

    void printMatrix(int (*arr)[cols], int rows, int cols) {
        // 使用指针操作符 * 和数组下标访问二维数组元素
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                printf("%d ", arr[i][j]);
            }
            printf("\n");
        }
    }
    
    int main() {
        int matrix[3][3] = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        int rows = sizeof(matrix) / sizeof(matrix[0]);
        int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]);
    
        // 传递二维数组的首行地址作为指针参数
        printMatrix(matrix, rows, cols);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. 使用指针数组

      可以将每一行看作是一个一维数组,并将指向二维数组的指针数组传递给函数。在函数中,使用指针操作符 * 来访问二维数组元素。

    void printMatrix(int *arr[], int rows, int cols) {
        // 使用指针操作符 * 访问二维数组元素
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                printf("%d ", arr[i][j]);
            }
            printf("\n");
        }
    }
    
    int main() {
        int matrix[3][3] = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        int *ptr[3];
        int rows = sizeof(matrix) / sizeof(matrix[0]);
        int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]);
    
        // 将指向二维数组的指针数组传递给函数
        for (int i = 0; i < rows; i++) {
            ptr[i] = matrix[i];
        }
        printMatrix(ptr, rows, cols);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    1. 使用一维指针

      可以将整个二维数组展开成一维数组,并传递该一维数组的指针给函数。在函数中,可以使用类似于一维数组的方式来访问元素。

    void printMatrix(int *arr, int rows, int cols) {
        // 使用类似于一维数组的方式访问元素
        for (int i = 0; i < rows * cols; i++) {
            printf("%d ", arr[i]);
            if ((i + 1) % cols == 0) {
                printf("\n");
            }
        }
    }
    
    int main() {
        int matrix[3][3] = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        int rows = sizeof(matrix) / sizeof(matrix[0]);
        int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]);
    
        // 将二维数组展开成一维数组,并传递指针给函数
        printMatrix((int *)matrix, rows, cols);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    一级指针传参

    当将一级指针作为参数传递给函数时,有三种常见的方式:

    1. 传递指针的地址

      可以将一级指针的地址作为参数传递给函数。在函数中,使用双重指针来接收该地址,并可以通过指针操作符 *-> 来访问指针指向的值和成员。

    void updatePointer(int **ptr) {
        // 使用指针操作符 * 和 -> 访问指针指向的值和成员
        *ptr = NULL;
    }
    
    int main() {
        int *ptr;
        int num = 10;
    
        ptr = &num;
    
        // 传递一级指针的地址
        updatePointer(&ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 传递指针的指针

      可以直接将一级指针作为指针参数传递给函数。在函数中,使用指针操作符 *-> 来访问指针指向的值和成员。

    void updatePointer(int **ptr) {
        // 使用指针操作符 * 和 -> 访问指针指向的值和成员
        *ptr = NULL;
    }
    
    int main() {
        int *ptr;
        int num = 10;
    
        ptr = &num;
    
        // 直接传递一级指针参数
        updatePointer(&ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 传递指针的引用

      在 C++ 中,可以使用引用来传递一级指针参数。在函数中,使用引用符号 & 来声明指针参数,并可以通过指针操作符 *-> 来访问指针指向的值和成员。

    void updatePointer(int *&ptr) {
        // 使用指针操作符 * 和 -> 访问指针指向的值和成员
        ptr = NULL;
    }
    
    int main() {
        int *ptr;
        int num = 10;
    
        ptr = &num;
    
        // 传递指针的引用
        updatePointer(ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二级指针传参

    当将二级指针作为参数传递给函数时,有三种常见的方式:

    1. 传递指针的地址

      可以将二级指针的地址作为参数传递给函数。在函数中,使用三重指针来接收该地址,并可以通过多次指针操作符 *-> 来访问指针指向的值和成员。

    void updatePointer(int ***ptr) {
        // 使用指针操作符 * 和 -> 访问指针指向的值和成员
        **ptr = NULL;
    }
    
    int main() {
        int **ptr;
        int num = 10;
    
        ptr = &num;
    
        // 传递二级指针的地址
        updatePointer(&ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 传递指针的指针

      可以直接将二级指针作为指针参数传递给函数。在函数中,使用指针操作符 *-> 来访问指针指向的值和成员。

    void updatePointer(int **ptr) {
        // 使用指针操作符 * 和 -> 访问指针指向的值和成员
        *ptr = NULL;
    }
    
    int main() {
        int **ptr;
        int num = 10;
    
        ptr = &num;
    
        // 直接传递二级指针参数
        updatePointer(ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 传递指针的引用

      在 C++ 中,可以使用引用来传递二级指针参数。在函数中,使用引用符号 & 来声明指针参数,并可以通过多次指针操作符 *-> 来访问指针指向的值和成员。

    void updatePointer(int **&ptr) {
        // 使用指针操作符 * 和 -> 访问指针指向的值和成员
        ptr = NULL;
    }
    
    int main() {
        int **ptr;
        int num = 10;
    
        ptr = &num;
    
        // 传递二级指针的引用
        updatePointer(ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意事项:

    在C语言中不能直接使用传递指针的引用(例如int *&ptr),因为C语言没有引用类型。


    ok,到这里就暂时将指针进阶的上半部分介绍了,明天或者今晚会再更新下半部分,敬请期待~

  • 相关阅读:
    (附源码)计算机毕业设计SSM金融投资管理系统
    TypeScript
    mysql服务器无法启动问题处理
    Qwik开发使用入门
    vue3 + axios 中断取消接口请求
    深度学习的模型剪枝
    JavaWeb在线问题.系列博文入口
    python爬虫实战——抖音
    Java:阻塞队列BlockingQueue与应用场景
    上半年亏损之下,卫龙第三次冲刺港股IPO
  • 原文地址:https://blog.csdn.net/m0_73075027/article/details/133267542