指向二维数组的指针访问冲突

问题描述 投票:0回答:2
#include <stdio.h>
int main()
{
   int arr_2D[3][3]={ {1,2,3},
                      {11,22,33},
                      {111,222,333} };
    int (*ptr)[3]=arr_2D;
    
    printf("ptr=0x%0X\n",ptr+1); // ptr=0x60FEE4
    
    printf("*(ptr)=0x%0X\n",*(ptr+1)); //*(ptr+1)=0x60FEE4
    return 0;
}

我尝试使用解引用运算符 * 访问存储在 (ptr+1) 中的位置 为什么 ptr+1 的输出等于 *(ptr+1) 的输出? `

c pointers multidimensional-array implicit-conversion
2个回答
0
投票

对于输出指针的初学者,您需要使用转换说明符

p

printf("ptr=%p\n",( void * )( ptr+1) ); // ptr=0x60FEE4

printf("*(ptr)=%p\n", ( void * )*(ptr+1)); //*(ptr+1)=0x60FEE4

使用错误的转换说明符会调用未定义的行为。

由于声明

,表达式 
*( ptr + 1 )
 具有类型 
int[3]

int (*ptr)[3]=arr_2D;

表达式中使用的数组指示符(极少数例外)会转换为指向其第一个元素的指针,

来自 C 标准(6.3.2.1 左值、数组和函数指示符 )

3 除非它是 sizeof 运算符的操作数,或者一元 & 运算符,或者是用于初始化数组的字符串文字, 类型为“类型数组”的表达式将转换为表达式 类型为“指向类型的指针”,指向该类型的初始元素 数组对象并且不是左值。如果数组对象有寄存器 存储类,行为未定义。

因此,具有数组类型

*( ptr + 1 )
并用作参数表达式的表达式
int[3]
被转换为指针类型
int *

尽管在调用 printf 时用作参数的表达式

ptr + 1
*( ptr + 1 )
的类型不同(第一个表达式的类型为
int ( * )[3]
,隐式转换后的第二个表达式的类型为
int *
)它们具有相同的值 - 数组第二“行”占用的内存范围的地址
arr_2D


0
投票

我会用更简单的话解释它:

  1. int (*ptr)[3]=arr_2D;
    定义了
    ptr
    指向由三个 int 元素组成的
    array
    的指针。
  2. (ptr + 1)
    给出一个指向由三个 int 元素组成的数组
    的指针
  3. 取消引用指向数组
  4. *(ptr + 1)
     的指针会给出一个包含三个 
    int 元素的 array
  5. array
     用于表达式(如函数参数)时,它会衰减为指向其第一个元素的 
    pointer
  6. 由于
  7. (ptr + 1)
     和衰减的 
    *(ptr + 1)
     引用内存中的相同位置,因此 
    printf
     将打印相同的值。唯一的区别是指针的 
    type
© www.soinside.com 2019 - 2024. All rights reserved.