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

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机器上正确打印了值

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

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

我假设您只是输入代码,而不是复制粘贴实际代码。

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

简短的回答:有区别,但你的例子有缺陷。

答案很长:

区别在于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! 

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

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

希望这段代码有帮助:

 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的大小)。 这表明了不同之处。

要从标题中回答你的问题,请参阅comp.lang.c FAQ: 由于数组引用会衰减为指针,如果arr是一个数组,arr和&arr之间的区别是什么?

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

谁知道 – 这段代码表现出未定义的行为:

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

希望这段代码有帮助。


 #include  #include  #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 
 #include 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; } 

//输出::

11 22 33 44 55 66

11 22 33 44 55 66

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

人们应该理解(*x)[i]的内部表征。 在内部,它表示为*((*x)+i) ,它只是x所指向的数组的第i个元素。 这也是一种指向2d数组的指针的方法。 行数在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)将打印y索引值。