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机器上正确打印了值
答案 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
,而不是x
,y
是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
。