C++ 十分钟看指针
指针,用来遍历数组。是数组的迭代器,用来指向数组的一个元素。指针用于指向对象,与迭代器不同的是,指针用于指向单个对象,而迭代器只能用于访问容内的元素。
string s("By:Sayln_wu");string *sp =&s;上面的定义个一个指向string类型的指针sp,&是取地址操作符。
1、指针的初始化
C++语音使用*符号把一个标示符声明为指针:
int *p1,*p2;string *ps;double *pd;
在声明语句中,符号*可用在指定类型的对象列表的任意位置。
int i1,*i2;
还有一种风格,如下:
int* p1; //和int *p1; 是一样的。
千万不要把int*当做是一种数据类型。
不过,语句:
int* pi1,pi2; //pi1为指针,而pi2则是为int类型。int *pi1,*pi2; //pi1,pi2为指针
注意以上的类型即可。
2、指针的赋值
int i;int zero = 0;const int c_i = 0;int *pi = i;//因为i没有赋值,所以此语句错误! pi = zero;//不能把变量zero赋值给指针,所以此语句错误! pi = c_i;//可以把const int 型的c_i赋值给指针pi pi = 0;// 0值常量表达式可以。
赋值只能使用以下4种类型的值。
* 0值常量表达式
* 类型匹配的对象的地址
* 另一对象之后的下一个地址
* 同类型的另一个有效指针
3、空指针 void*指针
viod*指针只支持几种有效的操作:与另一个指针进行比较;向函数传递void*指针或从函数返回void*指针;给另一个void*指针赋值。
不允许使用void*指针操纵它所指的对象。
4、指针操作
#include <IOSTREAM>#include <STRING>using namespace std;int main(){string s("BY:sayln_wu");string *ps = &s;cout<<*ps<<endl;//输出:BY:sayln_wucout<<ps<<endl;//输出:0018FF2C ,即ps的地址。*ps = "欢迎光临Sayln_wu博客";cout<<endl<<" s的值为:" << s <<"\n *ps的值为:"<<*ps<<"\n ps的地址为:"<<ps<<endl;return 0;}输出截图如下:

可以看出ps的地址是不变的。即s的地址。而*ps的改变使得s也发生了改变。
5、指针和引用的比较
引用(reference)和指针都可以间接的访问另一个值,但是他们有着重要区别。
第一个区别:引用总是指向某个对象,就是定义引用时没有初始化是错误的。而指针可以赋空值。
第二个区别:赋值行为的差异。下面写两个程序段来看一下赋值差异。
cout<<"By:sayln_wu "<<endl<<endl;cout<<"指针赋值:"<<endl;int i1=25;int i2=50;int *pi=&i1,*pi2=&i2;cout<<"i1为"<<i1<<" i2为"<<i2<<endl;cout<<"*pi为"<<*pi<<" *pi2为"<<*pi2<<endl;pi = pi2;cout<<"after:"<<endl;cout<<"i1为"<<i1<<" i2为"<<i2<<endl;cout<<"*pi为"<<*pi<<" *pi2为"<<*pi2<<endl<<endl;cout<<"引用赋值:"<<endl;int a=25;int b=50;int &ra=a,&rb=b;cout<<"a为"<<a<<" b为"<<b<<endl;cout<<"ra为"<<ra<<" rb为"<<rb<<endl;ra = rb;cout<<"after:"<<endl;cout<<"a为"<<a<<" b为"<<b<<endl;cout<<"ra为"<<ra<<" rb为"<<rb<<endl;
截图如下:

可以看到指针是修改了指向的地址,i1不变。而引用是ra即a的值,故a变为rb的值,也就是b的值。
6、指针的算术操作
通常,在指针上加上(或减去)一个整型数值n等效于获得一个新指针,该新指针指向指针原来指向的元素之后(或之前)的第n个元素。
int ia[] = {0,1,2,3,4}; int *ip = ia; //ip指向ia[0]int *ip2 = ip+4;//ip2指向ia[4]int *ip3 = ip+10;//错误,溢出。当然指针还支持相减,
ptrdiff_t n = ip2 -ip; //结果为4
两种指针减法操作的结果是标准库类型ptrdiff_t的数据。需要加入<cstddef>头文件。ptrdiff_t是一个signed整形。