1

我只是无法理解以下程序中的错误。我所做的是我已经将大小为 5 的数组的地址分配给了类型为ptr(*)[]的指针。没有类型不匹配,就这样就可以了。但是后来我想打印值ptr+1ptr+1 。正如我所料,它显示了一个关于未指定边界的错误。但是当我将它转换为 type 时,它​​只是想念我是如何正常工作的void*

铸造很好,但在此之前,程序如何计算ptr+1,因为它根本不知道界限?它如何知道是向前移动 5 个元素,还是向前移动 8 个元素或向前移动任何元素?为什么不(void*)ptr+1显示与 相同的错误ptr+1

为了更好地突出整件事,我还使用了一个ctr明确声明为 type(*)[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
}

PSST!! 最后两个正确printf()的不产生相同的值。如果我注释掉不正确的printf("%p\n",ptr+1);行,这就是输出。

0023FF25

0023FF38

PSST!!我再次检查了它,在 的ptr+1部分中 (void*)ptr+1,a1只是被添加到 的数值中。ptr这是怎么回事?

4

2 回答 2

1

根据您的代码

int (*ptr)[]

ptr 是一个指向 UNKNOWN 大小数组的指针。所以到目前为止,编译器不知道 ptr 指向的大小。当您尝试进行增量时,编译器仍然不知道要增加多少。指针增量将是 sizeof(pointed element) 的加法。所以你得到错误“未指定的边界”。

现在对于您剩下的两个问题,为了更好地理解,请允许我将您的两个问题重新表述为一个-“为什么(VOID *)表现得像(CHAR *)”??(那是:)?)您的答案是

在C标准(N1256草案):6.2.5-27中:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.

于 2013-05-02T11:37:02.333 回答
0

请告诉我这背后的技术原因。

技术原因是,当添加一个时,您的编译器会尝试跳转到该类型的下一个实例。

示例:向int指针添加 1 会将其增加4,因为 an 的int长度为 4 个字节,然后它将指向下一个 int。

在您的示例中,使用 ptr 您从未指定大小。无法跳转到下一个元素,因为该元素的大小未知。一旦您通过使其指向恰好包含 5 个元素的数组来指定大小,它就会再次起作用。

将 ptr 转换为 void 时,再次转到下一个元素变得容易。编译器只是增加了一个字节。

在你的运行中:

ptr0023FF24

((void*)ptr) + 10023FF25(“void”的一个元素的基地址加上 1 个字节)

ctr0023FF24(与 ptr 相同)

ctr + 10023FF38(基地址,加上 20 ( 5 * sizeof(int)) 字节的一个元素int (*)[5]

于 2013-05-02T10:53:19.047 回答