This question already has answers here:
Closed 6 years ago.
Pointer arithmetic for void pointer in C
(8个答案)
我只是无法理解下面程序中的错误。我所做的是将一个大小为5的数组的地址分配给一个类型为
铸造是很好的,但在此之前,程序如何计算
为了更好地突出整个内容,我还使用了一个指针
嘘!!最后两个正确的
0023FF25
0023FF38
(8个答案)
我只是无法理解下面程序中的错误。我所做的是将一个大小为5的数组的地址分配给一个类型为
(*)[]
的指针ptr。没有类型不匹配的情况,就目前而言,这是可以的。但是我想打印ptr+1的值。正如我所料,它显示了一个关于未指定边界的错误,但是它忽略了当我将它转换为ptr+1
类型时,相同的void*
如何工作。铸造是很好的,但在此之前,程序如何计算
ptr+1
,因为它根本不知道界限?它如何知道是向前移动5个元素,还是向前移动8个元素,或者向前移动任何元素?为什么(void*)ptr+1
不显示与ptr+1
相同的错误?为了更好地突出整个内容,我还使用了一个指针
ctr
,它被显式声明为(*)[5]
类型,而不是(*)[]
。请告诉我背后的技术原因。谢谢。#include<stdio.h>
int main(void)
{
int ar1[5]={1,5,3,8,9};
int (*ptr)[]=&ar1,(*ctr)[5]=&ar1;
printf("%p\n",ptr+1); //ERROR about unspecified bounds
printf("%p\n",(void*)ptr+1); //It's ok
printf("%p\n",ctr+1); //It's ok
}
嘘!!最后两个正确的
printf()
不产生相同的值。如果我注释掉不正确的printf("%p\n",ptr+1);
行,这是输出。0023FF25
0023FF38
PSST!!
我又检查了一遍,在ptr+1
的(void*)ptr+1
部分中,1
只是被加到ptr
的数值中。发生了什么事? 最佳答案
请告诉我背后的技术原因。
技术原因是,在添加一个实例时,编译器会尝试跳转到该类型的下一个实例。
示例:向int
指针添加一个指针将使其增加四个字节,因为int
的长度为4字节,然后它将指向下一个int。
在您的示例中,ptr从未指定大小。不可能跳到下一个元素,因为这个元素的大小未知。一旦您通过使它指向一个正好由5个元素组成的数组来指定大小,它就会再次工作。
当将ptr铸造成空腔时,再次很容易进入下一个元素。编译器只增加了一个字节。
在您的跑步中:ptr
是0023FF24
((void*)ptr) + 1
是0023FF25
(一个“void”元素的基址加1字节)ctr
是0023FF24
(与ptr相同)ctr + 1
是0023FF38
(基址,对于sizeof(int)
的一个元素加上20(5*int (*)[5]
)字节)
关于c - 对于(* ptr)[],为什么printf(“%p”,(void *)ptr + 1)有效,但printf(“%p”,ptr + 1)不起作用? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16335883/
10-14 22:17