1.指向一维数组的指针变量
运行时每个变量在内存空间都会分配存储空间,因此都有一个地址,数组包含多个元素,数组的每个元素都使用同一个同类型的普通变量,因此我们可以让指针变量指向数组的一个元素(即把一个数组元素的地址放到一个指针变量中),所谓数组元素的指针就是数组元素的地址。
1.1指向一维数组的指针
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p;
p=a;//p=&a[0]
上述代码即定义了含10个元素的数组,并对其元素初始化;定义一个指针变量,此时指针变量没有指向数组,是悬空的;此时指针变量p指向数组a的第一个元素。
说明:
(1)数组名不代表整个数组,只能代表数组的首地址,“p=a”的作用是把数组a的首地址赋给指针变量p,而不是把数组a的各个元素的值赋给p。
(2)数组名a是常量指针,而p是指针变量,两者虽然都指向数组的首元素,但是它们是有区别的,a是常量指针,其值是不可以改变的(定义数组时其值就确定了),不能进行a++,a=a+n等相关的运算来改变,而p是指针变量,它的值是可以改变的,如p指向数组的第一个元素,p++就指向数组的第二个元素,p=p+2,p就指向数组的第三个元素。
(3)在定义指针变量时可以同时对其初始化:
int a[10],*p=a;
1.2一维数组元素的引用方式
(1)下标表示法
如int a[5],其五个元素分别为a[0],a[1],a[2],a[3],a[4].如果p指向a的第一个元素a[0],则p[i]和a[i]有相同的意义,都表示第i个元素。
(2)采用指针表示法
数组名代表数组首地址,因此用指针间接引用数组元素,可以表示为:*(a+i),其中i=0,1,2...,代表数组元素a[i].a[0]既可以*(a)表示也可用*p表示。则*(p+0),*(p+1),*(p+2),*(p+3),*(p+4)代表数组的五个元素。
数组元素的下标表示法和指针表示法区别:
(1)下标表示法直观,能直接表示第几个元素,如a[0]表示第0个元素,s[5]表示第五个元素。
(2)指针表示法效率高,能直接根据指针变量的地址访问所指向的数组元素,而用下标表示法,若需要访问a[i],则先计算a[i]的地址a+i*sizeof(数组的类型),再通过此地址去访问对应的内存空间,即元素的值。
是用指针变量来引用数组元素时,应注意:
(1)指针变量当前指向哪一个元素,特别是在循环结构控制中。
(2)*p++等价于*(++p),因为*和++的优先级相同,且结合方向为右结合性。
(3)*(p++)与*(++p)的区别:*(p++)是先间接引用p当前地址的值,在使指针p向高地址移动1个存储块;而*(++p)是先使指针p向高地址端移动1个存储块,在间接引用p所指向的高地址端的值。例如:
p=&a[0];p指向a[i],*(p++)的值是a[i+1]的值,而*(++p)的值仍为a[i],但两种情况后,p都指向元素a[i+1]。
(4)*(p)++是表示将p指向的变量值加1.若p指向元素a[i],运行*(p)++之后,是a[i]+1,p的值不变,仍指向a[i].
1.3二维数组的指针与多维数组的指针表示法
1.3.1二维数组的地址
设有定义int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
在前面我们讲过可以将二维数组a理解为含有3个行元素:a[0],a[1],a[2],每个行元素又可以看作是一个包含四个元素的一维数组如图:
二维数组的指针同样与前面一维数组的指针一样 ,对于行元素a[0],a[1],a[2],数组名a是它们的首地址,因此a+0(也就是a)代表a[0]的地址,a+1代表a[1]的地址,a+2代表a[2]的地址,它们都是各行的首元素。每一行的元素都可以用a[i]+1,a[i]+2,a[i]+3来表示。
1.3.2二维数组的指针
a[i]=*(a+i),a[i][j]=*(a[i]+j)=*(*(a+i)+j),二维数组的指针表示法如图:
1.3.3指向二维数组的指针变量
(1)直接指向数组元素的指针变量
(2)指向一个含有M个元素的一维数组的指针变量,也称行指针。定义形式如下:
类型标识符 (*指针变量名)[M];
例如 int(*p)[4];int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
假设数组a的存储形式如图:
二维数组的数组名代表首地址,哪些是行指针,哪些是列指针如下图:
1.4指向字符串的指针变量
C语言中有两种方法表示字符串,一是将字符串存放在一维字符数组里,通过一维数组命来引用字符串,二是通过字符指针变量来引用字符串。下面我们来重点介绍第二种方法。
1.4.1指向字符串的指针的定义和初始化
指向字符串的指针变量实际上就是字符指针变量,用于存放字符串的首地址。其初始化就是在定义字符指针变量的同时赋予一个字符串的首地址给它,看下面的代码例题:
ps:系统自动在内存的存储区存放字符串常量“computer”,并把该字符串常量的首地址赋给指针变量p,千万不要以为字符串是存放在字符指针变量中,这时p是指向字符串的第一个字符,而不是整个字符串。p不是字符串变量,因此不能从键盘输入一个字符串给字符指针变量。
1.4.2指向字符串的指针变量的赋值运算
用字符数组存放字符串时,只能用字符串对字符数组进行初始化,而不能对字符数组赋值,要想对其赋值要用到字符串的复制函数(strcpy()),但是作为字符指针变量,既可以用字符串对字符指针变量进行初始化,也可以使用“=”将一个字符串常量赋给一个字符指针变量,其作用是将字符串的首地址赋给指针变量。因此我们可以用字符指针变量实现对字符串的访问。