指针算术(char *)& a [1] - (char *)& a [0] == 4

时间:2013-12-10 05:14:04

标签: c pointers casting

如果a是一个int数组,(char*) &a[1] - (char *)&a[0]等于4,而&a[1] - &a[0]等于1.为什么会这样?

3 个答案:

答案 0 :(得分:5)

指针数学运算的大小与其指向的数据结构有关。这是因为如果我这样做:

int array[10] ;
int * p = array ;

p ++ ;

我希望p指向第二个int,而不是两个元素中间的一些记忆。

所以&a[1]&a[0]相差四个字节,但要求它&a[1] - &a[0]询问它有多少ints分开。当您将其投放到char时,您需要根据char的大小来计算数学。

答案 1 :(得分:3)

当你这样做时

&a[1] - &a[0]

因为a是一个int数组,所以假定是一个隐式(int *)指针,即

(int *)&a[1] - (int *)&a[0]

因此,由于两者都是指向int的类型指针,因此它们的差异为1。

但是当你这样做的时候 -

(char*) &a[1] - (char *)&a[2]

假设int是4个字节,char在编译器上是1个字节,差异将是4,因为a的每个元素都是int并且有4个字节。

答案 2 :(得分:0)

这是程序员将指针视为只是地址的常见问题。这是错误的做法。为了让编译器创建适当的低级代码,它必须知道关于指针的更多信息,而不仅仅是它指向的内存位置。附加信息是指针指向的对象的大小。这一切都包含在指针类型中,并且对于指针算法是必需的。例如:

int a[25] ;
int *i_ptr = a;

printf("address of 1st element %d\n", a);
printf("address of 1st element %d\n", &a[0]);

// address of first element + sizeof(int)
printf("address of 2nd element %d\n", a+1);

// address of first element + sizeof(int)    
printf("address of 2nd element %d\n", &a[1]);

// this one is tricky
// address of first element + sizeof(25*int) ie sizeof(the whole array)
printf("address of JUST AFTER THE ARRAY %d\n", &a+1);

最后是非常棘手的,大多数程序员甚至都不知道。虽然 a 指向数组的第一个元素,并且数组元素类型& a 是完全不同的。它还保留了数组的第一个元素(即数组启动)的地址,但它的类型不同,这表明编译器上的指针算法将基于数组大小而不是元素大小。

给出:

address of 1st element 2881388               +0
address of 1st element 2881388               +0
address of 2nd element 2881392               +4
address of 2nd element 2881392               +4
address of JUST AFTER THE ARRAY 2881488    +100

每当您使用 & 运算符获取某些内容的地址时,它都会与之关联,并允许稍后使用该类型的指针进行计算。

请记住,指针 void * 没有与之关联的任何类型信息,您可以对其执行算术运算。