指针是一个地址,有两个属性,一个是起始地址,一个是长度,起始地址告诉编译器从哪里开始寻址,地址长度由编译器根据指针所指对象的类型进行推断,如int占4字节,double占8字节。int从指定地址向后寻找4字节作为变量的存储单元 。double从指定地址向后寻找8字节作为变量的存储单元
这里补充一点:不同类型的指针+1跳过的字节数是不同的。
1.void指针是一种特别的指针
void *vp
//说它特别是因为它没有类型
//或者说这个类型不能判断出指向对象的长度
2.任何指针都可以赋值给void指针
type *p;
vp=p;
//不需转换
//只获得变量/对象地址而不获得大小
3.void指针赋值给其他类型的指针时都要进行转换
type *p=(type*)vp;
//转换类型也就是获得指向变量/对象大小
4.void指针不能解引用
*vp//错误
因为void指针只知道,指向变量/对象的起始地址
而不知道指向变量/对象的大小(占几个字节)所以无法正确引用
下面讲一下解引用到底是啥玩意(转自百度百科)
"*"的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为“解引用”。也就是说,解引用是返回内存地址中对应的对象。
比如int a=10; int *p=&a;
cout<<*p<<endl; 输出a的值,就是解引用操作。
因为p是一个int类型的指针变量(int*),指向的是一个地址,在p前面加上*,就是解开这个地址,取出里面的值。
5.void*的作用
void * 以定义一个指针变量,但不说明它指向哪一种类型数据.
1.传参:通用类型
可以作为函数模板,链表等参数的通用参数。在使用时,只需要强制类型转换就可以。
2.强制类型转换
有时候由于重载等的干扰,导致需要转换成void *,来进行取地址。
例如,(void *)obj.member,就可以取到member的地址;直接&(obj.member)取到的实际上是obj的开始地址。
3.指向0的地址
(void *)0,指向全是0的地址,相当于NULL。