指针:值为内存地址的变量(或数据对象)

指针声明:声明“指针指向的值”

int * ptr;
其中,“ptr指向的值”*ptr是int类型。
ptr本身的类型则是“指向int类型的指针”,其值是一个地址,大多数系统内部由一个无符号整数表示。但其是一个新类型,不可将其当作整数类型来处理,例如两个指针无法相乘。

  1. void interchange(int * u, int * v)//例程将x和y的地址传递给函数
  2. {
  3. int temp;
  4. temp=*u;//获取指针所指向的值
  5. *u = *v;//交换指针所指向的值
  6. *v = temp;
  7. }

一般而言,可以将变量相关的两类信息传递给函数:

  1. function1(x); 的传递了x的值。

对于这种形式,要求定义中的形式参数必须是一个与x类型相同的变量:int function1(int num)

  1. function2(&x);传递的是x的地址。

要求形式参数必须是一个指向正确类型的指针:int function2(int * ptr)

八种指针变量基本操作

1 赋值&取值&解引用

涉及两种运算符

查找地址:&地址运算符
后跟变量名,一元&运算符用于给出变量的存储地址
解引用:间接运算符 “*”
后跟指针名或地址,*给出存储在指针指向地址上的值。

赋值

用数组名、带地址运算符&的变量名或另一个指针,将地址赋给指针,地址须与指针类型兼容。

取值

指针变量有自己的地址和值。对于指针而言,&运算符给出指针本身的地址。

解引用

*给出指针指向地址上存储的值。

2 指针与整数相加&指针减去一个整数

指针与整数相加时,整数会和指针所指向类型的大小(以字节为单位)相乘,然后把结果与初始地址相加。
特别的,指针减去一个整数时,指针必须是第一个运算对象。其余可类比“指针与整数相加”

3 递增指针&递减指针

递增指向数组元素的指针可以让该指针移动至数组的下一个元素。

4 指针求差

计算两个指针的差值,求出两元素之间的距离(距离单位与数组类型的单位相同)

5 比较

使用关系运算符比较两个指针的值(前提是两个指针指向相同类型的对象)

数组:变相地使用指针

数组名是数组首元素的地址。即arr == &arr[0];
此两者都是常量,但可将它们赋值给变量,进而修改指针变量的值。

指针“加一”

指针加一指的是增加一个存储单位(而非字节单位)。
对数组而言意味着加一后的地址是下一个元素的地址,而非下一个字节的地址。
所以必须声明指针所指向对象类型:只知道地址不够,还需要知道存储对象需要多少字节。

数组与指针:同一对象的两种表示

dates + 2 == &dates[2] 相同的地址
*(dates + 2) == dates[2] 相同的值
可以认为*(ar+n)的意思是“到内存的ar位置,然后移动n个单位,检索存储在那里的值”。
注:间接运算符*的优先级高于+

指针与多维数组

zippo[2][1]等价的指针表示法是*(*(zippo+2)+1)

zippo 二维数组首元素的地址(每个元素是一维数组)
zippo+2 二维数组第三个元素的地址
*(zippo+2) 二维数组第三个元素的首元素地址(int)
*(zippo+2)+1 二维数组第三个元素的第二个元素地址
*(*(zippo+2)+1) 二维数组第三个一维数组元素的第二个int类型元素的

指向多维指针的数组

数组指针

int (* pax) [2];
pax指向一个内含两个int类型值的数组。pax是指向数组的指针,*pax是数组名。

指针数组

int * pz[2];
pz是一个内含两个指针元素的数组,每个元素都指向int的指针。
[]运算符优先级更高,与pz结合,所以pz成为一个含有两个元素的数组。再用*表示pz数组内含两个指针。