This question already has answers here:
Closed 6 years ago.
Pointer arithmetic for void pointer in C
(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铸造成空腔时,再次很容易进入下一个元素。编译器只增加了一个字节。
在您的跑步中:
ptr0023FF24
((void*)ptr) + 10023FF25(一个“void”元素的基址加1字节)
ctr0023FF24(与ptr相同)
ctr + 10023FF38(基址,对于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