指针是一个值为内存地址的变量(或数据对象)
指针的用途非常广泛,比如如果你想通过函数改变一个变量的值,就得用指针而不能用值传递。或者想要通过一个函数返回多个值时,显然无法通过return做到,此时,可以利用到指针的址传递的特性。还有在很多时候变量,特别是对象的数据量实在太大(如数组和自定义数组),程序员就会用指针来做形参,只需要传递一个地址就行,大大提高了效率。
简单地说指针就是指向变量和对象的地址。
声明指针
int * pi;
解析:int 类型说明符表明了所指向对象的类型,星号()表明声明的变量为一个指针,pi为指针,pi为int类型。pi不是整数类型,处理整数的操作不能用来处理指针。
(注:星号和指针名之间的空格可有可无,通常声明时加空格,而解引用变量时省略空格)
此外,声明多个指针的正确形式是:int * a,* b,* c,* d;
int * a,b时,并非是定义了两个 int 型的指针,而是定义了一个int型的变量 a 和一个 int 型的 b
指针变量的基本操作
赋值:可以把地址赋给指针
解引用:*运算符给出指针指向地址上存储的值
取址:和所有变量一样,指针变量也有自己的地址和值,可以用&运算符给出指针本身的地址
指针和整数相加:相当于移向下、上一位
指针求差:可以计算两个指针的差值
比较:可以通过关系运算符比较两个指针的值,前提是两个指针都指向相同类型的变量
指针和const
可以创建const数组、const指针和指向const的指针
用const关键字保护数组:const int days[MONTHS] = {31,28,30}
指向const的指针不能用于改变值:const double * pd = rates;(rates为int型数组首地址,把pd指向的double类型声明为const,这表明不能用pd来更改它的值)
声明、初始化一个不能指向别处的指针:double * const pc = rates;
指针和数组
使用指针可以有效地处理数组
rates是数组首元素的地址,rates+index是元素rates[index]的地址,而*(rates+index)是该元素的值,相当于rates[index]
指针表示法和数组表示法是两种等效的方法
指针和多维数组
int zippo[4][2];
zippo 是该数组首元素的地址
首元素是一个内含两个int值的数组,所以zippo是这个内含两个int值的数组的地址,即zippo = &zippo[0] 。而zippo[0]本身是一个内含两个整数的数组,所以 zippo[0] = &zippo[0][0]。简而言之,zippo[0]是一个占用一个int大小的对象的地址,而zippo是一个占用int大小的对象的地址
因此,*zippo = zippo[0],zippp[0] = zippo[0][0],**zippo = zippo[0][0],zippo[2][1] = ((zippo+2)+1)
简而言之,zippo是地址的地址,想象有一个树状结构,分散
指向多维数组的指针
int ( * pz)[2]; int **pi;
解析:pz 指向一个内含两个int类型值的数组,可与 po[3][2] 兼容,即 pz = po有效,而 pi是指向指针的指针,与po不兼容,但是pi是指向int的指针,与po[0]兼容