1、1C+程序设计语言程序设计语言林桂明24.1、数、数 组组4.2、指针和引用、指针和引用4.3、动态存储分配、动态存储分配34.1 数组一、数组一、数组根据数组的维数,分为一维数组、二维数组和多维数组,常用的是一维和二维数组。有一个下标是一维数组;有两个下标是二维数组。有一个下标是一维数组;有两个下标是二维数组。(1)一维数组)一维数组的定义:的定义:数据类型数据类型 数组名数组名 数组长度数组长度n说明:说明:n数组名为用户定义的标识符。数组名为用户定义的标识符。n数据类型为数组元素的数据类型。数据类型为数组元素的数据类型。n数组长度指定数组中元素的个数,为正整数,不能是变量。数组长度指定数
2、组中元素的个数,为正整数,不能是变量。n数组元素是通过下标进行访问的,其作用相当于简单变量。数组元素是通过下标进行访问的,其作用相当于简单变量。n数组元素的下标从数组元素的下标从0 0开始到开始到“数组长度数组长度”1 1。n数组名代表的是数组在内存中的首地址。数组名代表的是数组在内存中的首地址。n同一个数组中的元素在内存中是按顺序连续存放的。同一个数组中的元素在内存中是按顺序连续存放的。数组是数目固定、类数组是数目固定、类型相同的多个数据的型相同的多个数据的有序排列。有序排列。例:例:int a 5;数组数组a的数组元素为:的数组元素为:a0,a1,a2,a3,a4a0的值a1的值a2的值a
3、3的值a4的值a44.1 数组(2)一维数组)一维数组的初始化:的初始化:语法格式为:类型类型 数组名数组名 数组长度数组长度 =元素元素1,元素,元素2,元素,元素3,例:例:int a 5 =1,2,3,4,5;int b 7 =1,2,3,4;/对前面连续的元素部分初始化数组对前面连续的元素部分初始化数组。这时这时b0=1,b1=2,b2=3,b3=4,b4=0float c =1.5,2.0,3.2,4.5;/没有给出数组的大小,则大没有给出数组的大小,则大小由元素个数确定小由元素个数确定。数组。数组c的大小为的大小为4。(3)访问一维数组元素)访问一维数组元素 数组不能整体使用,只能
4、逐个引用数组元素。数组元素的表示形数组不能整体使用,只能逐个引用数组元素。数组元素的表示形式:式:数组名数组名 下标下标例:例:int a3=1,2,3;int x=a 0 +a 1;cout a 2 endl;下标可以是整型常数、下标可以是整型常数、整型变量和整型表达整型变量和整型表达式,其起始值为式,其起始值为0。54.1 数组n例4.2:有5个元素的数组,在定义时初始化,要求计算这些值的平均数,并找出最大值和最小值。#include void main()int a5=13,44,-12,39,2;int i,avg,max,min;min=max=a0;avg=a0;for(i=1;i
5、 max)max=ai;if(ai min)min=aiavg/=5.0;cout “平均值是:”avg endl;cout “最小值是:”min endl;cout “最大值是:”max endl;6#include using namespace std;void main()int a10,t,i,j;cout请输入10个整数:endl;for(i=0;iai;for(i=1;i10;i+)for(j=0;jaj+1)t=aj;aj=aj+1;aj+1=t;for(i=0;i10;i+)coutai,;coutendl;例4.3冒泡排序法P817作业:P116第18题84.1 数组(4)
6、二维数组)二维数组的定义:的定义:n一般格式:一般格式:数据类型数据类型 数组名数组名 表达式表达式1 表达式表达式2 n例如,三个学生四门课程成绩数据如下:n 85 87 93 88n 86 90 95 89n 78 91 82 95n利用二维数组存放这些数据更能表现数据之间相互联系的特征。每一行数据表示该学生的各门课程的成绩,而每一列数据表示该门课程各学生的成绩。该数组定义为:n int a34;其中:其中:“表达式表达式1”用来指定数组中行的数目,用来指定数组中行的数目,“表达式表达式2”用来指用来指定数组中列的数目。整个二维数组的大小是定数组中列的数目。整个二维数组的大小是表达式表达式
7、1*表达式表达式2(即(即行数行数*列数列数)n可以把二维数组看作是一种特殊的一维数组:它的元素又是一个可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组。例如:一维数组。例如:int a34;可以把;可以把a看作是一个一维数组,它看作是一个一维数组,它有三个元素:有三个元素:a0、a1、a2,每个元素又是一个包含,每个元素又是一个包含4个元素个元素的一维数组。可以把的一维数组。可以把a0、a1、a2看作是一维数组的名字。看作是一维数组的名字。a0 a00 a01 a02 a03a1 a10 a11 a12 a13a3 a20 a21 a22 a2394.1 数组n逻辑结构:n
8、二维数组恰似一张表格(或矩阵)。数组元素中的第一个下标值表示该元素在表格中的行号,第二个下标为列号。M33具有如下逻辑结构:n M00 M01 M02n M10 M11 M12n M20 M21 M22n存贮结构:n 二维数组在内存中按一维数组存放、占据一片连续的存贮单元;是“按行顺序”在内存中分配存贮单元。数组在内存中排列如下:m00 m01 m02 m10 m11 m12 m20 m21 m22104.1 数组(5)二维数组的初始化:)二维数组的初始化:可以用下面的方法对二维数组初始化:可以用下面的方法对二维数组初始化:1)分行初绐化)分行初绐化int a25=1,3,5,7,9,2,4,
9、6,8,10;这种赋值方法比较直观,把第一个花括号内的数据给第一行的元素,第二个这种赋值方法比较直观,把第一个花括号内的数据给第一行的元素,第二个花括号内的数据给第二行的元素,花括号内的数据给第二行的元素,2)不分行初始化)不分行初始化可以将所有数据写在一个花括号内,按数组排列的顺序对每个元素赋初值。可以将所有数据写在一个花括号内,按数组排列的顺序对每个元素赋初值。如:如:int a25=1,3,5,7,9,2,4,6,8,10;3)部分初始化)部分初始化int a25=1,3,5,2,4,6;其余元素值自动为其余元素值自动为0。赋初值后数组各元素为:。赋初值后数组各元素为:4)省略行数)省略
10、行数对数组中的全体元素都赋初值时,二维数组的定义中第一维的长度也可以省对数组中的全体元素都赋初值时,二维数组的定义中第一维的长度也可以省略,但二维的长度不能省略。如:略,但二维的长度不能省略。如:int a23=1,3,5,7,9,11;等价于:等价于:int a 3=1,3,5,7,9,11;但不能写成:但不能写成:int a2=1,3,5,7,9,11;114.1 数组(6)访问二维数组元素)访问二维数组元素数组名下标1下标2其中的下标为整型表达式其中的下标为整型表达式,但不得越界。但不得越界。与一维数组元素一样与一维数组元素一样,二维数组元素相当于同类型的简二维数组元素相当于同类型的简单
11、变量。单变量。例如:a11=3;a21=a11;124.1 数组例 有一个3*4的矩阵,求出其中值最大的那个元素的值,以及其所在行号和列号。#include void main()int i,j,row,colum,max;int a34=1,2,3,4,9,8,7,6,-10,10,-5,2;max=a00;row=0;colum=0;for(i=0;i3;i+)for(j=0;jmax)max=aij;row=i;colum=j;cout “最大数是:”max “,行号是:”row;cout “,列号是:”colum endl;134.1 数组例:输入一个4行4列(4*4)的二维整型数组,
12、并将该数组输出,然后按行求元素之和、按列求元素之和、按对角线求元素之和。作业:P117第21题144.1 数组(7)string 类型类型在在ANSI/ISO标准标准C+颁布之前,标准颁布之前,标准C+库并不提供库并不提供string数数据类型。据类型。String由由C+标准库来支持,而不是标准库来支持,而不是C+语言本身语言本身的一部分。在使用的一部分。在使用string数据类型之前,需要在程序中包含数据类型之前,需要在程序中包含头文件头文件string并声明其所在的名字空间并声明其所在的名字空间std:#include using namespace std;n直接用直接用string声
13、明的变量:声明的变量:n变量可直接赋值。变量可直接赋值。n可用可用“+”号连接字符串,不必用号连接字符串,不必用strcatn可直接用可直接用“=”“=”“=”逻辑比较,不必用逻辑比较,不必用strcmpn可直接用可直接用“=”“+=”进行传值,不必用进行传值,不必用strcpyn可直接用可直接用“”进行字符串的流输入、输出。进行字符串的流输入、输出。例:定义一个例:定义一个string型变量:型变量:string st;cinst;st=st+”123”;coutstname;coutchar name10;cinname;coutname;name;注意字符数组和字符串这两个术语的区别。字
14、符串存放在字符数组中,但字符数组与字符串可以不等长。字符串以0作为结束标记。字符串是由若干字符组成的字符序列,字符串是由若干字符组成的字符序列,并且最后一个字符必须是结束符并且最后一个字符必须是结束符0174.1 数组例:例:#include void main()int i,j;char a 5=B,A,S,I,C,d,B,A,S,E ;for(i=0;i=1;i+)for(j=0;j=4;j+)coutaij;coutn;#include void main()int I,j;char a 6=“BASIC”,”dBASE”for(I=0;I2;I+)coutaIendl;184.1 数组
15、n例:编写程序实现将一个字符串s1中的小写字母转换成大写字母、大写字母保持不变,将结果存入另一个字符串s2中。#include void main()char s1=“tHiS Is a stRinG”;char s250;int i=0;while(s1i!=0)if(s1i=a&s1i=z)s2i=s1i-32;else s2i=s1i;i+;s2i=0;/一个字符串的结束标志是一个字符串的结束标志是0。couts1endl;couts2endl;194.1 数组练习:编写一个程序,该程序提示用户输入学生姓名及考试分数。练习:编写一个程序,该程序提示用户输入学生姓名及考试分数。该程序输出(
16、假定每个班级中最多有学生该程序输出(假定每个班级中最多有学生30人):人):(1)班级平均分;()班级平均分;(2)考试分数低于班级平均分的学生姓名;)考试分数低于班级平均分的学生姓名;(3)最高分以及最高分的学生姓名。)最高分以及最高分的学生姓名。#include /#includeusing namespace std;void main()char a306;/string a30;int b30;int n,i,avg=0;coutn;for(i=0;in;i+)coutaibi;coutendl;avg=avg+bi;avg=avg/n;cout班级平均分为班级平均分为avgendl
17、;int max=0,j;cout低于平均分的学生是:;for(i=0;in;i+)if(biavg)coutaiendl;if(maxbi)max=bi;j=i;cout最高分为:max姓名为:ajendl;204.1 数组(12)常用字符串函数)常用字符串函数C+提供了一系列字符串操作的函数,这些函数都包含在头文件提供了一系列字符串操作的函数,这些函数都包含在头文件cstring中。中。需要添加需要添加#include n常用的字符串函数有:常用的字符串函数有:(1)字符串拷贝:)字符串拷贝:char*strcpy(char*s1,char*s2):s2拷贝到拷贝到s1中,返回中,返回s1
18、的首地址的首地址;(2)字符串连接:)字符串连接:char*strcat(char*s1,char*s2):s2添加到添加到s1的末端,返回的末端,返回s1的首地址的首地址;(3)字符串比较:)字符串比较:int strcmp(char*s1,char*s2):如果:如果s1小于小于s2,返回一个负数,返回一个负数,s1等于等于s2,返,返回回0,s1大于大于s2,返回一个正数,返回一个正数;(4)求字符串长度:)求字符串长度:int strlen(char*s):返回字符串:返回字符串s的有效长度,末尾的空字符不计算在内的有效长度,末尾的空字符不计算在内;(5)查找字符串:)查找字符串:ch
19、ar*strstr(char*s1,char*s2):在字符串:在字符串s1中查找另一个字符串中查找另一个字符串s2,若查找,若查找成功则返回成功则返回s2在在s1中首次出现的位置,否则返回中首次出现的位置,否则返回NULL。214.1 数组(12)字符串处理函数)字符串处理函数C+提供丰富的提供丰富的字符串字符串处理处理函数,函数,在调用字符串处理函数时在调用字符串处理函数时则应包含头文件则应包含头文件。下面介绍几个最常用的字符串函数。下面介绍几个最常用的字符串函数。1、字符串拷贝函数字符串拷贝函数 strcpy()格式:格式:strcpy(字符数组名字符数组名1,字符数组名,字符数组名2)
20、或或 strcpy(字符字符指针指针1,字符,字符指针指针2)功能:把字符数组功能:把字符数组2中的字符串拷贝到字符数组中的字符串拷贝到字符数组1中。串结束标志中。串结束标志“0”也一同拷贝。也一同拷贝。字符数名字符数名2,也可以是一个字符串常量。这时相当于把一个字符串赋予一个字,也可以是一个字符串常量。这时相当于把一个字符串赋予一个字符数组。符数组。例:例:#include#include using namespace std;void main()char st115,st2=C Language;strcpy(st1,st2);coutst1endl;strncpy(字符数组名字符数组
21、名1,字符数组名字符数组名2,整数整数n)或或 strncpy(字符字符指针指针1,字符字符指针指针2,整数整数n)将字符串将字符串2的前的前n个字符复个字符复制到字符数组制到字符数组1中中224.1 数组2、字符串连接函数字符串连接函数 strcat()格式:格式:strcatstrcat(字符数组名字符数组名1,1,字符数组名字符数组名2)2)或或strcatstrcat(字符指针字符指针1,1,字符指针字符指针2)2)功能:把字符数组功能:把字符数组2 2中的字符串连接到字符数组中的字符串连接到字符数组1 1中字符串的后面,并中字符串的后面,并在最后加一个在最后加一个“0”0”。连接后新
22、的字符串存放在字符数组。连接后新的字符串存放在字符数组1 1中,因中,因此字符数组此字符数组1 1必须定义的足够大。必须定义的足够大。例例#include iostream#include#include cstring#include using namespace std;using namespace std;void main()void main()char st130=“char st130=“我的名字是我的名字是;char st210char st210;coutcout“st2st2;strcat(st1,st2)strcat(st1,st2);coutst1endlcouts
23、t1endl;234.1 数组3、字符串比较函数字符串比较函数 strcmp()格式为:格式为:strcmp(字符数组名字符数组名1,字符数组名字符数组名2)或或 strcmp(字符指针字符指针1,字符指针字符指针2)其返回值如下:其返回值如下:(1)当当str1串等于串等于str2串时,返回值串时,返回值0;(2)当当str1串大于串大于str2串时,返回一个正值;串时,返回一个正值;(3)当当str1串小于串小于str2串时,返回一个负值。串时,返回一个负值。strncmp(字符数组名(字符数组名1,字符数组名,字符数组名2,整数,整数n););将两个字符将两个字符串进行比较。串进行比较。
24、只对两个字符串的只对两个字符串的前前n个字符比较,个字符比较,后面的不比较。后面的不比较。例:例:#include#include#include cstring#include using namespace std;using namespace std;void main()void main()char str110=hello;char str110=hello;char str210=hello;char str210=hello;if(strcmp(str1,str2)=0)if(strcmp(str1,str2)=0)coutcout“相等相等n”;n”;elseelsecou
25、tcout“不相等不相等n;n;244.1 数组4、字符串长度函数字符串长度函数 strlen()格式为:格式为:strlenstrlen(字符数组字符数组名名)函数返回值:函数返回值:字符串中的实际字符个数。字符串中的实际字符个数。参数还可以参数还可以是字符指针是字符指针或字符串常或字符串常量。量。例:#include#include#include cstring#include using namespace std;using namespace std;void main()void main()char str150;char str150;cin cinstr1;str1;int
26、int n;n;n=strlen(str1);n=strlen(str1);coutcout“长度为长度为”nendlnendl;254.1 数组n例4.5 P90264.1 数组作业:作业:1、输入、输入10个学生的成绩,求平均成绩,并将低于平均成个学生的成绩,求平均成绩,并将低于平均成绩的分数打印出来。绩的分数打印出来。2、将一个二维数组的行与列的元素交换,存到另一个二、将一个二维数组的行与列的元素交换,存到另一个二维数组中。维数组中。3、编写程序实现将用户输入的两个字符串连接,放在第、编写程序实现将用户输入的两个字符串连接,放在第一个字符串中。要求使用字符数组保存字符串。一个字符串中。要
27、求使用字符数组保存字符串。4、将一个数组、将一个数组a中的元素按反向的顺序存放。中的元素按反向的顺序存放。P11618、19、20、21274.1 数组#includeusing namespace std;void main()char a50,b10;int i,j;couta;coutb;i=j=0;while(ai)i+;while(bj)ai=bj;j+;i+;ai=0;coutaendl;coutbendl;284.2 指针和引用二、指针和引用二、指针和引用本节目标:本节目标:1、掌握指针和指针变量的概念、掌握指针变量的定义、赋值方法,、掌握指针和指针变量的概念、掌握指针变量的定义
28、、赋值方法,熟练使用指针访问简单变量,指针的加减运算;熟练使用指针访问简单变量,指针的加减运算;2、掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访、掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素;问一维数组元素;3、掌握指针与字符串的关系;、掌握指针与字符串的关系;4、掌握内存动态分配的方法掌握内存动态分配的方法;5、掌握引用的概念。掌握引用的概念。294.2 指针和引用(一)指针(一)指针1、指针的概念、指针的概念n通过前面的学习,我们已知道:通过前面的学习,我们已知道:nC+C+程序的变量所存放的数据:程序的变量所存放的数据:n数值型数据:整数、实数数值型
29、数据:整数、实数n字符型数据:字符、字符串字符型数据:字符、字符串n构造型数据:数组、结构体、共用体构造型数据:数组、结构体、共用体n这些变量具有的性质:这些变量具有的性质:n占有一定长度的内存占有一定长度的内存 单元单元 如如:int x;x占占4字节、字节、4个内存单元个内存单元。n每一个变量都有一个地址,为无符号整数,它不同于一般的每一个变量都有一个地址,为无符号整数,它不同于一般的整数。整数。问题:问题:能否对地址运算?能否对地址运算?能否用一个变量保存地址?能否用一个变量保存地址?304.2 指针和引用n数据在内存中的存放数据在内存中的存放n内存:内存:为一个连续编号(连续地址)且以
30、一个单元为一个字节的连续存贮区。若程序中定义了两个int变量i,j int i=5,j=5;设设:系统分配i的起始地址为2000的单元则则:j的起始地址有可能为为2004的单元n当程序中要用它们的值时:当程序中要用它们的值时:y=i+j;n则系统通过一张变量名与地址对应关系表:则系统通过一张变量名与地址对应关系表:n分别分别 找到i的地址2000,将20002003中的数据5读出;n找到j的地址2004,将20042007中的数据5读出;n然后把这些数据进行算术运算。然后把这些数据进行算术运算。2000200120022003200420053001 5+52000ij20062007314.
31、2 指针和引用上述过程称为变量的上述过程称为变量的“直接访问直接访问”直接访问直接访问:直接使用存放该数据的变量名。直接使用存放该数据的变量名。间接访问间接访问:如果将某一变量的地址如果将某一变量的地址(如如 i 的地的地址址2000)存放到另一个变量存放到另一个变量x,则可,则可通过通过x来存取来存取i的值。的值。i相当于使用相当于使用 5使用变量使用变量324.2 指针和引用如:如:用用pi,pj来存放来存放i,j的地址的地址20002004 55300130033005300720002004pipjij若要得到变量若要得到变量i的值,可以先访问的值,可以先访问pi,得到,得到i的地址,
32、的地址,再通过该地址找到再通过该地址找到i的值。的值。334.2 指针和引用显然,显然,pi与与i是通过是通过i的地址联系起来的。的地址联系起来的。定义:定义:一个一个变量的变量的地址称为该变量的指针地址称为该变量的指针。因。因此,此,i的指针的值为的指针的值为2000。如如:pi就是指针变量。而存放地址而存放地址(指针指针)的变量叫做指针变量的变量叫做指针变量。指针和指针变量是两个不同的概念,指针是数据对象的地址,是不可变的,指针和指针变量是两个不同的概念,指针是数据对象的地址,是不可变的,而指针变量中的内容是可以改变的,既可存放对象而指针变量中的内容是可以改变的,既可存放对象a a的地址,
33、又可存放对的地址,又可存放对象象b b的地址,也就是说,的地址,也就是说,pi pi 既可指向对象既可指向对象a a,又可指向对象,又可指向对象b b。在不致产生。在不致产生混淆的情况下,经常将混淆的情况下,经常将“指针变量指针变量”简单地说成了指针。简单地说成了指针。344.2 指针和引用2、指针变量的定义、指针变量的定义数据类型数据类型 变量名变量名n其中数据类型表示指针所指向的对象的数据类型。其中数据类型表示指针所指向的对象的数据类型。n如:如:int p;(p为指向整型数据的指针变量)char*s;(s为指向字符型数据的指针变量)float*t;(t为指向浮点型数据的指针变量)指针变量
34、名前的指针变量名前的“*”是指针变是指针变量说明符,说明其后的变量(如量说明符,说明其后的变量(如p p、s s、t t)是指针变量,但它并)是指针变量,但它并不是指针变量名的组成部分。不是指针变量名的组成部分。与指针相关的运算符:与指针相关的运算符:1)取地址运算符)取地址运算符“&”&变量名变量名 例:例:int i=2,*pi;pi=&i;2)间接访问运算符)间接访问运算符“*”*指针变量名指针变量名 例:例:int i=2,*pi;pi=&i;cout *pi;*pi 代表pi所指向的变量i&i的值为i的地址。354.2 指针和引用3、指针变量的赋值、指针变量的赋值 指针变量的初始化:
35、在定义指针变量的同时为其赋初值。指针变量的初始化:在定义指针变量的同时为其赋初值。数据类型数据类型*指针变量名指针变量名1=地址地址1,*指针变量名指针变量名2=地址地址2;其中的地址形式有多种,如:其中的地址形式有多种,如:&变量名、数组名、另外的指针变变量名、数组名、另外的指针变量等。量等。例:例:int i=10;int*pi=&i;int a5;int*pa=a;或或 int*pa=&a0;int i,*p1=&i,*p2=p1;使用赋值语句赋值使用赋值语句赋值指针变量地址指针变量地址例如:例如:intint m=19,m=19,*p,p,*q;q;p=&m;/p=&m;/将变量将变量
36、m m的地址赋给指针变量的地址赋给指针变量p p q=p;/q=p;/利用指针变量利用指针变量p p为指针变量为指针变量q q赋值赋值int*p1=NULL;/值为值为“NULL”的指针称为空指针。的指针称为空指针。即不指向任何数据。即不指向任何数据。给指针变量赋值给指针变量赋值就是将一个地址就是将一个地址赋给一个指针变赋给一个指针变量的过程量的过程指针变量只能存放指针变量只能存放相同类型的数据对相同类型的数据对象的内存地址。象的内存地址。364.2 指针和引用注意区分下面三种表示方法所具有的不同意义。注意区分下面三种表示方法所具有的不同意义。例如,有一个指针变量例如,有一个指针变量px=&a
37、,npx -指针变量,它的值是所指向的变量指针变量,它的值是所指向的变量a的地址。的地址。n*px -指针所指向的变量,它的值是数据。等效于变量指针所指向的变量,它的值是数据。等效于变量a。n&px -指针变量在内存中的地址。指针变量在内存中的地址。px&px*pxa374.2 指针和引用注:指针在使用前,必须先给它赋一个具体对象的地址。注:指针在使用前,必须先给它赋一个具体对象的地址。例如,下面的代码是危险的:int i;int*Pi;*Pi=58;/!指针忘了赋值比整型变量忘了赋值危险得多。Pi当前指向什么地方?该代码能通过编译,但没有赋初值的指针Pi是一个随机地址。“*Pi=58;”是把
38、58赋到内存中的随机位置,因此该赋值将破坏内存中某个地址空间中的内容,严重时将导致计算机死机或进入死循环。384.2 指针和引用例:例:#include void main()int*p,x=30;p=&x;cout “x=”x endl;cout “*p=”*p endl;*p=50;cout “x=“x endl;cout “*p=”*p endl;cout “p=”p endl;cout “&x=”&x endl;cout “&p=”&p endl;练习:指出下面程序的运行结果#include void main()int a=10,b=10,*ptr1,*ptr2;ptr1=&a;pt
39、r2=&b;cout(*ptr1=*ptr2)endl;cout(ptr1=ptr2)endl;*ptr1=20;b=15;coutaendl;cout*ptr2endl;394.2 指针和引用练习:输入a和b两个整数,用指针法实现从大到小输出#include void main()int a,b;int*p1,*p2,*p;coutab;p1=&a;p2=&b;if(*p1*p2)p=p1;p1=p2;p2=p;/*指针交换指向*/cout*p1“*p2,=n算术运算:算术运算:完成指针移动,实现对不同数据单元的访问操作。这种运算与指针指向的数据类型有密切关系。设p和q是指向具有相同数据类型
40、的一组若干数据(一般为数组)的指针,n是整数,则指针可以进行的算术运算有如下几种:p+n,p-n,p+,+p,p-,-p,p-q指针运算的实质指针运算的实质是地址的计算。是地址的计算。结果为两个指结果为两个指针之间相差元针之间相差元素的个数。素的个数。结果为指向p所指位置后第n个元素的指针。等价于p=p+1即p指向下一个元素。等价于p=p-1即p指向前一个元素。414.2 指针和引用n例如:当有如下数组声明语句时:例如:当有如下数组声明语句时:intint a5=10,20,30,40,50 a5=10,20,30,40,50;则内存中将开辟如图则内存中将开辟如图1 1所示的五个连续的、存放所
41、示的五个连续的、存放intint型数据的存储单位(每型数据的存储单位(每个存储单位占个存储单位占4 4个字节单元),其对应的标识名称分别个字节单元),其对应的标识名称分别为为a0a0、a1a1、a2a2、a3a3、a4a4,其中存放的整数,其中存放的整数分别为分别为1010、2020、3030、4040、5050,如下图所示:,如下图所示:q=p+4int*p=a;int q;q-;/?q-p;/?p+;/?a0a1a2a3a41020304050 pa0a1a2a3a41020304050 p q424.2 指针和引用n例:下面程序说明指针和整数相加的结果#include void main
42、()int*p,a10=0,1,2,3,4,5,6,7,8,9;double*q,b10=10,11,12,13,14,15,16,17,18,19;p=a;q=b;for(int I=0;I10;I+)cout p+I“*(p+I)“q+I“”*(q+I)q,p q为真,则为真,则p指向位置在指向位置在q指向位置的后方。指向位置的后方。注意几组常见的指针表达式的比较:设注意几组常见的指针表达式的比较:设p为指针变量,为指针变量,y为普通变量。为普通变量。(1)p+和和 p+1的区别的区别:p+结果为结果为p指向下一元素;指向下一元素;p+1结果为结果为下一元素的指针,但下一元素的指针,但p本
43、身不变。本身不变。(2)y=*p+1和和y=*(p+1)的区别的区别:*p+1结果为取结果为取p所指对象的值加所指对象的值加1;*(p+1)结果为结果为p指针加指针加1,并取,并取(p+1)指针所指对象的值赋给指针所指对象的值赋给y。(3)y=(*p)+和和y=*p+的区别的区别:(*p)+先取指针先取指针p所指对象的所指对象的值赋给值赋给y,然后对指针,然后对指针p所指对象的值加所指对象的值加1;*p+表达式中后缀增量表达式中后缀增量+优先级别高于优先级别高于*,所以,所以+运算是对运算是对p进行的。它相当于:进行的。它相当于:y=*(p+)这里这里p+是后置运算。因此该表达式的运算顺序是,
44、是后置运算。因此该表达式的运算顺序是,取指针取指针p所所指对象的值赋予指对象的值赋予y,然后,然后p加加1指向下一个目标。指向下一个目标。444.2 指针和引用练习:指出下面程序的运行结果:#include void main()int a6=1,2,3,4,5,6;int*p1=a,*p2;p2=p1+2;cout*p1“*p2endl;int s;s=*p1+;couts“p1endl;s=(*p1)+;couts“”p1endl;cout*p1endl;coutp2-p1endl;454.2 指针和引用6、指针与数组、指针与数组(1)(1)用指针常量访问数组元素用指针常量访问数组元素在在
45、C+语言中,数组名不仅仅表示数组的名称,还表示数组在内存语言中,数组名不仅仅表示数组的名称,还表示数组在内存中的首地址。数组名是由系统分配的地址常量,不允许用户修改。中的首地址。数组名是由系统分配的地址常量,不允许用户修改。例如,对于数组例如,对于数组int a10=1,2,3,4,5,6,7,8,9,10;a 表示数组表示数组a的首地址,即第的首地址,即第1个元素的地址;个元素的地址;a+1 表示第表示第2个元素的地址;个元素的地址;a+i 表示第表示第i+1个元素的地址(个元素的地址(0=i=9););知道了数组元素的地址就可以对数组元素进行访问。可以用知道了数组元素的地址就可以对数组元素
46、进行访问。可以用下标下标 和指针两种形式访问数组元素。和指针两种形式访问数组元素。下标形式下标形式 指针形式指针形式 a0 *(a+0)a1 *(a+1)ai *(a+i)(0=i=9)所以所以a+i与与&ai是等价的(表示第是等价的(表示第i+1个数组元素的地址);个数组元素的地址);ai与与*(a+i)是等价的(表示第是等价的(表示第i+1个数组元素的值)。个数组元素的值)。464.2 指针和引用(2)(2)用指针变量访问数组元素用指针变量访问数组元素n定义指向一维数组的指针变量定义指向一维数组的指针变量int a6=10,20,30,40,50,60;int*p=a;或或 int*p=&
47、a0;/将数组将数组a的首地址(第一个元素地址)赋值给指针变量的首地址(第一个元素地址)赋值给指针变量p。用指针变量对数组元素的访问也可以采用下标形式和指针形式两种。用指针变量对数组元素的访问也可以采用下标形式和指针形式两种。下标形式下标形式 指针形式指针形式 pipi *(p+i)(p+i)pipi和和*(p+i)(p+i)这两种形式是等价的,都表示访问数组的第这两种形式是等价的,都表示访问数组的第i+1i+1个元素。个元素。(3)(3)由上述可知,引用数组元素(取数组第由上述可知,引用数组元素(取数组第i i个元素)的个元素)的方法如下:方法如下:n指钍法:指钍法:*(p+i)、*(a+i
48、);n下标法:下标法:p i 、a i;尽管用指针和数组名都能对数组元素尽管用指针和数组名都能对数组元素进行访问,但二者有区别:指针是一进行访问,但二者有区别:指针是一个变量,它的值可以变化;而数组名个变量,它的值可以变化;而数组名是数组的首地址,是一个常量,其值是数组的首地址,是一个常量,其值不能改变。如:不能改变。如:a+、a=&x等操作都等操作都是非法的。是非法的。474.2 指针和引用n例:用5种方法实现一维数组的输出。#include using namespace std;void main()int a5=5,4,3,2,1;int*p=a;for(int i=0;i5;i+)c
49、outpit;coutendl;#include using namespace std;void main()int a5=5,4,3,2,1;for(int i=0;i5;i+)coutait;coutendl;#include using namespace std;void main()int a5=5,4,3,2,1;for(int i=0;i5;i+)cout*(a+i)t;coutendl;#include using namespace std;void main()int a5=5,4,3,2,1;int*p=a;for(int i=0;i5;i+)cout*(p+i)t;c
50、outendl;#include using namespace std;void main()int a5=5,4,3,2,1;int*p=a;for(int i=0;i5;i+)cout*p+t;coutendl;484.2 指针和引用n练习:用5种方法对一个数组求和。#include void main()int sum=0;int a5=3,5,6,12,9;for(int I=0;I5;I+)sum+=aI;coutsumendl;#include void main()int sum=0;int a5=3,5,6,12,9;for(int I=0;I5;I+)sum+=*(a+I)