C指针陷阱
问题一:
#include <stdio.h> int main(int argc, char *argv[]) { int a[5]={ 1,2,3,4,5 }; int *p =(int *)(&a+1); printf("%d,%d\n",*(a+1),*(p-1)); return 0; }
答案结果:2,5
解析:a 和&a的地址一样,但是意思不一样,a是数组的首地址,也就是a[0]的地址;
&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],而&a+1是下一个对象的地址,即a[5]。
所以:p实际上是a[5]的地址,但是p本身是指向int类型数据的指针,所以p-1只会减去sizeof(int*)。
注意:p=&a这样写法在ANSI C中是非法的,因为&a是一个指向数组的指针,而p是一个指向整形变量的指针,他们类型不匹配
问题二:
二维数组那点事:二维数组在内存中占据连续的空间,在内存中从上到下存储各行元素,在同一行中按照从左到右的顺序存储,因此我们可以根据行号和列好
来计算出相对于数组首地址的偏移量,从而找到对应的元组,比如:arr[row*columns+column]
问题三:
1, 以指针类型出现:
C语言中,指针类型值的本质为地址。
C语言规定,不同类型的指针,不可以做相减操作,只有同类才可以进行减操作。比如同样是char*,或者同样是int*等。注意int *和int**,即一维指针和二维指针属于不同类型。
同类型相减的计算原则为
T *a, *b;
a-b=(a与b值的算术差值)/sizeof(T);
2, 以整型变量形式。比如将地址值转为long型存储,这时地址本身已经转换成了一个整型变量,所以相减结果就是值的算术差。
3,两个Int型变量的地址之差就是这两个地址中间可以有多少个int型变量。(这是因为C语言可以根据变量的类型来决定地址增加的实际空间。比如你定义一个int指针int*p,
p=p+1时,其实在内存地址中实际加4,因为int在C中4个字节。)