C++指针

一.指针定义

C++规定,存放地址的变量称为指针变量,变量的地址称为变量的指针。指针变量是一种特殊的变量,它不同于一般的变量,一般变量存放的是数据本身,而指针变量存放的是数据的地址。

指针变量也是变量,只是指针变量存储的是变量的指针。指针变量存放的是变量的指针,在32位系统中指针的宽度为32位(即4字节),所以在32位系统中,指针变量的大小是4字节,无论是什么类型的指针变量。

一个指针变量有两个属性,一个是它的值,另外一个是它的类型。这个类型表示指针所指向的变量的数据类型,而不是指针自身的类型。这个类型有两个作用:一是指示编译在解引用时从内存中读取几个字节,指针指向下一个元素内存跳变几个字节;二是指示编译在进行指针类型转换时如何进行类型检查匹配。

int nValue = 0xFF00;

char* pszValue = reinterpreter_cast(&a);

cout<<*p<<endl;

本例结果为0,即只取出了低十六进制位一字节的数值。

C/C++中有两个特殊的指针,分别是空指针和void指针。空指针是一种特殊指针,它的值是0。C/C++用符号常量NULL表示这个空值,并保证这个值不会是任何变量的地址。空指针可以给任何指针赋值。所以空指针一般用于判断指针是否合法。void指针又称为通用指针,它可指向任何变量。C语言允许直接把任何变量的地址作为指针赋给通用指针。但有一点需要注意,void*不能指向由const修饰的变量。

指针注意事项:

1.一个指针变量定义了,确保其初始化,以防此指针悬空变成野指针。

2.如果一个指针变量被delete释放后,确保其被赋值为NULL,防止此指针变量变为野指针。

3.如果一个函数的形式参数可接收所有类型的指针,请将此函数的形参声明为void*,如C语言内存操作系列函数(memmove,memcopy)就是这类函数。

4.禁止使用void指针操纵其指向的对象,因为void操作对象时无法确定对象的类型。

指针变量初始化的4种方式:

1.使用NULL指针进行初始化,因为NULL可以给任何指针变量初始化。

2.使用类型匹配的对象的地址。

3.另一个对象之后的下一个地址

4.同一类型的另一个有效的指针

int iVal;

int iZero = 0;

const int piVal = NULL;

int* pi = iVal; //error:用一个整形变量初始化pi是错误的

pi = iZero; //error:用整形值0初始化pi是错误的

pi = piVal; //OK:通过const int指针初始化int指针是合法的

pi = NULL; //OK:直接通过恒值0初始化int指针是合法的

pi = &iVal; //OK:使用int型对象地址初始化int型指针是合法的

由于指针的类型用于确定指针所指向的对象的类型,因此初始化或赋值时必须保证类型匹配。

指针用于间接访问对象,并基于指针的类型提供可执行的操作。也就是说指针必须指向int型变量,不能指向double或其他,否则基于指针进行的间接操作都是未定义的

绝对不能把一个整形值赋值给一个指针(NULL)除外

二.空指针

空指针在概念上不同于未初始化的指针,空指针可以确保不指向任何对象或函数,而未初始化的指针则可能指向任何地方。空指针不是任何变量的指针,也不是野指针。

每种指针类型都有一个空指针,而不同类型的空指针内部表示可能不尽相同。

1.在程序中获得一个空指针

根据语言定义,在指针上下文中的常数0会在编译时转换为空指针。即,在初始化,赋值或比较的时候,如果一边是指针类型的值或表达式,编译器可以确定另一边的常数0为空指针并生成正确的空指针值。 char* p = 0; if(p!=0);都合法

然而,传入函数的参数不一定被当作指针环境,因而编译器可能不能识别未加修饰的0“表示”指针,在函数调用的上下文中生成空指针需要明确的类型转换,强制把0看成是指针。例如unix系统调用execl接受变长的以空指针结束的字符指针参数,它应采用如下正确的调用:

execl("bin/sh","sh","-c","date",(char*)0);

如果省略最后一个参数的(char*)转换,则编译器无法知道这是一个空指针,而当做一个0传入。如果在作用域内有函数原型,则参数传递变为"赋值上下文",从而可以安全省略多数类型转换,因为原型告知编译器需要指针,使之把未回修饰的0正确转换为适当的指针。函数原型不能为变长参数列表中的可变参数提供类型,在函数调用时对所有的空指针进行类型转换可能是预防可变参数和无原型函数产生问题的最安全的办法。

2.使用"if(p)"检查空指针是否可靠

if(p),无论p是任何表达式,编译器本质上都会把它做如下处理

if(p!=0)

编译器可以看出0实际上是一个空指针常数,并使用正确的空指针值。所以类似if(p)这样的"缩写"尽管完全合法,但被一些人认为是不好的风格

stdio.h中NULL的定义

#ifndef NULL

#ifdef __cplusplus

#define NULL 0

else

define NULL ((void*)0)

endif

endif

3.如果NULL和0作为空指针常数是等价的,到底该用哪一个呢

在指针上下文中NULL和0完全等价,而未加修饰的0也完全可以接受。虽然NULL和0具有相同的功能,但仍建议使用NULL替代0.有两个好处

(1)用NULL会比0有更好的兼容性

(2)尽管符号常量经常代替数字使用以备数字的改变,但这不是用NULL代替0的原因。语言本身确保了源码中的0会生成空指针。NULL只是用做一种格式习惯

空指针不一定是0,但必须是指向不能被变量分配到的地址。而NULL肯定是0

赋值为空指针的变量,可确保变量不指向任何对象或函数。合理地使用空指针可有效避免内存泄漏,提高程序的执行效率

原文链接: https://www.cnblogs.com/fenghuan/p/4820179.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/222015

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 上午11:32
下一篇 2023年2月13日 上午11:32

相关推荐