四章数组与指针ppt课件.ppt
uangXi University,1,C/C+程序设计,胡立坤,uangXi University,2,第4章数组与指针及其应用,4.1 一维数组4.2 二维数组4.3 字符串4.4 指针和数组4.5动态数组4.6 程序举例,数组用于保存大量同类型的相关数据,如矩阵运算,表格数据等。,uangXi University,3,4.1一维数组,4.1.1 引例例4.1求N个学生的平均成绩,并统计高于平均分的人数。,用以前所学知识实现:int k=0;float s,ave,sum=0;for(int i=0;is;sum=sum+s;ave=sum/100;for(i=0;is;if(save)k+;,用数组来实现:int k=0;float s100,ave,sum=0;for(i=0;isi;sum=sum+si;ave=sum/100;for(i=0;iave)k+;,数组:一组数据类型相同的元素按一定顺序存放,构成的数据集合。,采用随机数函数si=rand()%101,uangXi University,4,4.1一维数组,4.1.2一维数组的定义、存储和初始化(1)数组的形式 数据类型 数组名整型常量表达式;如:int s5;s0 s1 s2 s3 s4 下标从0开始数组名是常量,表示数组在内存中的首地址。数组长度应该为整型常量表达式,不能是变量。如:,正确:const int s=10;int as;float f5;,错误:int s=10;int as;float b3.4,uangXi University,5,4.1一维数组,(2)数组的初始化 a.给所有元素赋初值。如:int a5=0,2,4,6,8;或 int a=0,2,4,6,8;b.给部分元素赋初值。如:int a10=1,3,5,7,9;花括号内列出的值赋给前面的若干个元素,其余元素自动赋0。以下的语句均是错误:int a10;a=1,3,5,7,9;/数组名是个地址常量,不能被赋值。int a10;a10=1,3,5,7,9;/a10不是数组中的元素,并且不能用花括号为一个元素赋多个值。int c3=1,2,3,4;/常量个数超过数组定义的长度。,花括号,uangXi University,6,4.1一维数组,说明:数组大小最好用宏来定义,以适应未来可能的变化#define SIZE 10int aSIZE;对数组每个元素的使用与普通变量无异,可以快速地随机访问可以用任意表达式作为下标,动态决定访问哪个元素for(i=0;iSIZE;i+)ai=2*i;下标越界是大忌!使用大于最大下标的下标,将访问数组以外的空间。那里的数据是未知的,可能带来严重后果sizeof可以用来获得数组大小一旦定义,不能改变大小,uangXi University,7,4.1一维数组,4.1.3数组元素的引用和基本操作(1)数组元素的引用 形式:数组名下标-相当于一个普通变量,如有:int a10=1,2,3,4,5,6,7,8,9,10,b10,i(2);则:a3=a0+ai;/a3=1+3=4 couta2+i;/输出a4元素的值 coutaa3;/aa3=a4=5 couta10;/数组下标越界 couta;/对数组一般不能作为一个整体进行操作 b=a;,uangXi University,8,4.1一维数组,(2)基本操作 假设有定义:int aN;N是已定义过的符号常量。数组元素的输入和输出-for(j=0;jaj;-for(j=0;jN;j+)coutaj;-for(i=0;i10;i+)scanf(%d,uangXi University,9,4.1一维数组,求数组中的最大元素-max=a0;/假设第一个元素值最大 for(j=1;jmax)max=aj;求最大元素下标-imax=0;/imax代表最大元素下标 for(j=1;jaimax)imax=j;将最大元素放于某一特定位置(如放在最前头)-imax=0;for(j=1;jaimax)imax=j;if(imax!=0)t=a0;a0=aimax;aimax=t;,uangXi University,10,4.1一维数组,4.1.4 数组排序 排序是将一组数按递增或递减的次序排列,如按学生的成绩、球赛积分等排序。常用的算法有:,选择法()冒泡法()插入法 快速排序法.,uangXi University,11,4.1一维数组,(1)选择法排序-基本思想:(a)从n个数的序列中选出最小的数(递增),与第1个数交换位置;(b)除第1个数外,其余n-1个数再按(1)的方法选出次小的数,与第2个数交换位置;(c)重复(1)n-1遍,最后构成递增序列。例4.3对存放在数组中的6个数,用选择法按递增排序。,下标 0 15 1 25 2 35 3 45 4 5,for(i=0;i5;i+)min=i;for(j=i+1;j6;j+)if(ajamin)min=j;if(i!=min)temp=ai;ai=amin;amin=temp;,uangXi University,12,4.1一维数组,(2)冒泡法排序-基本思想:(a)从第一个元素开始,对数组中两两相邻的元素比较,将值较小的元素放在前面,值较大的元素放在后面,一轮比较完毕,最大的数存放在aN-1中;(b)然后对a0到aN-2的N-1个数进行同(a)的操作,次最大数放入aN-2元素内,完成第二趟排序;依次类推,进行N-1趟排序后,所有数均有序。例4.4用冒泡排序法实现例4.3,for(i=0;iaj)temp=aj-1;aj-1=aj;aj=temp;,思考:当数据未交换,说明数组已有序,如何结束排序?,uangXi University,13,4.2二维数组,4.2.1 二维数组的定义和初始化(1)数组的定义 形式:数据类型 数组名常量表达式1常量表达式2;如:float a23;,以“先行后列”的规则连续存放:,序号=当前行号*每行列数+当前列号,序号:0 1 2 3 4 5,uangXi University,14,4.2二维数组,(2)数组的初始化,(a)按在内存排列顺序对所有元素赋初值。(b)按行给所有元素赋初值,每一行的数据放于一个花括号内。(c)按行给部分元素赋初值,省略的元素初值此时自动为0。对应的数组b为:(d)按行赋初值也可省略第一维的长度。对应的数组c为:,int a23=1,2,3,4,5,6;或 int a3=1,2,3,4,5,6;,int a23=1,2,3,4,5,6;,int b34=1,2,0,3,4,0,0,5;,int c 3=1,0,2;,uangXi University,15,4.2二维数组,4.2.2 二维数组的基本操作(1)数组的输入、输出例4.5输入两个矩阵A、B的值,求C=A+B。,分析:(1)A、B矩阵相加,其实质是将两矩阵的对应元素相加。相加的条件是有相同的行、列数。(2)输入可以通过空格、Tab符和回车符控制;输出内循环不换行,出了内循环输出endl换行。,uangXi University,16,4.2二维数组,#include iostream.h#include iomanip.h void main()int a23,b23,c23,i,j;for(i=0;iaij;for(i=0;ibij;for(i=0;i2;i+)/A+B矩阵,每个对应元素相加 for(j=0;j3;j+)cij=aij+bij;for(i=0;i2;i+)for(j=0;j3;j+)coutsetw(4)cij;coutendl;,uangXi University,17,4.2二维数组,(2)求二维数组中最大(或最小)元素及下标 例4.6对33方阵,求最大元素及下标。与一维数组求最大值的方式相同,max=a00;imax=0;jmax=0;for(i=0;imax)max=aij;imax=i;jmax=j;,uangXi University,18,4.2二维数组,(3)矩阵转置:将矩阵以主对角线为轴线,将元素的行和列位置调换。如对33方阵转置,for(i=0;i3;i+)for(j=0;ji;j+)t=aij;aij=aji;aji=t;,uangXi University,19,4.2二维数组,4.矩阵相乘例4.7求两个矩阵aMN和bNP的乘积 c。,设矩阵A、B为:,则矩阵C为:,即矩阵C的第i行第j列元素可通过右边公式求得:,c00元素的实现:s=0;for(k=0;k3;k+)s+=a0k*bk0;c00=s;,uangXi University,20,4.2二维数组,#include iostream.h#define M 2#define N 3#define P 4void main()int aMN=3,5,7,4,6,8,bNP=1,4,7,10,2,5,8,11,3,6,9,12;int cMP,i,j,k,s;for(i=0;iM;i+)for(j=0;jP;j+)s=0;/求一个元素的值 for(k=0;kN;k+)s+=aik*bkj;cij=s;for(i=0;iM;i+)for(j=0;jP;j+)coutcij;coutendl;,uangXi University,21,4.3字符串,字符串常量:ab123,系统自动添加 0(结束标志符),处理字符串的方法有:字符数组、CString(string)类和字符指针。本节只介绍前两种方法,后一种方法我们将在下一节介绍。,uangXi University,22,4.3字符串,4.3.1 字符数组(1)字符数组 char s6;-既可以存放若干个字符,也可以存放一个字符串。char s28;-可以存放一组相关的字符串,按要处理字符串中最大长度来定义列数。,s0,s1,si0,si7,uangXi University,23,4.3字符串,(2)字符数组的初始化(a)逐个字符赋初值(b)用字符串为字符数组初始化(c)字符串数组初始化 对二维数组以字符串形式初始化。对于二维字符数组,用两个下标表示数组中的一个字符。,char s10=I,a,m,f,i,n,e;/s不是字符串,char s10=I am fine;char s10=I am fine;s是字符串,0 系统自动添加,char a48=COBOL,FORTRAN,PASCAL,C/C+;,uangXi University,24,4.3字符串,注意不要出现下面的错误:,char s10=“This is a book”;/长度超过了 char s10;s=“I am fine”;/不能将字符串常量赋给地址常量 char s10;s=I,a,m,f,i,n,e;/同样不能将一系列字符赋给地址常量 char s34;s7=c;/不能将二维数组当成一维数组访问,uangXi University,25,4.3字符串,(3)字符数组的输入/输出 逐个数组元素的输入/输出,char s110;for(i=0;is1i;/s1中是字符,不是字符串/C:scanf(“%c”,i+)couts1i/通过循环逐个输出/C:printf(“%c”,&s1i),注意:a.输入时各输入项之间不需加空格分隔 b.输入多出的字符不会被处理 c.逐个字符输出,uangXi University,26,4.3字符串,字符串整体的输入/输出,char s110,s225;输入:输出:cins1;cout s1;gets(s1);/C:scanf(%s,s1);puts(s1);/C:printf(%s,s1);for(int i=0;i2;i+)for(i=0;i2;i+)gets(s2i);puts(s2i);/C:scanf(%s,s2i);/C:printf(%s,s2i);s1、s2中是字符串,0自动添加,注意:使用cins1;语句,字符串中不能有空格。这与scanf一样。gets()和puts()是对字符串整体输入/输出,应加#include“stdio.h”命令。并且允许字符串中的空格,gets()以回车符r结束。gets(字符数组名或字符指针变量名);puts(字符数组名或字符指针变量名)。,uangXi University,27,4.3字符串,字符串输入函数gets()没有提供限制输入字符串长度的方法,容易引起缓冲区溢出,给黑客攻击以可乘之机。对输入字符串长度有限制的函数调用 fgets(buf,sizeof(buf),stdin);对于scanf,当用户的输入多于定义时,str数组将越界。所以scanf被公认为最易遭到黑客攻击的函数之一。getline(cin,str,定界符);从输入流读入一串字符,直到出现下列情况:(1)到达文件尾,这样,输入流的edfbit被设置,调用方法file()或eof()都将返回true;(2)遇到分界字符,默认为n,这种情况下,将把分界字符从输入流中删除,而且不存储她;(3)读取的字符到达最大的允许值,它将设置输入流的failbit,这意味着fail()方法返回true;/Attention!实际上,cin类中也有getline、get成员函数,详细地说明将在I/O流那一章给出。,uangXi University,28,4.3字符串,(4)字符串处理函数 在标准C+中使用下面函数时,应加#include string.h命令。a.strlen(str)功能:求str所指向的字符串长度。不包括字符串结束标志0。说明:str可为字符串常量、字符数组名或字符指针。b.strlwr(str)功能:将字符串中的大写字母转换成小写字母。说明:str为字符字符串常量、数组名或字符指针。c.strupr(str)功能:将字符串中的小写字母转换成大写字母。说明:str为字符字符串常量、数组名或字符指针。,uangXi University,29,4.3字符串,d.strcpy(str1,str2)功能:将str2所指的字符串复制到str1中。说明:str1和str2为字符数组名或字符指针,str2还可以是字符串常量。str1要有足够大的空 间。e.strcat(str1,str2)功能:将str2字符串内容连接到str1字符串内容的后面 说明:str1要有足够大的空间。例如:char s120=abcd;coutstrcat(s1,kkk)endl;/s1中的内容变为abcdk,设:char str210=aaa,str110;,strcpy(str1,str2);str1=bb;str1=str2;,uangXi University,30,4.3字符串,f.strcmp(str1,str2)功能:比较字符串str1和str2的大小。说明:从左至右逐个字符进行比较ASCII码值,直到出现不相同字符或遇到0为止。str1 小于str2 返回-1 str1等于str2 返回 0 str1大于str2 返回 1例4.8字符串处理函数示例,strcmp(ABCD,BD;/结果为:-1,#include stdio.h#include string.hvoid main()char s80;while(1)gets(s);if(strcmp(s,pass),puts(Invalid password.n);else break;puts(passn);,uangXi University,31,4.3字符串,4.3.2 CString 类(补充)对字符串的存取及有关操作,在VC开发平台下还可通过MFC中的CString 类。(1)定义CString 类对象 CString 类的定义在“afx.h”头文件中形式:CString 对象名;CString 对象名=字符串常量;CString 对象名(字符串常量);CString 对象名(字符,int n);/重复产生n个相同的字符如:CString s1=C/C+程序设计;CString s(d,5);couts;/s获得字符串ddddd,/CString类中有多个构造函数(多态),uangXi University,32,4.3字符串,(2)输入/输出例4.补1 示例#include iostream.h#include afx.hvoid main()char c80;CString st1;coutc;st1=c;cout输出结果:;coutst1endl;,由于VC+并不能直接使用cin对CString对象进行操作,应利用字符数组间接输入,CString对象可直接通过cout输出,uangXi University,33,4.3字符串,(3)基本运算假设定义:CString st1(ASDFG),st2,st3(DD);,uangXi University,34,4.3字符串,(4)成员函数形式:函数值类型 CString对象.成员函数名(参数列表)a.取子串形式:CString Mid(int nFirst,int nCount)/取字符串中nFirst位置开始的nCount个字符 CString Left(int nCount)/取字符串的左边nCount个字符 CString Right(int nCount)/取字符串的右边nCount个字符,有定义:CString s(12345);则:s.Mid(2,2)的值为34 s.Left(3)的值为123,uangXi University,35,4.3字符串,例4.补2 利用Left函数,输出如图所示的结果。,分析:确定每行显示字符的起始位,通过setw(n)显示一个空格的位数来实现,也可通过产生一个有若干个空格的字符串后left(n)显示n个空格来实现。显示可变的,利用left(n)。,如果不利用left函数,你如何输出如图所示的结果?,CString st1(,30);/产生30个空 CString st2(ABCDEFGHIJKLMNOPQRS);for(int i=1;i=10;i+)coutst1.Left(10-i)st2.Left(2*i-1)endl;,uangXi University,36,4.3字符串,b.查看字符串信息int Find(TCHAR ch);/返回指定字符在串中的位置int Find(LPCTSTR lpszSub);/返回指定子字符串在串中的位置int GetLength();/返回字符串的字符数,有定义:CString s(ABCDEF);则:s.Find(C)的值为2 s.Find(BCD)的值为1 s.GetLength()的值为6,uangXi University,37,4.3字符串,例4.补3 程序输入5个单词,显示最长的单词及长度。,#include stdio.h“#include iostream.h“#include afx.hvoid main()CString st1,maxst;char s80;int maxlen(0),len,i;coutmaxlen)maxlen=len;/找最长的单词长度 maxst=st1;/找最长的单词 coutmaxstmaxlenendl;,uangXi University,38,4.3字符串,c.字符串修改 void SetAt(int nIndex,TCHAR ch)/用字符替换指定位置的字符 int Insert(int nIndex,TCHAR ch)/将字符插入到指定位置前 int Delete(int nIndex,int nCount=1)/从指定位置开始删除一个或多个字符 int Replace(TCHAR chOld,TCHAR chNew)/将新字符替换字符串中的老字符 int Replace(LPCTSTR lpszOld,LPCTSTR lpszNew)/同上,区别替换的是子字符串,有定义:CString s(ABCDEF);则:s.SetAt(1,b);couts;/输出AbCDEF s.Insert(1,b);couts;/输出AbBCDEF s.Replace(g,k);couts;/输出ABCDEF s.Replace(BCD,bc);couts;/输出AbcEF,思考:如何删除字符串中任意子字符串?,uangXi University,39,4.3字符串,例4.补4 对已知输入的字符串,用定冠词替换The。,#include iostream.h#include afx.hvoid main()CString st1(The There Then The Thara);cout替换前st1=st1endl;st1.Replace(The,定冠词);cout替换后st1=st1endl;,uangXi University,40,4.3字符串,d.转换字符串void MakeUpper()/将字符串中的所有字符转换成大写 void MakeLower()/将字符串中的所有字符转换成小写 void MakeReverse()/将字符串中各字符的顺序倒转void Empty()/将字符串中的所有字符删除,有定义:CString s(ABCabc);则:s.MakeUpper();couts;输出:ABCABC s.MakeReverse();couts;输出:cbaCBA s.Empty();couts;输出:(空),uangXi University,41,4.3字符串,e.格式化输出形式:viod Format(格式字符串,输出参数列表);功能:构造一个输出的字符串,类似于C中的printf。其中:“格式字符串”由输出的文字和数据格式说明符组成,文字可以是直接键入的各种字符,还可以是转义符;数据格式说明符形式:%输出宽度格式字符-常用格式d/c/s/f/lf“输出参数列表”表示要输出的数据,其个数与类型必须与格式说明符依次对应。,有定义:CString s;则:s.Format(a1=%d,a2=%5.2f,a3=%s,123,12.3,abc);couts;输出:a1=123,a2=12.30,a3=abc,uangXi University,42,4.3字符串,例4.补5 利用Format函数显示10o180o之间每隔10o对应的弧度、sin、cos、平方根和e指数的函数值。要求:除第一项是角度占3位整数外,其余各项宽度为10、小数占5位。,#include iostream.h“#include math.h#include afx.hvoid main()CString s,sl(-,55);int i;float x;cout 数学函数表endl;coutslendl;/显示55个-字符 couti x sin(x)cos(x)sqr(i)exp(x)endl;for(i=10;i=180;i=i+10)x=i*3.14259/180;s.Format(%3d%10.5lf%10.5lf%10.5lf%10.5lf%10.5lfn,i,x,sin(x),cos(x),sqrt(x),exp(x);couts;,uangXi University,43,4.3字符串,例4.补6 使用CString 类对象数组存放若干个字符串,采用选择法排序,实现对字符串数组的排序。,#include iostream.h#include afx.h void main()CString s4=Fortran,C/c+,Pascal,Visual Basic,t;int i,j,m;for(i=0;i3;i+)/选择法排序 m=i;for(j=i+1;j4;j+)if(sjsm)m=j;t=si;si=sm;sm=t;for(i=0;i4;i+)couti siendl;,C/c+,Fortran,Pascal,Visual Basic,uangXi University,44,4.4指针与数组,4.4.1 指针和一维数组4.4.2 指针和二维数组4.4.3 指针和字符串4.4.4 指针的补充说明,指针可以指向基本数据类型变量(第二章),也可以指向数组或数组元素。实际上数组名就是起始地址。,uangXi University,45,4.4指针与数组,4.4.1 指针和一维数组 设有定义:int a6=10,20,30,40,50,60,*p=a;下面是引用数组元素的三种方式。1.下标方式形式:数组名下标 2.地址方式 形式:*(地址常量)3.指针方式 形式:*指针变量名,假设有定义float a10,*p=a;则如下在值上的关系成立:(1)p a&a0(2)p+i&ai(3)*(p+i)*(a+i)ai 指针可以作数组名用 即:piai,uangXi University,46,4.4指针与数组,例4.9(1)四种方式输入数据设有:int a10;p=a;for(i=0;iai;则等价于:,p=a;for(i=0;i*p+;,p=a;for(i=0;i*p;,p=a;for(i=0;i*(p+i);/cinpi,思考:第三种方法与其它二种区别何在?,P指针变量的值不变,uangXi University,47,4.4指针与数组,例4.9(2)分别用三种方式访问并显示数组中的所有元素。#include“iostream.h”void main()int a6=10,20,30,40,50,60,*p=a,i;cout“n下标方式:”;for(i=0;i6;i+)coutai“”;/coutflush;cout“n地址方式:”;for(i=0;i6;i+)cout*(a+i)“”;cout“n指针方式:”;for(i=0;i6;i+)cout*(p+i)“”;coutendl;,思考:按(1)的思路,还可以写成什么形式?,uangXi University,48,4.4指针与数组,分析下列程序,思考:数组元素能否正确输出?,#include void main()int a10,i,*p;p=a;for(i=0;i*p+;for(i=0;i10;i+,p+)cout*p;,否,uangXi University,49,4.4指针与数组,说明:(1)三种引用方式比较,(2)p与a的区别:p是地址变量,而a是地址常量。,p+、p-、p=p+2 a+、a=a+2,uangXi University,50,4.4指针与数组,(3)*p+与(*p)+区别:*p+的+运算符作用于指针变量;(*p)+的+运算符作用于指针变量所指对象。,cout*p+;/输出?cout*p;/输出?,cout(*p)+;/输出?cout*p;/输出?,The fisrt:,The Second:,30,40,30,31,设有定义:int a6=10,20,30,40,50,60,*p=a+2;分别执行下面两段代码,思考每行代码的输出:,uangXi University,51,4.4指针与数组,4.4.2 指针和二维数组(若干个一维数组组成)定义二维数组:int anm;则a 代表二维数组的首地址,第0行的地址a+i 代表第i行的地址*(a+i)即 ai 代表第i行第0列的地址*(a+i)+j 即 ai+j 代表第i行第j列的地址*(*(a+i)+j)即 aij 代表第i行第j列的元素,元素aij的地址的几种等价的引用方式&aij ai+j*(a+i)+j&(*(a+i)j元素aij的几种等价的引用方式aij*(ai+j)*(*(a+i)+j)(*(a+i)j,uangXi University,52,4.4指针与数组,如设有定义:int a23;,数组名a可以解释为指向int类型的二级指针常量;a可以看成是由两个元素a0、a1构成的一维数组。a0可以看成是由a00、a01、a02 3个整型变量组成的一维数组,可将a0解释为指向int类型的一级指针常量;a1具有a0相同的性质。指针方式引用二维数组元素的两种方式:指针变量引用数组元素、指针数组元素引用数组元素。,uangXi University,53,4.4指针与数组,(1)指针变量引用数组元素,a.采用列指针(一级指针)设有定义:int a23,*p=a0;/或用p=*a初始化通过p指针显示二维数组的各元素:,for(i=0;i6;p+,i+)cout*p;if(i%3=0)coutendl;,注意:在C+中二级指针地址不能赋值给一级指针变量:如:int a23,*p=a;在标准C中是允许的,但在C+中就不允许。,p+1,uangXi University,54,4.4指针与数组,b.采用行指针(二级指针)-数组指针设有定义:int a23,(*p)3=a;/或p=a初始化;通过p指针显示二维数组的各元素:,p+1,for(int i=0;i2;i+)for(int j=0;j3;j+)cout(*p)j;p+;coutendl;,p等效于二维数组名a,但没有指出其边界,即第一维的元素数量,但是它的较低维数的元素数量必须要指定。,for(int i=0;i2;i+)for(int j=0;j3;j+)cout*(*p)+j);p+;coutendl;,uangXi University,55,4.4指针与数组,(2)指针数组引用数组元素 指针数组的形式:,数据类型*标识符整型常量表达式;,即:数组中每个元素是指针。,设有定义:int a23,*p2=a0,a1;,要引用aij元素,可用指针数组表示如下:*(pi+j)或*(*(p+i)+j),注意:指针数组名p与二维数组名a都是二级指针的概念,区别在于:,ai是地址常量,pi是地址变量。,uangXi University,56,4.4指针与数组,例4.10 数组指针与指针数组示例,#include iostream.hvoid main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int i,j;/列指针示例int*p=a0;for(i=0;i12;p+,i+)cout*p;if(i+1)%4=0)coutendl;coutendl;/数组指针(二级指针-行指针)示例int(*p0)4=a;/的优先级高于*,p0是一个指针变量/第一种方式输出for(i=0;i12;i+)cout(*p0)i;if(i+1)%4=0)coutendl;coutendl;,/第二种方式输出for(i=0;i3;i+)for(j=0;j4;j+)cout*(*p0)+j);p0+;coutendl;coutendl;/第三种方式输出p0=a;/重新指向afor(i=0;i3;i+)for(j=0;j4;j+)cout(*p0)j;p0+;coutendl;coutendl;/第四种方式输出p0=a;/重新指向afor(i=0;i3;i+)for(j=0;j4;j+)coutp0ij;coutendl;coutendl;,/指针数组示例/对一维数组int c4=1,2,3,4;int*p14=,uangXi University,57,4.4指针与数组,4.4.3 指针和字符串,(1)可通过字符指针来访问字符数组,二者的区别:,uangXi University,58,4.4指针与数组,例4.11输入一串字符存储在字符数组中,用指针方式逐一显示字符,并求其长度。,#include iostream.h#include stdio.hvoid main()char s80,*p;gets(s);p=s;/p指向数组的第一个元素 cout输出每个字符:;while(*p!=0)cout*p+;/指针下移,直到p指向字符串结束符 coutn 字符串长度:p-sendl;,uangXi University,59,4.4指针与数组,(2)字符指针数组,常用于处理若干字符串。设有定义:char*book=Fortran,C/c+,Pascal,Visual Basic;,按字符串的实际长度存储,以0表示每个字符串的结束。采用交换指针值的方法改变指针的指向。,即:数组book中每个元素是指向字符串的指针。,uangXi University,60,4.4指针与数组,例4.12 对4个字符串,按字典顺序将它们排序输出。,#include iostream.h#include string.hvoid main()char*book=Fortran,C/c+,Pascal,Basic,*p;int i,j,k;for(i=0;i0)k=j;if(i!=k)p=booki;booki=bookk;bookk=p;for(i=0;i4;i+)coutbookiendl;,注意元素的比较,uangXi University,61,4.4指针与数组,4.4.4指针的补充说明 指针学习不好关键是概念不清造成的,说的简单点就是书没有认真看,指针的学习犹如人在学习饶口令不多看多学多练是不行的。学习原则一定要学会其实通常的应用很简单,与使用变量几乎无异仔细琢磨 使用原则永远要清楚每个指针指向了哪里永远要清楚指针指向的位置是什么我们还是给几个例子来说明。,uangXi University,62,4.4指针与数组,例:用变量a给出下面的定义一个整型数一个指向整型数的指针一个指向指针的指针,它指向的指针是指向一个整型数一个有10个整型数的数组一个有10个指针的数组,该指针是指向一个整型数的一个指向有10个整型数数组的指针,a)int a;,b)int*a;,c)int*a;,d)int a10;,e)int*a10;,f)int(*a)10;,uangXi University,63,4.4指针与数组,例:分析下面程序的功能#include main()inta,b;int*point_1,*point_2,*temp_point;scanf(%d,%d,此题并没有改变变量a,b的值,利用指针变量分别存储a和b的地址,然后若ab,把那两个指针变量的值对换一下,再利用*point_1和*point_2的方式把调换后的值显示出来。利用指针进行地址交换达到大小排序的目的.,uangXi University,64,4.5动态数组,在 和中均定义了下面的函数void*malloc(unsigned int size);向系统申请大小为size的内存块,把首地址返回。如果申请不成功,返回NULLvoid*calloc(unsigned int num,unsigned int size);向系统申请num个size大小的内存块,把首地址返回。如果申请不成功,返回NULLvoid free(void*p);释放由malloc()和calloc()申请的内存块。p是指向此块的指针,uangXi University,65,4.5动态数组,一维动态数组#include main()int*p=NULL,n,i,sum;printf(Please enter array size:);scanf(%d,uangXi University,66,4.5动态数组,二维动态数组#include main()int*pScore=NULL,i,j,m,n,maxScore,row,col;printf(Please enter array size m,n:);scanf(%d,%d,uangXi University,67,4.6应用举例,插入数据基本思想:1)首先要查找待插入数据在数组中的位置k;2)然后从最后一个元素开始往前直到下标为k的元素依次往后移动一个位置;3)第k个元素的位置空出,将欲插入的数据插入。,例4.13 在有序数组a中插入数值x,for(k=0;k=k;i-)ai+1=ai;/从最后元素开始往后移,腾出位置 ak=x;,uangXi University,68,4.5应用举例,删除操作首先也是要找到欲删除的元素的位置k;然后从k+1到n个位置开始向前移动;最后将数组元素减1。,例4.14 从数组中删除某数。,