指针的初始化和定义
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
每个指针都有一个与之关联的数据类型,该数据类型决定了指针所有指向的对象的类型。例如,一个int 型指针只能指向int 型对象。
1.指针变量的定义
C++语言使用* 号把一个标识符声明为指针:
vector
int *p1, *p2;
string *pstring;
提示:理解指针声明语句时,请从右向左阅读。
2.另一种声明指针的风格
在定义指针变量时,可用空格符号* 与气候的标识符分别开来,如下:
string* ps;
也就是说,该语句把ps定义为一个指向string 类型对象的指针。
这种指针声明风格容易引起这样的误解:把string * 理解为一种数据类型,认为在同意声明语句中定义的其他变量也指向string 类型对象的指针。
如果使用下面的语句:
string* p1, p2;
实际上只把ps1 定义为指针,而ps2并非指针,只是一个普通的string 对象而已。如果需要在一个声明语句中定义了两个指针,必须在每一个变量标识符前再加符号* 声明:
string* ps1,*ps2;
3.指针的可能取值
一个有效的指针必然是以下三种状态之一:1.保存一个特定对象的地址;2.指向某个对象后面的另一对象;3.是0值。若指针保存0值,表明它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可以使用它。下面的定义是合法的:
int ival = 1024;
int *pi = 0;
int *pi2 = &ival;
int *pi3;
pi = pi2;
pi2 = 0;
4.避免使用未初始化的指针
提示:很多运行时错误都源于使用了未初始化的指针。
就像使用其他没有初始化的变量一样,使用未初始化的指针时的行为C++标准中并没有定义,它几乎总会导致运行时崩溃。然而,导致崩溃的这一原因很难发现。
对于大多数的编译器来说,如果使用未初始化的指针,会将指针
中存放的不确定值视为地址,然后操纵该内存地址中存放的位内容。使用未初始化的指针相当于操纵这个不确定地址中存储的基础数据。因此,在对未初始化的指针进行解引用时,通常会导致程序崩溃。
C++语言无法检测指针是否未被初始化,也无法区分有效地址和由指针分配到的存储空间中存放的二进制位形成的地址。建议在使用之前初始化所有的变量,尤其是指针!
建议:如果可能的话,除非所指向的对象已经存在,否则不要先定义指针,这样可避免定义一个未初始化的指针。
如果必须分开定义指针和其所指向的对象,则将指针初始化为0.因为编译器可检测出0值的指针,程序可判断出该指针并未指向一个对象。
5.指针初始化和复制操作约束
对指针进行初始化或赋值只能使用一下四种类型的值:
(1)0值常量表达式,例如:在编译时可获得0值的整型const 对象或字面值常量0.
(2)类型匹配的对象的地址。
(3)另一对象之后的下一地址。
(4)同类型的另一个有效指针。
把int 型变量赋值给指针是非法的,尽管此int 型变量的值可能为0.但允许把数值0 赋值给指针:
int ival;
int zero = 0;
const int c_ival = 0;
int *pi = ival;
pi = zero;
pi = c_ival;
pi = 0;
除了使用数值0外,还可以使用C++语言从C语言中继承下来的预处理变量NULL,该变量在cstdlib头文件中定义,其值为0.如果在代码中使用了这个预处理变量,则编译时会自动被数值0替换。因此,把指针初始化为NULL等效于初始化为0值:
int *pi = NULL;// ok:equivalent to int *pi = 0;
正如其他预处理器变量一样,不可以使用NULL这个标识符给自定义的变量命名。
6.void *指针
C++提供了一种特殊的指针类型void *,它可以保存任何类型对象的地址:
double obj = 3.14;
double *pd = &obj;
void *pv = &obj;
pv =pd; //pd can be a pointer to any type
void *表明该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。
void *指针只支持几种有限的操作:1.与另一个指针进行比较;2.向函数传递void*指针或从函数返回void * 指针;3.给另一个void*指针赋值。不允许使用void *指针操纵它所指向的对象。