指针边角料——void*指针, const指针, 函数指针等

void*指针

        void*指针是一种特殊的指针类型,可以用于存放任意对象的地址。void*指针和其他指针一样,存放着一个地址,但是这个地址的类型是未知的。

指向常量的指针

        指针既可以指向常量也可以指向变量。指向常量的指针( pointer to const )并不是说其所指向的对象必须是一个常量(可以是变量,变量本身也是可以被赋值的,同时指针p也可以指向其他地址),而是要求不能通过该指针改变对象的值(可以通过其他途径改变对象的值)。

const int pi = 3;//pi 是一个常量,其值不能更改

int *ptr = π//错误!ptr是一个普通指针,不能指向一个常量

const int *cptr = π//cptr是一个指向常量的指针

*cptr = 42;//错误!不能给cptr赋值

【这里 const int *cptr = π与int const *cptr = π是一样的】 

        一般地,指针的类型必须与其所指向的对象的类型保持一致。这里是个例外,允许一个指向常量的指针指向一个非常量对象:

int dval = 3;//dval是一个变量

cptr = &dval;//正确

常量指针(const 指针) 

        把指针本身定义为常量的指针叫常量指针( const pointer )。常量指针在定义时就必须初始化,一旦初始化完成,其值就不能改变了,也就是地址不再发生变化了。

int Num = 0;

int *const curNum = &Num;//curNum是一个常量指针,指向一个int对象

const int Num2 = 1;

const int *const curNum2 = &Num2;//curNum2是一个常量指针,指向一个int型常量对象

        常量指针是说指针本身是一个常量,并不意味着不能通过指针修改其所指向的对象的值。能否修改所指对象的值只和该对象的类型有关。若所指对象被const修饰,也就是说是一个常量对象,则不能修改,否则能修改。

const数组

const int a[] = {1,2,3,4};

       其实数组变量本身就是const指针,而这里的const的作用是表示数组中的每一个元素都是不可变的,所以数组中的元素只能通过初始化来赋值。

复制指针

        混淆指针与指针所指向的数据,常见于字符串使用的情形:

char = *p, *q;

p = " xyz ";

        我们可能认为p的值就是“xyz”,但是实际情况并非如此,p的值实际上是一个指向由‘x’,‘y’,‘z’,‘\0’构成的数组第一个元素的指针。

        在指向语句q = p后,p和q都成为指向该数组第一个元素的指针。但是需要注意的是,这个赋值语句并没有同时复制内存中的字符。也就是说,复制指针并不同时复制指针所指向的数据。

        在执行语句 q[1] = 'Y'; 后,q所指向的内存存储的是“xYz”,p和q指向的是同一个存储空间,那么p所指向的存储空间存储的字符串也是“xYz”。

【ANSI C标准中,禁止对string literal作出修改。K&R C对此说明,试图修改字符串常量的行为是未定义的。某些C编译器还允许q[1] = 'Y';这种修改行为,如LCC v3.6。但是,这种写法不提倡。】

NULL指针

        在C语言中,将一个整数转换为一个指针所得到的结果取决于具体编译器的实现。但是对于常量0,编译器保证由0转换而来的指针不等于任何有效的指针。常量0对被NULL替代。

#define NULL 0

        注意:常量0被转换为指针使用时,这个指针不可以被解引用。换句话说,当我们将0赋值给一个指针变量时,不可以用该指针指向内存中存储的内容。下面这句是非法的:

if ( strcmp( p, ( char *) 0) == 0)...

        因为库函数strcmp的实现中包含查看它的指针参数所指向的内存中的内容的操作。 

        NULL 指针并不指向任何对象。记住,除非用于赋值或者比较运算,出于其他任何目的使用NULL指针都是非法的。

函数指针

        函数指针指向的是函数而非对象。要想声明一个可以指向函数的指针,只需用指针替换函数名:

bool lengthCompare( const string &, const string & );//函数

       定义一个函数指针 pf ,pf 指向函数 lengthCompare ,函数的两个参数是 const string 的引用,返回值是 bool 型。 

bool (*pf)( const string &, const string & ); 

        注意上式函数指针要小括号包住。如若不加括号,意义截然不同:

 bool  *pf ( const string &, const string & ); 

        其意义为 pf 是一个返回值为 bool * 的函数(pf 是一个普通函数,只是其返回类型为 bool * )。  

指向数组的指针

        声明一个指向数组的指针,形似:

int  ( *pi )[ 10 ];

( *pi ):pi是一个指针;

( *pi )[ 10 ]:pi是一个指向数组的指针;

int  ( *pi )[ 10 ]:pi是一个指向整型数组的指针。

        看两组语句是否合法:

//第一组

int vector[ 10 ] ;

int *vp = vector; 

//第二组

int matrix[ 3 ][ 10 ];

int *mp = matrix; 

        一般地,指针的类型要与其所指向的对象的类型保持一致。 vector 和 vp 具有相同的类型,都是指向 int 型的指针,所以没有问题。而 matrix 是一个指向整型数组的指针(matrix是二维数组,它的第一个元素是一个数组),mp 是一个指向整型的指针,所以 mp 的初始化是不合法的。

指针数组

        指针数组是一个数组,数组里的元素是指针。例如:

int *api[ 10 ];

api[ 10 ]:api 是一个数组;

*api[ 10 ]:api 是一个数组,数组里的元素是指针;

int  *api[ 10 ]:api 是一个数组,数组里的元素类型是指向 int 型的指针。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值