C 区别于;指向int的指针;及;指向整数数组的指针; intmain() { int(*x)[5];//指向整数数组的指针 int y[6]={1,2,3,4,5,6};//整数数组 int*z;//指向整数的指针 z=y; 对于(int i=0;i
谁知道-此代码显示未定义的行为:C 区别于;指向int的指针;及;指向整数数组的指针; intmain() { int(*x)[5];//指向整数数组的指针 int y[6]={1,2,3,4,5,6};//整数数组 int*z;//指向整数的指针 z=y; 对于(int i=0;i,c,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++)
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;
}
要回答标题中的问题,请参阅comp.lang.c常见问题解答:
但是,您发布的代码还有其他问题(您正在将
y
,而不是&y
分配给x
,并且y
是一个6元素数组,但是*x
是一个5元素数组;这两者都应该会生成编译警告)。首先,您的代码不会编译。数组的类型为int[6]
(6个元素),而指针的类型为int(*)[5]
。由于类型不同,无法使此指针指向该数组
其次,当您初始化(分配)这样的指针时,您必须使用数组上的&
:x=&y
,而不仅仅是代码中的普通x=y
我假设您只是简单地键入了代码,而不是复制粘贴真正的代码
第三,关于内部表示。通常,在实践中,您应该期望所有数据指针使用相同的内部表示。此外,在上述赋值之后(如果写入正确),指针将具有相同的数值。
int(*)之间的差异[5]
和int*
仅存在于概念层面,即语言层面:类型不同。这会产生一些后果。例如,如果您增加z
,它将跳转到数组的下一个成员,但如果您增加y
,它将跳转到整个数组等。因此,这些指针不存在不要真的“做同样的事情”。简短的回答是:有区别,但你的例子是有缺陷的
答案很长:
区别在于int*
指向一个int类型,但是int(*x)[6]
指向一个包含6个int的数组
是未定义的**行为,您知道这是两种不同的类型,但在C中,您可以随心所欲。我只使用指向六个整数数组的指针
以这个修改后的示例为例:
x = y;
将被打印。然后,我们得到x[0]
。x[0]只是一个6个整数的数组。C中的数组是第一个元素的地址。因此,将打印y
的地址,然后在下一次迭代中打印下一个数组的地址。例如,在我的机器上:
1 2 3 4 5 6
如您所见,连续地址之间的差异只不过是:
1 2 3 4 5 6 109247792 109247816 109247840 109247864 109247888 109247912
总之,这是两种不同的指针类型
**我认为这是未定义的行为,如果有错误,请随时更正我的帖子。希望此代码有帮助
#包括
#包括
#定义MAXCOL 4
#定义MAXROW 3
int main()
{
int i,j,k=1;
int(*q)[MAXCOL];//指向整数数组的指针
/*因为malloc被类型转换为“int(*)[MAXCOL]”,并且
元素(如*q)的长度为16字节(我假设为4字节int),
在所有3*16中,将分配48个字节*/
q=(int(*)[MAXCOL])malloc(MAXROW*sizeof(*q));
对于(i=0;i人们应该理解(*x)[i]
的内部表示。在内部,它表示为
*((*x)+i)
,它只不过是x指向的数组的第i个元素。这也是指针指向2d数组的一种方法。2d数组中的行数无关
例如:
#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");
}
}
这里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)的值,依此类推
现在,一维数组可以被视为只有一行、列数相同的二维数组
int arr[][2]={{1,2},{3,4}};
int (*x)(2);
x=arr; /* Now x is a pointer to the 2d array arr.*/
这意味着x
是指向具有6个整数的数组的指针。因此(*x)[i]
相当于*(*x)+i
将以索引值y
\include>打印
int y[6] = {1,2,3,4,5,6};
int (*x)[6];
x =y;
内部主(空)
{
int(*x)[6];//指向整数数组的指针
int y[6]={11,22,33,44,55,66};//整数数组
int*z;//指向整数的指针
int i;
z=y;
对于(i=0;i希望此代码有助于:
#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;
}
更新:
您可以注意到,指向整数的指针增加了4个字节(大小为32位整数),而指向整数数组的指针增加了20个字节(大小为int arr[5],即大小为5 int,每个32位)。这说明了两者之间的区别。int(*)[5]
和int*
可能存在于符号表中……这并不是说这种区别会改变你的观点。@dmckee:我不知道你的确切意思。这是一个C问题。在C中,名称通常不会损坏,这意味着符号表中不会有任何差异(如果我理解正确的话)。符号表是编译器保存与每个变量相关的类型信息的地方;也就是说,编译器将在这里查看如何增加指针。这个问题有点让我吃惊。我想我会避免int(*x)[]样式声明永远存在。@Sandip:代码编译是因为在默认模式下GCC错误检测过于松散。它将违反约束的情况报告为警告。您的x=y
赋值确实是一个错误。
int arr[][2]={{1,2},{3,4}};
int (*x)(2);
x=arr; /* Now x is a pointer to the 2d array arr.*/
int y[6] = {1,2,3,4,5,6};
int (*x)[6];
x =y;
#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;
}
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