“指向int”和“指向int数组的指针”之间的区别

时间:2010-03-07 20:18:05

标签: c

int main()
{
    int (*x)[5];                 //pointer to an array of integers
    int y[6] = {1,2,3,4,5,6};    //array of integers
    int *z;                      //pointer to integer

    z = y;
    for(int i=0;i<6;i++)
        printf("%d ",z[i]);

    x = y;
    for(int i=0;i<6;i++)
        printf("%d ",(*x)[i]);

    return 0;
}

以上printfs打印编号1到6 如果“指向整数数组的指针”和“指向整数的指针”可以做同样的事情,它们是否具有相同的内部表示?
编辑:这个代码确实在编译时发出警告,如下面的答案所指出的那样,但它确实在使用gcc的x86_64机器上正确打印了值

8 个答案:

答案 0 :(得分:18)

首先,您的代码无法编译。数组具有类型int[6](6个元素),而指针具有类型int (*)[5]。您不能使此指针指向该数组,因为类型不同。

其次,当您初始化(赋值)此类指针时,您必须使用数组上的&x = &y,而不仅仅是代码中的普通x = y

我认为您只需输入代码,而不是复制粘贴实际代码。

第三,关于内部代表性。通常,在实践中,您应该期望所有数据指针都使用相同的内部表示。此外,在上述分配(如果正确写入)之后,指针将具有相同的数值。 int (*)[5]int *之间的差异仅存在于概念层面,即语言层面:类型不同。它有一些后果。例如,如果你递增z它将跳转到数组的下一个成员,但是如果你递增y,它将跳过整个数组等。所以,这些指针实际上不是“做同样的事情“。

答案 1 :(得分:11)

答案简短:存在差异,但您的例子存在缺陷。

答案很长:

区别在于int*指向int类型,但int (*x)[6]指向6个int的数组。实际上在你的示例中,

x = y;

是未定义的**行为,你知道它们有两种不同的类型,但在C中你可以做你想要的。我只是使用一个指向六个整数数组的指针。

采取这个修改过的例子:

int (*x)[6];                 //pointer to an array of integers
int y[6] = {1,2,3,4,5,6};    //array of integers
int *z;                      //pointer to integer
int i;

z = y;
for(i = 0;i<6;i++)
    printf("%d ",z[i]);

x = y; // should be x = &y but leave it for now!

for(i = 0;i<6;i++)
    printf("%d ",x[i]); // note: x[i] not (*x)[i]

首先,

1 2 3 4 5 6

会被打印出来。然后,我们到达x[0]。 x [0]只不过是6个整数的数组。 C中的数组是第一个元素的地址。因此,将打印y的地址,然后打印下一次迭代中next数组的地址。例如,在我的机器上:

1 2 3 4 5 6 109247792 109247816 109247840 109247864 109247888 109247912

正如您所看到的,连续地址之间的差异只不过是:

sizeof(int[6]) // 24 on my machine!

总之,这是两种不同的指针类型。

**我认为这是未定义的行为,如果错误,请随时更正我的帖子。

答案 2 :(得分:4)

要从标题中回答您的问题,请参阅comp.lang.c常见问题解答:Since array references decay into pointers, if arr is an array, what's the difference between arr and &arr?

但是,您发布的代码还有其他问题(您要为y分配&y,而不是xy是6元素数组,但是*x是一个5元素的数组;这两个都应该生成编译警告。)

答案 3 :(得分:4)

希望此代码有所帮助:

int main() {

    int arr[5] = {4,5,6,7,8};        
    int (*pa)[5] = &arr;
    int *pi = arr;

    for(int i = 0; i< 5; i++) {
        printf("\n%d %d", arr[i], (*pa)[i]);    
    }

    printf("\n0x%x -- 0x%x", pi, pa);
    pi++;
    pa++;
    printf("\n0x%x -- 0x%x", pi, pa);
}

打印以下内容:

4 4
5 5
6 6
7 7
8 8
0x5fb0be70 -- 0x5fb0be70
0x5fb0be74 -- 0x5fb0be84 

<强> 更新: 您可以注意到指向整数的指针增加了4个字节(32位整数的大小),而指向整数数组的指针增加了20个字节(int arr [5]的大小,即每个32位的5个int的大小)。这表明了不同之处。

答案 4 :(得分:2)

谁知道 - 此代码表现出未定义的行为:

printf("%d ",(*x)[i]);

答案 5 :(得分:2)

希望此代码有所帮助。


#include <stdio.h>
#include <stdlib.h>
#define MAXCOL 4
#define MAXROW 3

int main()
{      
      int i,j,k=1;
      int (*q)[MAXCOL];      //pointer to an array of integers

      /* As malloc is type casted to "int(*)[MAXCOL]" and every 
         element (as in *q) is 16 bytes long (I assume 4 bytes int), 
         in all 3*16=48 bytes will be allocated */

      q=(int(*)[MAXCOL])malloc(MAXROW*sizeof(*q)); 

      for(i=0; i<MAXROW; i++)
        for(j=0;j<MAXCOL;j++)
          q[i][j]=k++;


      for(i=0;i<MAXROW;i++){
        for(j=0;j<MAXCOL;j++)
          printf(" %2d ", q[i][j]);
        printf("\n");         
      } 
}

答案 6 :(得分:0)

#include<stdio.h>

int main(void)
{
    int (*x)[6];                 //pointer to an array of integers
    int y[6] = {11,22,33,44,55,66};    //array of integers
    int *z;                      //pointer to integer
    int i;

    z = y;
    for(i = 0;i<6;i++)
        printf("%d ",z[i]);
    printf("\n");

    x = &y;

    for(int j = 0;j<6;j++)
        printf("%d ",*(x[0]+j));

    return 0;
}

// OUTPUT ::

11 22 33 44 55 66

11 22 33 44 55 66

指向数组的指针最适合多维数组。但在上面的例子中我们使用了单维数组。因此,在第二个for循环中,我们应该使用(x [0] + j)和*来打印该值。这里,x [0]表示第0个数组。 当我们尝试使用printf打印值时(&#34;%d&#34;,x [i]); 你会得到第一个值是11,然后是一些垃圾值,因为试图访问第一行数组等等。

答案 7 :(得分:-1)

应该理解(*x)[i]的内部表示。在内部,它表示为 *((*x)+i),它只是x所指向的数组的第i个元素。这也是一种指向2d数组的指针的方法。行数与二维数组无关。

例如:

int arr[][2]={{1,2},{3,4}};
int (*x)(2);
x=arr; /* Now x is a pointer to the 2d array arr.*/

这里x指向所有列中具有2个整数值的2d数组,并且数组元素是连续存储的。因此(*x)[0]将打印arr[0][0](即1),(*x)[1]将打印arr[0][1](即2)的值,依此类推。 (*x+1)[0]将打印arr[1][0]的值(本例中为3)(*x+1)[1]将打印arr[1][1]的值(本例中为4),依此类推。

现在,一个1d数组可以被视为只有一行只有一列的2d数组。

int y[6] = {1,2,3,4,5,6};
int (*x)[6];
x =y;

这意味着x是指向具有6个整数的数组的指针。因此,(*x)[i]等同于*((*x)+i)将打印第i个索引值y