c - 对于 (*ptr)[],为什么 printf ("%p",(void*)ptr+1) 有效但 printf ("%p",ptr+1) 无效?

标签 c pointers casting indexoutofboundsexception

<分区>

我只是无法理解以下程序中的错误。我所做的是将大小为 5 的数组的地址分配给类型为 (* )[]。没有类型不匹配,就目前而言没问题。但是我想打印值 ptr+1。正如我所料,它显示了关于未指定的边界。但是当我将它转换为类型 void* 时,我只是想念相同的 ptr+1 是如何工作的。

转换很好,但在此之前,程序如何计算 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
}

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

0023FF25

0023FF38

PSST!! 我又检查了一遍,(void*)ptr+1ptr+1 部分,一个 1 只是被添加到 ptr 的数值中。发生了什么?

最佳答案

根据你的代码

int (*ptr)[]

ptr 是指向未知大小数组的指针。所以直到现在编译器还不知道 ptr 指向的大小。当您尝试增加时,编译器仍然不知道要增加多少. 指针增量将增加 sizeof(指向元素)。因此您会收到“未指定边界”错误。

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

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

指向 void 的指针应与指向字符类型的指针具有相同的表示和对齐要求。

关于c - 对于 (*ptr)[],为什么 printf ("%p",(void*)ptr+1) 有效但 printf ("%p",ptr+1) 无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16335883/

相关文章:

c# - Visual Studio 2015 : Invalid "Cast is redundant" warning in interpolated string expression

c - qemu 跟踪哪些指令?

c - 将数组中的元素作为指针传递给 C 中的函数

c - 使用指针的快速排序和冒泡排序,将这两个实现到 calc.c 中

c++ - 多态性 : Runtime-Casting Pointers

swift - 转换一个快速字典([String :AnyObject] ) to a UnsafeMutablePointer

c - 通过结构数组按排序顺序显示年份

c - 许多子进程与单亲通信

c++ - 指向相同类型的对象

c - 指针类型转换为不同的数据类型