我有一个2D数组(int s[4][2]
),我创建了一个指针int (*p)[2]
。
指针p
现在被分配了for循环中第一行元素的地址。
for (int i = 0; i<4; i++)
p = &s[i];
现在,当我尝试使用解除引用来编写数组元素数据时,我得到了错误的值。
printf ("%d \n", *p)
但是,如果我创建另一个指针并将其与前一个指针
链接int *ptr = p;
和取消引用指针ptr
我得到正确的值。
printf ("%d \n", *ptr)
当两个指针指向同一个地址时,为什么一个指针(*ptr
)按预期工作而另一个指针(*p
)不返回预期值?
答案 0 :(得分:8)
如果p
是指向数组的指针,那么*p
是数组的2个整数(int[2]
)。所以,你不能打印这样的数组元素:
printf ("%d \n", *p);
要通过指针p
打印数组元素,您需要执行以下操作:
printf ("%d \n", (*p)[0]); /* first element */
printf ("%d \n", (*p)[1]); /* second element */
答案 1 :(得分:2)
p
不是指向int
的指针。它是指向两个int
的数组的指针。因此*p
也是两个int
的数组。由于它不是int
,因此使用%d
进行打印会产生未定义的行为。
你将无法链接&#34;由于类型不匹配导致ptr
到p
(ptr
是指向int
的指针,p
(如前所述)是指向数组的指针两个int
。因此,分配ptr = p
将无法编译。如果您强制编译(例如ptr = (int *)p
),那么ptr
和p
将具有相同的值(即它们将在内存中标识相同的位置)但不同的类型(即取消引用它们以不同的方式解释该内存的内容)。
p
的值(忽略类型)将是s[0][0]
的地址。同样,ptr
的值将是s[0][0]
的地址。
因此printf("%d\n", *ptr)
将打印s[0][0]
的值。
答案 2 :(得分:2)
当两个指针指向同一个地址时,为什么一个指针(* ptr)按预期工作而另一个(* p)不返回预期值?
*p
评估为int[2]
,一个数组。
将一个数组int[2]
传递给一个函数,导致将一个指针传递给数组的 st 元素,int*
。
*ptr
评估为int
。
将int
传递给某个函数会导致将int
传递给函数...: - )
答案 3 :(得分:1)
通过
int (*ptr)[2] ; // means int[2]<-(*ptr)
你有一个指向两个整数数组的指针
现在为指针p分配了行的第一个元素的地址 在for循环中。
这是不正确的,从技术上讲,p被分配了整个int[2]
块的地址(提示:使用sizeof
来验证大小)。
有什么问题
printf ("%d \n", *ptr)
*ptr
本身并不包含整数,但它保存int[2]
的第一个元素的地址,即*ptr
本身就是指针。
一个工作的例子是
int main(void)
{
int i;
int s[4][2]={{0,1},{2,3},{4,5},{6,7}};
int (*ptr)[2];
for(i=0;i<4;i++)
{
ptr=&s[i];
printf("i:%d\n",i);
printf("Element 1 : %d\n",(*ptr)[0]);
printf("Element 2 : %d\n",(*ptr)[1]);
/* Replacing (*ptr)[1] with *((*ptr)+1) gives you the same
* results
*/
}
return 0;
}
<强>输出强>
i:0
Element 1 : 0
Element 2 : 1
i:1
Element 1 : 2
Element 2 : 3
i:2
Element 1 : 4
Element 2 : 5
i:3
Element 1 : 6
Element 2 : 7