指针总结

来源:互联网 发布:网络配音软件 编辑:程序博客网 时间:2024/05/21 18:34

一、概述

指针就是地址,指针变量就是用于保存地址的变量。

首先考虑内存的结构,内存实际上只有两个属性,一是内存地址,二是地址里存的值,就好像一栋楼有很多房间,房间都有门牌号,房间里住的人也都不一样。

指针的操作只有两种,一是析取(*),二是取址(&),前面说过,关于内存只有地址和值两个概念,那么这两种操作就对应这两个概念的转换,析取就是由地址得到值,取址就是由值得到地址。


二、指针类型

指针存放的是内存地址,32位系统的最大寻址空间是2的32次方,也就是4个字节,因此指针变量的大小是4字节,即是说无论什么类型的指针变量,用sizeof求值得到的都是4.

指针变量的类型,实际上是一种析取规则。例如int *p,int型变量占4个字节,这里就是告诉编译器,要取这个地址的值,就需要将这个地址及其后3个字节的值合起来作为一个值。double* p,就是告诉编译器这个地址后面的8个字节按double型数据方式析取(double型在内存中存放方式与int型不一样)。指向结构体类型的变量也是如此。明确指针的类型不仅是为了解析这个指针,同时也是为了让编译器明确怎样对这个指针进行运算。例如:

int ia;

int *pa = &ia;

这里pa存了一个地址,比如是123456。

那么pa++或者pa+1就代表对该地址加上一个int型所占的空间大小,即是123456+4=123460


比较特殊的是void型的指针变量,无类型即代表这个变量单纯的就表示一个内存地址。任何类型的指针变量都可以赋值给void型指针变量,即是说

int *ip;

char *cp;

double* dp;

void *p;

p = ip;

p = cp;

p = dp;

上面这几种赋值都是正常的,相当于只保留了地址,而不保留解析地址的规则。

然而void型指针变量却不能赋给其它类型的指针变量。例如:

int *ip;

void *p;

ip = p;

这样就是不对的,因为没有明确p指向的变量是什么类型。这里需要用到强制类型转换才能成功,即是

ip = (int *)p;


三、指向指针的指针

指向指针的指针,实际上就是一个存放了另一个指针变量地址的变量。不要把它叫成二重指针之类的东西,这样会很容易把int **p和int a[3][4]这两种东西联想到一起,实际上不是一回事。之所以需要指向指针的指针,是因为有其实际的应用场景。比如我们要写一个分配内存的函数,看下面的代码:

void get_memory(char *p, int num) {        p = (char *)malloc(num * sizeof(int));        return ;}int main(){        char *p = NULL;        get_memory(p, 100);        return 0;}

这段代码本意是想分配一段内存空间,然后让指针p指向该段内存空间。但是由于函数参数传递的是形参,即是说main函数中的p与get_memory中的p有相同的值(都是NULL),但实际上是两个变量,因此将get_memory中的p指向新分配的内存空间并不代表main函数中的p也指向了新分配的内存空间,main函数中的p实际上根本没有变化,还是指向NULL,而在get_memory中的内存也就泄露了。因此需要将代码改成下面这样:

void get_memory(char **p, int num) {        *p = (char *)malloc(num * sizeof(int));        return ;}int main(){        char *mp = NULL;        get_memory(&mp, 100);        return 0;}

p收到的是mp的地址,那么*p就是mp本身,因此对*p赋值就如同对mp赋值一样,因此达到了需要的效果。


四、指针数组与指向数组的指针

指针数组比较容易,其定义如下:

int *a[10];

意思就是一个长度为10的数组,数组里的每个元素都是指向int类型的指针。

指向数组的指针稍微难理解一些,实际上也是一个指针,不过这个指针的类型是数组。在第二部分说过,指针的类型无非是告诉编译器解析这种指针的方式。那么首先看数组这个类型怎么表示。

int a;

这句表示变量a是int类型的,那么看数组的定义:

int a[10];

这句就表示变量a是int [10]这种类型的,虽然看着有些奇怪 ,但实际上这也是一种类型。

因此指向数组的指针的定义就是

int (*a)[10];
这里用括号将*和a括起来首先表明这是一个指针,然后再定义指针的类型是int [10],因此合起来就是这是一个指向长度为10的数组的指针。因此当已知指向数组的指针并且需要取出数组当中的第i个元素时,首先用(*a)表示这个数组,那(*a)[i]就代表第i个元素。

0 0
原创粉丝点击