【问题标题】:What is a pointer to array, int (*ptr)[10], and how does it work?什么是指向数组的指针,int (*ptr)[10],它是如何工作的?
【发布时间】:2021-01-12 13:01:15
【问题描述】:
int (*ptr)[10];

我原以为 ptr10 整数的指针数组。

我不明白它是如何指向10 整数数组的指针。

【问题讨论】:

标签: c++ arrays c pointers pointer-to-array


【解决方案1】:

指向 10 个数组的指针 ints 意味着指向 10 个元素的数组,不多也不少,或者如果您有一个二维数组,则指向此类数组的给定行,前提是它正好有 10 列。

指向intint *ptr[10] 的指针数组就是这样,它有10 个指向int 的指针,每个指针都可以分配int 的地址,它可以是数组的一部分与否。

示例 1:

int (*ptr)[10];

int arr[10];
ptr = &arr; //correct, arr has 10 elements

int arr2[12]; 
ptr = &arr2; //not correct, arr2 does not have 10 elements

此类指针可用于指向行数不定但列数固定的二维数组。

示例 2:

int arr[5][10];
ptr = arr; //correct, pointer to the 1st row of a 2D array with 10 cols
ptr++; //now points to the second row        
    
int arr2[5][12]; 
ptr = arr2; //not correct, incompatible pointer, has too many cols

示例 3:

int(*ptr)[3];

int arr[2][3] = {{1, 2, 3}, {4, 5, 7}};
ptr = arr;

printf("%d", ptr[1][2]); //array indexing is identical as using arr[1][2] 

指针数组与指向数组的指针

当需要动态分配/释放内存时,数组指针的优势就出现了:

以 4 行 5 列的二维数组为例:

int (*ptr)[5]; 
ptr = calloc(5, sizeof *ptr); //simple assignment

free(ptr); //simple deallocation
int *ptr[5];

for (int i = 0; i < 5; i++)  //each pointer needs it's own allocation
    ptr[i] = calloc(5, sizeof **ptr);

for (int i = 0; i < 5; i++)  //each pointer needs to be freed
    free(ptr[i]);

另一方面,如果你有一个指针数组,你可以有一个 uneven 数组,也就是说第一行可以有 10 个ints,但第二行可以有 20 个:

int *ptr[5];

for (int i = 0; i < 5; i++)
    ptr[i] = calloc( i + 1, sizeof **ptr);

在上面的示例中,二维数组的第一行空间为 1 int,第二行空间为 2,第三行空间为 3,依此类推。

【讨论】:

    【解决方案2】:

    我喜欢这样阅读:(已经发布了很好的答案)

    int (*ptr) [10];
         ^ a pointer
               ^ to an array of 10
    ^ ints
    

    int* ptr[10];
            ^ array of 10
       ^ pointer to int
    

    【讨论】:

    • 你的也不错:)
    【解决方案3】:

    ptr 是“指向 10 个 int 数组的指针”类型。在您的声明中,它未初始化,因此它不指向任何对象。让它指向一个数组:

    int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    // initialize in the declaration:
    int (*ptr) [10] = &arr;
    
    // or after:
    int (*ptr) [10];
    ptr = &arr;
    

    【讨论】:

    • 不是我的反对意见。我看到的唯一不准确之处是指针是默认初始化的(具有不确定的值),而不是未初始化。
    【解决方案4】:

    在表达式和声明中,后缀运算符[]() 的优先级高于一元*。因此,声明

    T *a[N]; // a is an array of pointer to T
    T *f();  // f is a function returning pointer to T
    

    被解析为

    T *(a[N]); // result of a[i] will be dereferenced
    T *(f());  // result of f() will be dereferenced
    

    如果你想要一个指向数组的指针或一个指向函数的指针,你必须明确地将 * 运算符与指针表达式组合在一起:

    T (*a)[N]; // result of *a will be subscripted
    T (*f)();  // result of *f will be executed
    

    指针不必是一个简单的标识符——你可以有一个函数返回一个指向数组的指针:

    T (*f())[N]; // result of *f() will be subscripted
    

    或指向函数的指针数组

    T (*a[N])(); // result of *a[i] will be executed
    

    【讨论】:

      【解决方案5】:

      声明给出了如何使用变量的“图片”。1int (*ptr) [10] 表示“当(*ptr)[i] 在表达式中使用时,它就是int。”由此我们可以推导出ptr的类型:

      • 由于(*ptr)[i]int(*ptr) 必须是int 的数组。
      • 由于(*ptr)int 的数组,*ptr 必须是int 的数组。
      • 由于*ptrint 的数组,ptr 必须是指向int 数组的指针。

      脚注

      1 Kernighan 和 Ritchie,C 编程语言,1978 年,第 90 页。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-10
        • 2022-01-08
        • 2021-07-28
        • 1970-01-01
        • 2010-11-25
        • 2018-04-09
        • 1970-01-01
        相关资源
        最近更新 更多