要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。
指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
int *ptr; //指针的类型是int * char *ptr; //指针的类型是char * int **ptr; //指针的类型是 int **
指针所指向的类型
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如:
int *ptr; //指针所指向的类型是int char *ptr; //指针所指向的的类型是char int **ptr; //指针所指向的的类型是 int * int (*ptr)[3]; //指针所指向的的类型是 int()[3] int *(*ptr)[4]; //指针所指向的的类型是 int *()[4]
指针的值
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。
指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。
以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指向的类型是什么?该指针指向了哪里?
指针的算术运算
char array[22];
int *p=array; //*(p+5) == array[20]
p++; //p指向array[4]
由于地址是用字节做单位的,它把指针ptr的值加上了sizeof(指针所指的类型),在32位程序中,是被加上了4。
eg. ptr+=5;
//将指针ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。现在的ptr所指向的地址向高地址方向移动了20个字节。
Summary: ptr指针每次++,地址前移的字节数为sizeof(ptr的类型); 指针的'-'运算自动除以偏移量——sizeof(type)(eg.离散)
///////////////////////////////http://www.cnblogs.com/ggjucheng/archive/2011/12/13/2286391.html//////////////////////////////////////
把指针作为函数参数
void func(int *p) {} //传p的地址,会修改
注意:
1.指针*运算的优先级,如(*(x))+=3;
2.初始指针,不然会报错,如: //要么让指针指向一个已存在地址,要么给指针分配一个地址。int x; int *ptr=&x;
int ptr[1]; ptr[0]=31415926; //do sth
int tmp[1]; int *ptr=tmp; (*ptr)=3; //init完成 //do sth
//扯淡版
还有其它正式的init函数
int *ptr=new int();
不过看起来第3种可读性比较好