C:如何区分指针数组和指向数组的指针?

问题描述 投票:0回答:0

说我有以下代码。

// x = whatever number

int *arr_of_ptr[x];
int (*ptr_to_arr)[x]

int **p1 = arr_of_ptr;
int **p2 = ptr_to_arr;

我的理解是 arr_of_ptr 是 "dereferencing arr_of_ptr元素的结果是一个int"--因此,arr_of_ptr的元素 arr_of_ptr整数指针. 另一方面,取消引用 ptr_to_arr 结果是一个数组,然后我可以从这个数组中获取整数,因此 ptr_to_arr 指向一个数组.

我也有一个粗浅的理解,数组本身就是指针,而 arr[p] 评价为 (arr + p * sizeof(data_type_of_arr)) 其中名 arr 的第一个元素的指针。arr.

所以,这一切都很好,但有什么办法让我知道,是否有 p1p2pointers to arraysarrays of pointers 在没有预先信息的情况下?

我的困惑主要来自于这样一个事实:(我认为)我们可以评估出 int **p 两种方式。

  1. *(p + n * size) 是什么给我一个int
  2. (*p + n * size) 是什么给我一个int

现在回想起来,这个问题可能用词不当,因为回想起来我自己都有点糊涂了,但我真的不知道如何更好的表达自己。对不起,我的问题是

c arrays pointers
5
投票

最主要的区别是,这个是合法的。

int **p1 = arr_of_ptr;

而这是不合法的

int **p2 = ptr_to_arr;

因为... arr_of_ptr 是一个数组,它可以(在大多数情况下) 衰败 到指向其第一个元素的指针。 因此,由于 arr_of_ptr 属于 int *元素的指针类型为 int ** 所以你可以把它分配给 p1.

ptr_to_arr 然而,它不是一个数组,而是一个指针,所以没有发生衰减。 你试图将一个类型为 int (*)[x] 类型的表达式。int **. 这些类型是不兼容的,如果你试图使用 p2 你不会得到你所期望的。


0
投票
#include <stdio.h>

int main(void) {
    // your code goes here
    int arr[] = {1,2,3};
    int *p1 = &arr[0];
    int *p2 = &arr[1];
    int *p3 = &arr[2];
    int* arr2[3];
    arr2[0] = p1;
    arr2[1] = p2;
    arr2[2] = p3;
    int *p4 = &arr;
    printf("%d\n", sizeof(p4));
    printf("%d\n", sizeof(arr2));
    printf("%d\n", *p4);  // not **p4
    printf("%d\n", **arr2);
    return 0;
}

在上面的代码中 胳肢窝 是一个有3个元素的普通整型数组。 p1, p2p3 是这些元素的正常指针。 arr2 是一个 指数组 储存 p1, p2p3. p4 是一个 数组指针 指向数组 胳肢窝 根据你的问题,你需要区分以下几点 p4arr2 自: p4 是一个指针,它的大小是固定的(8个字节),而 arr2 vaires取决于它包含多少元素(8x3=24)。另外,打印包含在p4中的值时,使用单解引用(*p4)而不是**p4(非法),而打印包含在arr2中的值时,使用双解引用(**arr2)。上述代码的输出是.NET Framework 2.0。

8
24
1
1

0
投票

首先,是

我还有一个粗浅的理解,就是数组本身是指针,arr[p]的值是(arr + p * sizeof(data_type_of_arr)),其中arr这个名字会衰减为arr的第一个元素的指针。

这并不是严格正确的。 数组不是指针。在大多数情况下。表情 的数组类型将被转换("衰减")为指针类型的表达式,表达式的值将是数组中第一个元素的地址。 这个指针值是根据需要计算出来的,并不存储在任何地方。

当数组表达式的操作数为 sizeof, _Alignof或单利 & 操作符,或者说是声明中用来初始化字符数组的字符串文字。

说了这么多。ptr_to_arr指针 类型,而不是数组类型--它不会 "衰减 "到 int **.

鉴于声明

T arr[N];

以下为真。

 Expression        Type            Decays to            Equivalent expression
 ----------        ----            ---------            ---------------------
        arr        T [N]           T *                  &arr[0]
       *arr        T               n/a                  arr[0]
     arr[i]        T               n/a                  n/a
       &arr        T (*)[N]        n/a                  n/a

表达式 arr, &arr[0]&arr 都会产生相同的值(与类型之间的表示方式有任何差异)。 arr&arr[0] 具有相同的类型,"指针到 T" (T *),而 &arr 类型为 "指向N元素数组的指针"。T" (T (*)[N]).

如果你更换 T 带指针类型 P *因此,该声明现在是

P *arr[N];

你会得到以下内容。

 Expression        Type            Decays to            Equivalent expression
 ----------        ----            ---------            ---------------------
        arr        P *[N]          P **                 &arr[0]
       *arr        P *             n/a                  arr[0]
     arr[i]        P *             n/a                  n/a
       &arr        P *(*)[N]       n/a                  n/a

所以根据你的声明,更正确的写法是这样的。

int arr[x];
int *p1 = arr;         // the expression arr "decays" to int *

int *arr_of_ptr[x];
int **p2 = arr_of_ptr; // the expression arr_of_ptr "decays" to int **

/**
 * In the following declarations, the array expressions are operands
 * of the unary & operator, so the decay rule doesn't apply.
 */
int (*ptr_to_arr)[x] = &arr;
int *(*ptr_to_arr_of_ptr)[x] = &arr_of_ptr;

再来一次: ptr_to_arrptr_to_arr_of_ptr指针,而不是数组,也不会衰减到不同的指针类型。

© www.soinside.com 2019 - 2024. All rights reserved.