如果a是一个int数组,(char*) &a[1] - (char *)&a[0]
等于4,而&a[1] - &a[0]
等于1.为什么会这样?
答案 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 * 没有与之关联的任何类型信息,您可以对其执行算术运算。