2010/11/1
关键字:指针
指针的声明、定义和初始化
理解指针声明语句时需要从右向左阅读.
char *p1, p2;
p2为char型变量,p1为char型指针.
一个有效的指针必须是以下三种状态之一:
1. 保存一个特定对象的地址.
2. 指向某个对象后面的另一个对象.
3. 0值.
一定要避免使用未初始化的指针.必须在声明指针时就将其初始化.
C++语言无法检测指针是否未被初始化,也无法区分有效地址和由指针分配到存储空间中存放的二进制位形成的地址.除非指针指向某一存在的对象,最好初始化为0,因为编译器可以检测到0值指针.
对指针赋值或初始化时必须使用下面4种类型的值:
1. 0值常量表达式.
2. 类型匹配的对象的地址.
3. 另一对象之后的下一地址.
4. 同类型的另一个有效指针.
int i = 0;
char *p1 = i; //编译错误,虽然p1可以初始化为0,但i的值需要在运
//行时才知道.编译时编译器检测p1和i的类型不相同
//不能初始化,所以报编译错误
const int j = 0; //常量表达式
char *p2 = j; //正确,可以将指针初始化为值常量表达式
char *p3 = j+1; //错误,虽然j+1也是常量表达式,但不能将指针初始化为非0常量表达式
char *p4 = j+0; //正确,j+0计算结果是值为的常量表达式
指针和引用的比较
1. 引用总是指向某个对象.定义引用时没有初始化是错误的.指针总是指向某个地址,指针可以不用初始化,虽然是不被推荐的.
2. 给引用赋值是更改所指向对象的值,给指针赋值是更改指针指向的地址.引用一旦初始化就始终指向某个对象.
指针作为数组的迭代器
只要两个指针指向同一数组或有一个指向该数组末端的下一个单元,C++还支持对这两个指针做减法操作,两个指针的减法操作结果是标准库类型ptrdiff_t类型的数据.和size_t一样,也是一种机器相关的类型,在cstddef头文件中定义,size_t是unsigned类型,ptrdiff_t是signed类型.
const size_t arrsize = 5;
int array[arrsize] = {0, 1, 2, 3, 4};
ptrdiff_t dis = array - &array[arrsize]; //dis结果是-5
C++允许计算数组或对象的超出末端的地址,单不允许对该地址进行解引用操作.而计算数组超出末端位置之后和首地址之前的地址都是不合法的.
与vector相同,数组的超出末端地址可以用做哨兵,用于检测是否到达数组末尾.
const size_t arrsize = 5;
int array[arrsize] = {0, 1, 2, 3, 4};
for(int *pBegin = array, int *pEnd = array+arrsize; pBegin != pEnd; ++ pBegin)
//do something
更一般的写法是
for (int i=0; i<arrsize; ++i)
//do something