“指向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
,而不是分配给x
, y
是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
索引值。