指针算术(char *)&a – (char *)&a == 4

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

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

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

我希望p指向第二个int,而不是两个元素之间的一些内存。

因此&a[1]&a[0]相距四个字节,但要求它&a[1] - &a[0]询问它有多少个ints 。 当你把它投射到char时,你会根据char的大小来求数。

当你这样做

 &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个字节。

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

 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 * ,它没有与之关联的任何类型信息,您可以对其执行算术运算。