我认为z
的值应该是40,因为a[5]
有20个元素,它和a[3]
之间的空间也有20个元素,但是z
的实际值是2。
有人能解释一下这个概念吗?
#include <stdio.h>
int main()
{
int a[10][20];
int z = &a[5] - &a[3];
printf("%d\n", &a[3]); // the address information is 6421740
printf("%d\n", &a[5]); // the address information is 6421900
printf("%d\n", z); // z value is 2. why?
}
3条答案
按热度按时间mbjcgjjk1#
指针运算以所指向类型的单位进行。
在本例中,
a[5]
和a[3]
都是int [20]
类型数组的元素,&a[5]
和&a[3]
都是int(*)[20]
类型,它们相距2个数组元素,因此它们之间的差为2。基础类型是否也是数组并不重要。
jhiyze9q2#
根据C标准(6.5.2.1数组下标)
2一个后缀表达式后面跟一个方括号[]中的表达式是数组对象的一个元素的下标指定。下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))。由于应用于二元运算符+的转换规则,如果E1是数组对象(相当于指向数组对象初始元素的指针)且E2是整数,则E1[E2]指定E1的第E2个元素(从零开始计数)。
因此,表达式
a[3]
的计算方式与*( a + 3 )
相同,结果表达式&a[3]
等价于表达式&*( a + 3 )
,而表达式&*( a + 3 )
又等价于( a + 3 )
。同样,表达式
&a[5]
与表达式( a + 5 )
是等价的。所以
&a[5] - &a[3]
的差值可以像( a + 5 ) - ( a + 3 )
一样计算得到2
,也就是说在&a[5]
和&a[3]
这两个地址之间只有两个int[20]
类型的元素。另一方面,如果你写
( int * )&a[5] - ( int * )&a[3]
,也就是说,如果数组被解释为int
类型的一维数组,你会得到2 * 20
,它产生你所期望的值40
。pkln4tw63#
它和a[4]之间的空间也有20个元素
不,a[4]的
element
具有20个int
的数组类型。它不是int型。它被称为指针算术。它不对字节或字符起作用,只对指针类型起作用。
&a[3]
具有指向int[20]
的指针的类型。&a[5]
具有指向int[20]
的指针的类型,并且它从&a[3]
定位两个(2)int[20]
数组。用一个更简单的例子来解释要容易得多。
https://godbolt.org/z/KoKn8sM5b