1、第第6章章 指针指针本章要点本章要点 指针的概念指针的概念 数组与指针数组与指针 字符串与指针字符串与指针 函数与指针函数与指针 指针数组和指向指针的指针指针数组和指向指针的指针 引用引用6.1 指针的概念指针的概念 1.内存地址内存地址 计算机的内存储器被划分成一个个的计算机的内存储器被划分成一个个的存储单元存储单元,这些存储单元按一定的规则这些存储单元按一定的规则编号编号,这个,这个编号编号就是存就是存储单元的储单元的地址地址。每个存储单元的大小为一个字节,每个单元有每个存储单元的大小为一个字节,每个单元有一个唯一的地址。一个唯一的地址。20000000 2.变量的地址变量的地址 在程序中
2、定义的所有变量,都要分配相应的存储在程序中定义的所有变量,都要分配相应的存储单元,不同类型的数据所需要的存储空间的大小不同。单元,不同类型的数据所需要的存储空间的大小不同。系统分配给变量的内存空间的起始单元地址称为该系统分配给变量的内存空间的起始单元地址称为该变变量的地址量的地址。如如:int I,K;I=3;K=5;000020002004IK353.内存单元的访问方式内存单元的访问方式n在程序中一般通过变量名访问在程序中一般通过变量名访问(存取存取)内存单元内存单元.这种按变量地址存取变量值的方式称为这种按变量地址存取变量值的方式称为直接存直接存取方式取方式,或或直接访问方式直接访问方式.
3、n间接存取间接存取(间接访问间接访问)方式方式是指将变量是指将变量I的的地址地址存放在另一个变量存放在另一个变量J中中,通过变量通过变量J访问变量访问变量I的的值值.2000000020002004200635IKJ 4.指针与指针变量指针与指针变量指针:指针:一个变量的一个变量的地址地址也称为该变量的也称为该变量的指针指针。指针变量:指针变量:用于存储其它变量的指针用于存储其它变量的指针(即地址即地址)的变量。的变量。指针变量的定义:指针变量的定义:数据类型数据类型 *指针变量名;指针变量名;如:如:int *p1;float *p2;char *p3;6.2.指针变量的使用指针变量的使用1
4、.指针变量的赋值指针变量的赋值通常把被指向的变量的地址赋给指针变通常把被指向的变量的地址赋给指针变量量 如:如:int *p1,a=3;p1=&a;&:取地址运算符取地址运算符 注意:注意:不能用一个整数给一个指针变量赋值不能用一个整数给一个指针变量赋值.一个指针变量只能指向同一个类型的变一个指针变量只能指向同一个类型的变量量.20003p1a2000 6.2.指针变量的使用指针变量的使用2.指针变量的引用指针变量的引用 间接访问指针变量所指向的存储单元间接访问指针变量所指向的存储单元.指针运算符指针运算符(*)如:如:int *p1,a=3;p1=&a;int a1;a1=*p1;*p1=5
5、;注意注意:指针变量必须指向具体内存地址才能引用指针变量必须指向具体内存地址才能引用.如:如:int*p;*p=10;20003p1a2000例例 通过指针变量存取变量的值通过指针变量存取变量的值#include void main()int a,*p1;double b,*p2;char c,*p3;p1=&a;p2=&b;p3=&c;*p1=10;*p2=11.2;*p3=A;cout a endl;cout b endl;cout c endl;1011.2A100 x2000ap111.20 x2004bp2A0 x200Ccp3例例6.2 输入输入a和和b两个数,按从小到大的顺序输出
6、两个数,按从小到大的顺序输出#include void main()int a,b;int*p1,*p2,*p;cout a b;p1=&a;p2=&b;if(*p1 *p2)p=p1;p1=p2;p2=p;cout min=*p1 max=*p2 endl;请输入两个整数:30 10min=10 max=30&ap1&bp2p30a10b&bp1&ap2&ap30a10b3.指针作为函数的参数指针作为函数的参数指针作为函数的参数,传递的是变量的地址,可以实现指针作为函数的参数,传递的是变量的地址,可以实现地址地址传递传递。例例6.3 指针作为函数参数,被调函数中交换参数值指针作为函数参数,被
7、调函数中交换参数值#include void swap(int*x,int*y);void main()int a,b;a=10;b=20;swap(&a,&b);cout a ,b endl;void swap(int*x,int*y)int temp;temp=*x;*x=*y;*y=temp;程序运行过程中变量值的变化分析程序运行过程中变量值的变化分析yyb10ax20by&ax&b10temp20ax20by10temp&aax&bb10temp&a&btemp10a20&a&b2010(a)(b)(c)(d)比较数值型参数比较数值型参数#include void swap(int x
8、,int y);void main()int a,b;a=10;b=20;swap(a,b);cout a ,b endl;10a10 x20b20y1020 xy10temp2020 xy10temp2010 xy10tempvoid swap(int x,int y)int temp;temp=x;x=y;y=temp;注意:值传递时,函数的实参与形参在内存中占用不同的存储空间,值注意:值传递时,函数的实参与形参在内存中占用不同的存储空间,值只能由实参传递给形参,而形参的变化并不会影响实参。只能由实参传递给形参,而形参的变化并不会影响实参。比较以下函数比较以下函数#include void
9、 swap(int*x,int*y);void main()int a,b;a=10;b=20;swap(&a,&b);cout a ,b endl;void swap(int*x,int*y)int*temp;temp=x;x=y;y=temp;void swap(int*x,int*y)int*temp;*temp=*x;*x=*y;*y=*temp;#1.指针运算指针运算指针运算包括指针运算包括算术运算算术运算、关系运算关系运算与与赋值赋值运算运算。指针可以与整数进行指针可以与整数进行加减运算加减运算,结果,结果与与指针所指向的数据类型指针所指向的数据类型有关。有关。p+n表示指针表示指
10、针p当前所指向位置后面第当前所指向位置后面第n个同类型数据的个同类型数据的地址,地址,p-n表示指针表示指针p当前所指向位置前面当前所指向位置前面第第n个同类型数据的地址。个同类型数据的地址。6.3 指针与数组指针与数组例例 指针与整数的加减运算指针与整数的加减运算#include void main()int a,*p1,*p2;double b,*p3,*p4;p1=&a;p3=&b;cout p1 p3 endl;p2=p1+1;/p1+1与与p3+1的含义不同,与指针数据类型有关的含义不同,与指针数据类型有关p4=p3+1;cout p2 p4 endl;p2=p1-1;/p1-1与与
11、p3-1的含义不同,与指针数据类型有关的含义不同,与指针数据类型有关p4=p3-1;cout p2 p4 endl;p2=p1+5;p4=p3+5;cout p2 p4 endl;0 x0012FF7C 0 x0012FF6C0 x0012FF80 0 x0012FF740 x0012FF78 0 x0012FF640 x0012FF90 0 x0012FF94指向同一种数据类型的指针可以进行关系运算。指向同一种数据类型的指针可以进行关系运算。两个相同类型的指针相等,表示这两个指针指向两个相同类型的指针相等,表示这两个指针指向同一个地址。同一个地址。指针也可以与指针也可以与0进行比较运算,如果
12、进行比较运算,如果p=0成立,成立,我们称我们称p是一个是一个空指针空指针,即指针,即指针p还没有具体指向。还没有具体指向。为了避免使用没有指向的指针,在定义指针变量为了避免使用没有指向的指针,在定义指针变量时,可以将其时,可以将其初始化为初始化为0(也可以写成(也可以写成NULL)。)。指针的关系运算指针的关系运算例例:使用空指针使用空指针#include void main()int a,*p=NULL;cout p endl;if(p!=NULL)*p=10;cout 将将10赋值给赋值给p所指向的地址所指向的地址 endl;elsecout p是空指针,不能使用!是空指针,不能使用!e
13、ndl;p=&a;cout p endl;if(p!=NULL)*p=10;cout 将将10赋值给赋值给p所指向的地址所指向的地址 endl;elsecout p是空指针,不能使用!是空指针,不能使用!endl;0 x00000000p是空指针,不能使用!0 x0012FF7C将10赋值给p所指向的地址数组在内存中是连续存放的,每个数组元素数组在内存中是连续存放的,每个数组元素都占用存储单元都占用存储单元,有相应地址有相应地址,所以指针可以指所以指针可以指向数组元素向数组元素.如如:int a10,*p;p=&a5;*p,a5 含义相同含义相同 2.指向数组元素的指针指向数组元素的指针 数组
14、名数组名就是数组的就是数组的首地址首地址(第一个元素的地(第一个元素的地址),指针可以与整数进行加减运算,利用这址),指针可以与整数进行加减运算,利用这一性质可以方便地通过指针引用数组元素。一性质可以方便地通过指针引用数组元素。如如:int a10,*p;则则:p=a;p=&a0;含义相同含义相同 p+i a+i 含义相同含义相同 *(p+i)*(a+i)ai 含义相同含义相同注注:又称又称变址运算符变址运算符.ai 的地址为的地址为:a+i*d 指向数组元素的指针变量也可带下标指向数组元素的指针变量也可带下标,如如pi.2.指向数组元素的指针指向数组元素的指针例例 使用指针输出数组中的所有元
15、素使用指针输出数组中的所有元素#include void main()int a6=1,2,3,4,5,6;int*p;p=a;for(int i=0;i6;i+)cout *p ;p+;cout endl;1 2 3 4 5 6 1 2 3 4 5 6ap例例6.5 输出数组中的全部元素。输出数组中的全部元素。n下标法下标法#include using namespace std;int main()int a10;int i;for(i=0;iai;coutendl;for(i=0;i10;i+)coutai;coutendl;return 0;n 用指针变量指向数组元素用指针变量指向数组
16、元素#include using namespace std;int main()int a10;int i,*p=a;for(i=0;i*(p+i);/输入输入a0a9coutendl;for(p=a;p(a+10);p+)cout*p;coutendl;return 0;比较比较n下标法每次通过变址运算符计算数组下标法每次通过变址运算符计算数组元素的地址元素的地址,指针变量直接指向元素指针变量直接指向元素,不不必每次都重新计算地址必每次都重新计算地址,故效率高故效率高.n但是但是,用下标法比较直观用下标法比较直观,能直接知道第能直接知道第几个元素几个元素.注意注意n指针变量可能指向数组以后
17、的内存单元指针变量可能指向数组以后的内存单元,在使用在使用指针变量指向数组元素时指针变量指向数组元素时,应应切实保证切实保证指向数组指向数组中有效的元素中有效的元素.n注意指针变量自加自减运算及其所指向的元素注意指针变量自加自减运算及其所指向的元素.np+使使p指向下一个元素指向下一个元素n*p+先得到先得到p所指变量值所指变量值,再使再使p加加1.等同于等同于*(p+).n*(+p)先使先使p加加1,再得到再得到p所指变量值所指变量值.n(*p)+表示表示p所指向的所指向的元素值元素值加加1.例例:指向同一个数组的两个指针的减法运算指向同一个数组的两个指针的减法运算#include void
18、 main()int a10=1,2,3,4,5,6,7,8,9,10;int*p1,*p2;p1=a;p2=&a3;cout p2-p1 endl;p1=&a2;p2=&a7;cout p2-p1 endl;3 5ap1 1 2 3 4 5 6 7 8 9 10p2 a0 a1 a2 a3 a4 a5 a6 a7 a8 a93.指针作为函数的参数接收数组地址指针作为函数的参数接收数组地址数组名作为函数的参数实际上传递的是数数组名作为函数的参数实际上传递的是数组的首地址,进行的是组的首地址,进行的是地址传递地址传递,用指针变用指针变量作函数参数量作函数参数,同样可以接收实参传来的数同样可以接收
19、实参传来的数组首元素的地址组首元素的地址。例例6.6 用选择法将用选择法将10个整数按由小到大的顺个整数按由小到大的顺序排列。序排列。要求要求:将形参改为指针变量。将形参改为指针变量。函数函数void select_sort(int*p,int n)/用指针变量作形参用指针变量作形参 int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(*(p+j)*(p+k)k=j;/用指针法访问数组用指针法访问数组 t=*(p+k);*(p+k)=*(p+i);*(p+i)=t;#include using namespace std;void select
20、_sort(int*p,int n);int main()int a10,i;coutenter the originl array:endl;for(i=0;iai;coutendl;select_sort(a,10);coutthe sorted array:endl;for(i=0;i10;i+)coutai ;coutendl;return 0;主程序主程序说明说明n用指针变量作形参用指针变量作形参,接收实参数组名接收实参数组名,和数组名和数组名作形参作形参,本质上是一样的本质上是一样的.C+.C+编译系统将形参编译系统将形参数组名一律作为指针变量处理数组名一律作为指针变量处理.如如:
21、void select_sort(int array,int n)处理为处理为:void select_sort(int*array,int n)n在函数调用时在函数调用时不存在不存在占有内存空间的占有内存空间的形参数组形参数组,只为指针变量分配空间只为指针变量分配空间,形参数组和实参数组共形参数组和实参数组共占同一段内存单元占同一段内存单元.实参和形参的结合有实参和形参的结合有4种形式种形式实参实参形参形参数组名数组名数组名数组名数组名数组名指针变量指针变量指针变量指针变量数组名数组名指针变量指针变量指针变量指针变量注注:实参数组名是常量实参数组名是常量,形参数组名是变量形参数组名是变量例例
22、:编写一个函数,将数组中的元素按照编写一个函数,将数组中的元素按照相反的顺序存放相反的顺序存放分析:将数组名和元素个数作为函数的参数,可以分析:将数组名和元素个数作为函数的参数,可以通过地址访问数组中的所有元素。在函数中将数组通过地址访问数组中的所有元素。在函数中将数组的第一个元素与最后一个元素交换,第二个元素与的第一个元素与最后一个元素交换,第二个元素与倒数第二个元素交换,一直进行到中间,即完成反倒数第二个元素交换,一直进行到中间,即完成反序存放。序存放。源程序源程序#include void inv(int x,int n);void main()int i,a10=0,1,2,3,4,5
23、,6,7,8,9;cout 原数组:原数组:endl;for(i=0;i10;i+)cout ai ;cout endl;inv(a,10);cout 交换后的数组:交换后的数组:endl;for(i=0;i10;i+)cout ai ;cout endl;原数组:0 1 2 3 4 5 6 7 8 9交换后的数组:9 8 7 6 5 4 3 2 1 0void inv(int x,int n)int temp,i,j,m;m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;注意:由于传递的是数组地址,因此形参注意:由于传递的是数组地址
24、,因此形参x和实参和实参a指向相同的内存地址,因此在函数指向相同的内存地址,因此在函数体中对体中对x的操作实际上就是对的操作实际上就是对a的操作的操作注意:数组名作为函数参数传递的是数组首地址,因此也可以直接将形参改注意:数组名作为函数参数传递的是数组首地址,因此也可以直接将形参改为指针,当数组名作为实参时,同样能够传递数组首地址。将函数为指针,当数组名作为实参时,同样能够传递数组首地址。将函数inv()做以做以下修下修改:改:void inv(int*x,int n)int*i,*j,temp,m;m=(n-1)/2;for(i=x,j=x+n-1;ij;i+,j-)temp=*i;*i=*
25、j;*j=temp;0 1 2 3 4 5 6 7 8 9ixj4.多维数组与指针多维数组与指针(1)多维数组元素的地址多维数组元素的地址(二维二维)n一个二维数组可以看成元素是一维数组的一一个二维数组可以看成元素是一维数组的一维数组维数组.如如:int a34=1,3,5,7,9,11,13,15,17,19,21,23 可以看成可以看成a是是3个元素的一维数组个元素的一维数组,每个元素又是每个元素又是4个个元素的一维数组元素的一维数组.a2a1a02321191715131197531a由此可见由此可见na指向指向a0(即即a=&a0).(a指向的是一维数组指向的是一维数组,不不是二维数组
26、的元素是二维数组的元素)na+i 指向指向ai(即即ai可表示为可表示为*(a+i).na0是首行一维数组名是首行一维数组名,它指向它指向a00(即即a0=&a00)(a0指向的是二维数组元素指向的是二维数组元素).nai+j 指向指向ai中的第中的第j 个元素个元素aij(即即aij可可表示为表示为*(ai+j)或或 *(*(a+i)+j)a2a1a02321191715131197531aa+1a+2(2)指向多维数组元素的指针变量指向多维数组元素的指针变量n指向数组元素的指针变量指向数组元素的指针变量n定义指针变量的基类型为数组元素的类型定义指针变量的基类型为数组元素的类型例例6.7 输
27、出二维数组各元素的值。输出二维数组各元素的值。#include using namespace std;int main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int*p;/p是基类型为整型的指针变量是基类型为整型的指针变量for(p=a0;pa0+12;p+)cout*p;coutendl;return 0;n指向一维数组的指针变量指向一维数组的指针变量 一般格式一般格式:基类型名基类型名(*指针变量名指针变量名)常量表达式常量表达式例例6.8 输出二维数组任一行任一列元素的值。输出二维数组任一行任一列元素的值。#include using name
28、space std;int main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int(*p)4,i,j;cinij;p=a;cout*(*(p+i)+j)endl;return 0;(3)指向数组元素的指针作函数参数指向数组元素的指针作函数参数n指向一维数组元素的指针作函数参数指向一维数组元素的指针作函数参数,可以接可以接收二维数组名作实参收二维数组名作实参.例例6.9 输出二维数组各元素的值。输出二维数组各元素的值。#include using namespace std;int main()void output(int(*p)4);int a34=
29、1,3,5,7,9,11,13,15,17,19,21,23;output(a);return 0;void output(int(*p)4)int i,j;for(i=0;i3;i+)for(j=0;j4;j+)cout*(*(p+i)+j);coutendl;6.4 字符串与指针字符串与指针n字符串的访问方字符串的访问方法有法有3种种:n用字符数组用字符数组n用字符串变量用字符串变量n用字符指针用字符指针例例6.13 将字符串将字符串str1复制为字符复制为字符串串tr2。#include using namespace std;int main()char str1=I love CHI
30、NA!;char str220,*p1,*p2;p1=str1;p2=str2;for(;*p1!=0;p1+,p2+)*p2=*p1;*p2=0;p1=str1;p2=str2;coutstr1 is:p1endl;coutstr2 is:p2endl;return 0;6.5 函数与指针函数与指针1.用函数指针变量调用函数用函数指针变量调用函数n一个函数在编译时被分配一个入口地址一个函数在编译时被分配一个入口地址,函数名函数名代表函数入口地址代表函数入口地址,函数入口地址称为函数入口地址称为函数的指函数的指针针.n可以用一个指针变量指向函数可以用一个指针变量指向函数.n指向函数的指针变量的
31、指向函数的指针变量的一般定义形式一般定义形式:函数类型函数类型(*指针变量名指针变量名)(函数形参表函数形参表)例如:例如:int(*p)(int,int);就定义了一个函数指针就定义了一个函数指针p,它指向一个返回整型值,它指向一个返回整型值,有两个整型参数的函数。有两个整型参数的函数。n 函数指针变量的赋值函数指针变量的赋值在定义了指向函数的指针变量后,在使用此函数指针在定义了指向函数的指针变量后,在使用此函数指针之前,必须先给它赋值,使它指向一个函数的入口地址。之前,必须先给它赋值,使它指向一个函数的入口地址。由于由于函数名是函数在内存中的首地址,因此可以赋给函数函数名是函数在内存中的首
32、地址,因此可以赋给函数指针变量。指针变量。赋值的一般语法格式为:赋值的一般语法格式为:函数指针名函数指针名=函数名;函数名;例如,对上面刚定义的函数指针例如,对上面刚定义的函数指针p,可以给它赋值如下:可以给它赋值如下:p=func1;其中,函数名所代表的函数必须是一个已经定义过的,其中,函数名所代表的函数必须是一个已经定义过的,和函数指针和函数指针具有相同返回类型具有相同返回类型的函数。并且的函数。并且等号后面等号后面只需只需写函数名而写函数名而不要写参数不要写参数,例如不要写成下列形式:,例如不要写成下列形式:p=func1(a,b);n 函数指针变量的使用函数指针变量的使用 当函数指针指
33、向某函数以后,可以用下列形式调用函数:当函数指针指向某函数以后,可以用下列形式调用函数:(*指针变量)(实参表列)指针变量)(实参表列)例如:(例如:(*p)()(a,b),),它相当于它相当于funl(a,b)。)。必须指出的是:指针的运算在这里是无意义的。因为指必须指出的是:指针的运算在这里是无意义的。因为指针指向函数的首地址。当用指针调用函数时,程序是从针指向函数的首地址。当用指针调用函数时,程序是从指针所指向的位置开始按程序执行,若进行指针运算,指针所指向的位置开始按程序执行,若进行指针运算,程序的执行就不是从函数的开始位置执行,这就会造成程序的执行就不是从函数的开始位置执行,这就会造
34、成错误。错误。例例6.14 求和中的大者。求和中的大者。#include using namespace std;int main()int max(int x,int y);/函数声明函数声明 int(*p)(int,int);/定义指向函数的指针变量定义指向函数的指针变量p int a,b,m;p=max;/使使p指向函数指向函数max cinab;m=p(a,b);coutmax=mendl;return 0;6.6 返回指针值的函数返回指针值的函数n当一个函数的返回值是指针类型时,这个函数就是指当一个函数的返回值是指针类型时,这个函数就是指针型函数。针型函数。n通常非指针型函数调用结束
35、后,可以返回一个变量,通常非指针型函数调用结束后,可以返回一个变量,但是这样每次调用只能返回一个数据。有时需要从被但是这样每次调用只能返回一个数据。有时需要从被调函数调函数返回一批数据返回一批数据到主调函数中,这时可以通过指到主调函数中,这时可以通过指针型函数来解决。针型函数来解决。n指针型函数在调用后返回一个指针,通过指针中存储指针型函数在调用后返回一个指针,通过指针中存储的地址值,主调函数就能访问该地址中存放的数据,的地址值,主调函数就能访问该地址中存放的数据,并通过指针算术运算访问这个地址的前、后内存中的并通过指针算术运算访问这个地址的前、后内存中的值。因此,通过对空间的有效组织(如数组
36、、字符串值。因此,通过对空间的有效组织(如数组、字符串等能前后顺序存放多个变量的数据类型),就可以返等能前后顺序存放多个变量的数据类型),就可以返回大量的数据。回大量的数据。n定义指针型函数的一般格式定义指针型函数的一般格式 数据类型数据类型*函数名(参数表)函数名(参数表)其中,数据类型是函数返回的指针所指向数据其中,数据类型是函数返回的指针所指向数据的类型;的类型;*函数名声明了一个指针型的函数;函数名声明了一个指针型的函数;参数表是函数的形参列表。参数表是函数的形参列表。例如:例如:int*fun(a,b)它表示函数它表示函数fun返回一个指针值,这个指针返回一个指针值,这个指针指向一个
37、整型数据,指向一个整型数据,a、b是形参。是形参。6.7指针数组和指向指针的指针指针数组和指向指针的指针 1.指针数组的概念指针数组的概念 数组元素是指针的数组,称为指针数组。数组元素是指针的数组,称为指针数组。定义格式:定义格式:类型名类型名 *数组名数组名常量表达式常量表达式;如如 int *p110;double *p210;用指针数组可以方便处理多个字符串或二维数用指针数组可以方便处理多个字符串或二维数组组.例例6.15 若干字符串按字母顺序(由小到大)若干字符串按字母顺序(由小到大)输出。输出。#include using namespace std;void sort(char*n
38、ame,int n);/声明函数声明函数void print(char*name,int n);int main()char*name=BASIC,FORTRAN,C+,Pascal,COBOL;/定定义指针数组义指针数组int n=5;sort(name,n);print(name,n);return 0;函数函数void sort(char*name,int n)char*temp;int i,j,k;for(i=0;in-1;i+)k=i;for(j=i+1;j0)k=j;if(k!=i)temp=namei;namei=namek;namek=temp;void print(char*
39、name,int n)int i;for(i=0;in;i+)coutnameiendl;例例:用指针数组处理二维数组的元素用指针数组处理二维数组的元素#include void main()int line33=1,0,0,0,1,0,0,0,1;int*p_line3;/声明整型指针数组声明整型指针数组p_line0=line0;/初始化指针数组元素初始化指针数组元素p_line1=line1;p_line2=line2;coutMatrix test:endl;/输出单位矩阵输出单位矩阵for(int i=0;i3;i+)/对指针数组元素循环对指针数组元素循环for(int j=0;j3
40、;j+)/对矩阵每一行循环对矩阵每一行循环coutp_lineij;coutendl;1 0 00 1 0 0 0 11p_linelinep_line0p_line1p_line2110000002.指向指向指针的指针指针的指针如果一个指针变量保存的是另一个指针变量的地址,如果一个指针变量保存的是另一个指针变量的地址,我们称之为指向指针的指针,或多级指针。我们称之为指向指针的指针,或多级指针。定义格式:定义格式:类型名类型名 *指针变量名指针变量名;如:如:int *p1;double *p2;例例:二级指针的应用二级指针的应用#include void main()int a,*p1,*p
41、2;double b,*p3,*p4;a=10;b=22.3;p1=&a;p3=&b;p2=&p1;p4=&p3;cout a *p1 *p2 endl;cout b *p3 *p4 endl;*p2=20;*p4=45.8;cout a *p1 *p2 endl;cout b *p3 *p4 endl;10 10 1022.3 22.3 22.320 20 2045.8 45.8 45.8&p1&a10p2p1a&p3&b22.3p4p3b例例6.16 用二级指针指向指针数组用二级指针指向指针数组#include void main()char*name=Basic,Fortran,C+,P
42、ascal;char*p;int i;for(i=0;i4;i+)p=name+i;cout *p endl;BasicFortranC+Pascalname0name1name2name3BasicFortranC+Pascalp#include#include void stringcat(char*s1,char*s2);void main()char a20=abcde;char b=fgh123;cout a endl;cout b endl;stringcat(a,b);cout a endl;cout b endl;例例:编写一个函数,将两个字符串连接起来编写一个函数,将两个字符
43、串连接起来void stringcat(char*s1,char*s2)int i,len;len=strlen(s1);for(i=0;s2i!=0;i+)s1len+i=s2i;s1len+i=0;a b c d e 0 s2 f g h 1 2 3 0 s1n虽然用指针作函数的参数可以使得形参的虽然用指针作函数的参数可以使得形参的改变对相应的实参有效。但是,如果在函改变对相应的实参有效。但是,如果在函数中反复使用指针进行间接访问,会影响数中反复使用指针进行间接访问,会影响程序的可读性且容易产生错误,因此在程序的可读性且容易产生错误,因此在C+语言中扩充了引用的概念,这样既可语言中扩充了引
44、用的概念,这样既可以实现指针所带来的功能,又使程序清晰以实现指针所带来的功能,又使程序清晰易读。易读。6.9 引用引用1.1.引用的概念引用的概念引用是一种特殊的变量,可以认为是一个变量引用是一种特殊的变量,可以认为是一个变量的别名。的别名。定义引用的一般格式定义引用的一般格式:类型说明符类型说明符&引用名引用名 变量名;变量名;如:如:int a=1;int&b=a;首先定义变量首先定义变量a,并初始化为,并初始化为1,然后定义引用,然后定义引用b,并初始,并初始化为化为a,即,即b是是a的别名,因此的别名,因此a和和b是同一个单元。是同一个单元。注意:注意:定义引用时一定要初始化,指明该引
45、用变量是谁的定义引用时一定要初始化,指明该引用变量是谁的别名。别名。&为引用声明符为引用声明符,不代表地址不代表地址.2.引用的简单使用引用的简单使用#include void main()int a=1;int c=10;int&b=a;cout a ,b,c endl;b=c;cout a ,b,c endl;b=20;cout a ,b,c endl;定义引用定义引用b,并将其作为,并将其作为a的别名的别名将将c的值赋给的值赋给b,不是将,不是将b作为作为c的别名的别名 3.引用作为函数的参数引用作为函数的参数例例6.20 写一个函数,用引用作为参数,交换函数中两个写一个函数,用引用作为
46、参数,交换函数中两个变量的值。变量的值。#include void swap(int&x,int&y);void main()int a,b;a=10;b=20;swap(a,b);cout a ,b endl;void swap(int&x,int&y)int temp;temp=x;x=y;y=temp;例例6.20程序运行过程中参数值的变化图示程序运行过程中参数值的变化图示 10axby20axby10temp20axby10temp10axby10temp20202010注意:引用作参数时,函数的实参与形参在内存中共用存储注意:引用作参数时,函数的实参与形参在内存中共用存储单元,因此形
47、参的变化会使实参同时变化。单元,因此形参的变化会使实参同时变化。6.10 动态内存分配动态内存分配 1.1.动态分配一个数据的存储空间动态分配一个数据的存储空间 通过通过new运算符实现动态分配内存,格式如下:运算符实现动态分配内存,格式如下:new 类型名(初值)类型名(初值)如:如:int *p1,*p2;p1=new int(10);p2=new int;运算符运算符delete用来删除由运算符用来删除由运算符new动态分配的动态分配的存储空间。使用格式如下:存储空间。使用格式如下:delete 指针名指针名;如:如:delete p1;2.动态分配多个连续的数据存储空间动态分配多个连续
48、的数据存储空间通过通过new运算符动态分配数组,格式如下:运算符动态分配数组,格式如下:new 类型名类型名整型表达式整型表达式 如:如:int *p1;p1=new int10;用用delete删除动态数组时,要在指针前加删除动态数组时,要在指针前加“”。格式。格式如下:如下:delete 指针名指针名;如:如:delete p1;例例:动态内存分配的使用动态内存分配的使用#include void main()int*p1,*p2;p1=new int(10);p2=new int10;int i;for(i=0;i10;i+)*(p2+i)=i;cout *p1 endl;for(i=0;i10;i+)cout *(p2+i);cout endl;for(i=0;i10;i+)cout p2i “”;/p2i 与*(p2+i)所访问的数据相同cout endl;delete p1;delete p2;100 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9 p2 1 2 3 4 5 6 7 8 9 10