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

gkn4icbw  于 2023-11-17  发布在  其他
关注(0)|答案(2)|浏览(122)
#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)的输出?`

yqkkidmi

yqkkidmi1#

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

  1. int (*ptr)[3]=arr_2D;ptr定义为指向三个int元素的array的指针。
  2. (ptr + 1)给出了一个指向数组指针,该数组包含三个int元素
    1.解引用指向数组*(ptr + 1)的指针会给出一个由三个int元素组成的数组
    1.当array在表达式中使用时(如函数参数),它衰减为指向其第一个元素的指针
    1.由于(ptr + 1)和衰变的*(ptr + 1)引用内存中的相同位置,printf将打印相同的值。唯一的区别是指针的**类型 *。
i7uq4tfw

i7uq4tfw2#

对于输出指针的初学者,需要使用转换说明符p而不是X

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

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

字符串
conversuib说明符X被设计为输出类型为unsigned int的对象。
使用错误的转换说明符会引发未定义的行为。
由于声明了指针ptr,表达式*( ptr + 1 )的类型为int[3]

int (*ptr)[3]=arr_2D;


这相当于

int (*ptr)[3] = &arr_2D[0];


在表达式中使用的数组指示符(很少有例外)被转换为指向其第一个元素的指针。
来自C标准(6.3.2.1左值、数组和函数指示符)
3除非它是sizeof运算符的操作数,或一元&运算符,或用于初始化数组的字符串文字,否则具有类型“array of type”的表达式将转换为具有类型“pointer to type”的表达式,该类型指向数组对象的初始元素,并且不是左值。如果数组对象具有寄存器存储类,则行为未定义。
因此,具有数组类型int[3]并用作参数表达式的表达式*( ptr + 1 )被隐式转换为指向其第一个元素的指针类型int *
虽然在printf调用中用作参数的表达式ptr + 1*( ptr + 1 )的类型不同(第一个表达式的类型为int ( * )[3],隐式转换后的第二个表达式的类型为int *),但它们具有相同的值-数组arr_2D的第二“行”所占用的内存范围的地址。
因此,您有以下数组类型表达式的隐式转换链

int[3][3] (arr_2D)    -> int ( * )[3] (ptr)
int[3] (*( ptr + 1) ) -> int *

相关问题