#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) 的输出? `
对于输出指针的初学者,您需要使用转换说明符
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
。
我会用更简单的话解释它:
int (*ptr)[3]=arr_2D;
定义了 ptr
指向由三个 int
元素组成的 array的指针。
(ptr + 1)
给出一个指向由三个 int
元素组成的数组的指针
*(ptr + 1)
的指针会给出一个包含三个
int
元素的 array。
array
用于表达式(如函数参数)时,它会衰减为指向其第一个元素的pointer。
(ptr + 1)
和衰减的
*(ptr + 1)
引用内存中的相同位置,因此
printf
将打印相同的值。唯一的区别是指针的type。