指针二三事

来源:互联网 发布:电子狗升级软件下载 编辑:程序博客网 时间:2024/05/11 23:06

 指针

最近看了点指针的东西,随便记些下来,就当是读书笔记了。

指针(pointer)是对“数据对象或函数”的一种引用。通常管理大量数据的有效方法,不是直接处理数据本身,而是使用指向数据的指针。这样无需在内存中移动数据。

指针代表一个“对象或函数”的“地址和类型”。注意,不光是地址,还有类型。如果一个对象或函数具有T类型,那么指向它的指针就具有一个衍生类型“指向T指针”。

 

空指针,当把一个空指针常量转换为指针类型,所得到的结果就是空指针。空指针常量是一个值为0的整数常量表达式,或者把这样的表达式转型为void*类型。NULL宏正事空指针常量,它被定义在stdlib.h、stdio.h以及许多其他头文件中。

void指针,指向void的指针,或者简称为void指针,是类型为void*的指针。因为没有对象的类型是void,所以void*被称为万能的指针类型。换句话说,void指针可以代表任何对象的地址,但不代表该对象的类型。如果想存取内存内的对象,必须先把void指针转换为合适的对象指针。

 

初始化指针,具有自动生存周期的指针变量,一开始是没有定义值的,除非声明的同时提供显式的初始化器。被定义在任何语句块内的所有变量,只要没有被声明为static,就具有自动生存周期。

指针的声明可能包含类型限定符const、volatile、restrict。类型限定符const和volatile可以置于指针类型本身之前,或者置于所指向对象类型之前。

 

限定指针,C99中新增限定符restrict,此限定符只能用于对象指针。“具有restrict限定符”的指针被称为限定指针(restrict pointer)。有限定符restrict的指针和它所指向对象之间,有一种特别的关系:在指针的生存周期内,如果这个对象需要修改,只有使用此restrict指针来存取。举个例子:

memcpy()在string.h头文件是这么声明的:

           void *memcpy( void * restrict dest,  const void * restrict src,  size_t   n);

此函数复制n个字节的内存语句块,从src地址复制到dest地址。因为两个指针参数都是限定的,你必须确定此函数不会使用这两个参数来存取相同的对象:换句话说,要确定源语句快和目的语句块没有重叠。如下:

     char a[200];

     memcpy(a+100, a, 100);    //合法,没有重叠

     memcpy(a+1,  a,   199);     //不合法,有重叠

 

数组的指针和指针的数组,下列代码是数组的指针即指向数组的指针(不是指向数组第一个元素的指针)

     int (* arrPtr)[10] = NULL;

指针数组(也就是,“元素类型为指针类型”的数组)常常是二维数组很方便的替代品。通常这种数组中的指针会指向动态分配的内存语句块。

 

指向函数的指针,当调用一个函数的时候,可能不只是传入要被处理的数据,还可能希望传入指向子程序的指针,来决定如何处理数据。也可以在数组内存储函数指针,然后使用数组的索引号来调用这些函数。比如:

double Add(double x, double y) {return x + y};

double Sub(double x, double y) {return x -  y};

double Mul(double x, double y) {return x * y};

double Div(double x, double y) {return x /  y};

 

double (*funcTable[5])(double, double) = { Add, Sub, Mul, Div};