*(a+2)
和*(a[2])
之间的差异是由于a+2
和a[2]
的不同类型,以及C将数组自动转换为指针.a+2
指向数组,*(a+2)
是array.a[2]
是一个数组,*(a[2])
是一个int
.
C有一条规则,即表达式中使用的数组自动转换为指向其第一个元素的指针,除非它是sizeof
的操作数、一元&
的操作数或用于初始化数组的字符串文字.
因此,a + 2
的判断是:
a
是由两个元素的四个数组组成的array.
- 该数组会自动转换为指向其第一个元素的指针,因此结果为
&a[0]
,这是指向包含两个元素的数组的指针.
- 加上2将其调整为指向
a
中更多的两个元素.
- 最终结果是
&a[2]
,这是一个指向两个元素数组的指针.
a[2]
的判断结果为:
a[2]
被指定为等同于*(a+2)
.
a+2
的计算结果如上所述,得到&a[2]
,这是一个指向两个元素数组的指针.
- 应用
*
将生成a[2]
,这是一个由两个元素(a[2][0]
和a[2][1]
)组成的array.
- 该数组自动转换为指向其第一个元素
&a[2][0]
的指针,这是指向int
的指针.
在printf(" a + 2 = %p, a[2] = %p\n", a + 2, a[2]);
年中,印刷的两件事是:
a+2
,从上面我们知道是&a[2]
.
a[2]
,从上面我们知道是&a[2][0]
.
这两个地址是存储器中相同点的地址--数组a[2]
从其第一个元素a[2][0]
开始的相同位置开始.因此,打印它们会打印出相同的价值也就不足为奇了.(从技术上讲,您应该通过将这些地址转换为void *
来打印它们,因为%p
转换被指定为期望void *
参数.)
在printf(" *(a + 2) = %d, *(a[2]) = %d\n", *(a + 2), *(a[2]));
年中,印刷的两件事是:
*(a + 2)
.同样,a + 2
是&a[2]
,它是指向两个int
的数组的指针.应用*
将生成该array.该数组被自动转换为指向其第一元素的指针,&a[2][0]
.用%d
打印是错误的,因为%d
被指定为需要int
个参数,但您给它传递了一个指针.打印的"826886912"是地址部分的十进制表示,31494b0016.(这并不总是结果.C标准没有定义打印带有%d
的地址时的行为.)
*(a[2])
.从上面看,a[2]
等于&a[2][0]
.当应用*
时,这将生成a[2][0]
,即int
.该int
的值被打印为十进制数字.