C语言数组课件讲.ppt

上传人:牧羊曲112 文档编号:5426339 上传时间:2023-07-05 格式:PPT 页数:87 大小:913.50KB
返回 下载 相关 举报
C语言数组课件讲.ppt_第1页
第1页 / 共87页
C语言数组课件讲.ppt_第2页
第2页 / 共87页
C语言数组课件讲.ppt_第3页
第3页 / 共87页
C语言数组课件讲.ppt_第4页
第4页 / 共87页
C语言数组课件讲.ppt_第5页
第5页 / 共87页
点击查看更多>>
资源描述

《C语言数组课件讲.ppt》由会员分享,可在线阅读,更多相关《C语言数组课件讲.ppt(87页珍藏版)》请在三一办公上搜索。

1、/17,例 求一个班100个学生的平均成绩,然后统计高于平均分的人数。使用简单变量和循环结构相结合的方法求平均成绩:aver=0;for(i=1;i=100;i+)scanf(“f”,,/17,若要统计高于平均分的人数,则无法实现。mark是一个简单变量,存放的是最后一个学生的成绩。,用已有知识解决方法:1.再重复输入成绩,带来两个问题:(1)输入数据的工作量成倍增加;(2)若本次输入的成绩与上次不同,则统计的结果不正确。,2.使用100个变量mark1,mark2,mark99,mark100。,/17,分析:1.此100个变量均为学生成绩,表示同一类对象。2.数据类型相同。3.可以用序号区

2、分不同的变量。,解决此问题的根本方法,引入数组,始终保持输入的数据,一次输入,多次使用。,除了int、float、char等基本数据类型外,C语言还提供了构造数据类型,来满足不同应用的需要。构造数据类型是由基本数据类型按一定规则组成的,也称作“导出类型”。构造数据类型包括数组、结构体、共用体。数组(array)能将具有相同类型的数据组合在一起,通常是用于处理批量数据。An array is a data type that uses subscripted variables and makes possible the representation of a large number of

3、homogeneous values.,第4章 数组和指针,数组的维数,数组中能唯一确定数组元素的下标的个数称为数组的维数一维数组:只用一个下标就能区分数组中的不同元素的二维数组:要用两个下标才能区分数组中的不同元素,16 一维数组 34 二维数组 234 三维数组 int a6;int b34;int c234;,/17,4.1 一维数组一维数组的定义与初始化,1.一维数组定义 类型定义符 数组名整型常量表达式;【例如】int a6;,数组名表示内存首地址,是地址常量,编译时系统分配连续内存内存字节数=数组维数*sizeof(元素数据类型),数组a在内存占24字节(6*4字节),A one-

4、dimensional array declaration is a type followed by an identifier with a bracketed constant integral expression.The value of the expression,which must be positive,is the size of the array.It specifies the number of elements in the array.The array subscripts can range from 0 to size-1.The lower bound

5、 of the array subscripts is 0 and the upper bound is size-1.,/17,一维数组的定义与初始化,【例如】float score50;char name20;注意:不能用变量定义数组的长度。float scoren;当定义数组语句中不同时给变量赋值时,方括号内不得为空。int a;数组一旦定义,数组的大小就不能再改变。常用的办法是用符号常量来指定元素个数。#define size 50 float scoresize;,/17,4.1.1 一维数组的定义与初始化,2.一维数组初始化类型定义符 数组名常量=值1,值2,值n;例如:int a

6、6=1,2,3,4,5,6;int a=1,2,3,4,5,6;两者等价于:a0=1;a1=2;a2=3;a3=4;a4=5;a5=6;例如:int a6=1,2;等价于:a0=1;a1=2;a2=0;a3=0;a4=0;a5=6;int c10=0;/将0赋给c0c9int a=1,2;/等价于:a0=1;a1=2;,/17,4.1.2 一维数组元素的引用与操作,1.数组元素的引用 数组名下标注意:(1)数组元素的下标从0开始(2)引用数组元素时,只能单个引用,不能一次引用整个数组 int a6;a=3,4,5,6,7;a6=3,4,5,6,7;(3)下标不要超出数组的范围,否则导致错误的程

7、序结果。,2.数组的赋值可以在定义数组时对数组中的全部变量或部分变量赋值(即数组的初始化)。可以在语句中为变量赋值。利用循环依次为每个数组元素赋值或输入值。,4.1.2 一维数组元素的引用与操作,main()int i,a5;for(i=0;i5;i+)ai=i;/用循环结构直接对数组赋初值 for(i=0;i5;i+)printf(%d,ai);printf(n);,运行结果为:0,1,2,3,4,用交互的循环结构对数组赋初值,main()int i,a5;for(i=0;i5;i+)printf(a%d=,i),scanf(%d,例:定义长度为10的整型类型一维数组并完成以下功能:从键盘输

8、入10个整数,分别存放在10个数组元素中;输出数组中的各元素值;按逆序输出数组中的各元素值。,main()int i,a10;for(i=0;i=0;i-)printf(%4d,ai);printf(n);,应用举例,下标越界:差一错误 off-by-one error,在C语言中,有N个元素的数组其元素下标的允许取值范围为0到N-1,不存在下标为N的元素。例如这段代码本意是要设置数组a中的10个元素均为0。但通常编译器按内存递减方式分配内存,使得内存中a9之后的4个字节分配给i。本来计数器i的值为10,循环体内将并不存在的a10设为0,实际是将i值设为0,就陷入死循环!,main()int

9、i,a10;for(i=1;i=10;i+)ai=0;printf(%d,ai);,4.1.3 数组应用1.比较法排序,由键盘输入10个数,按由小到大排序输出解题方法:将10个数存入数组a将a(0)与a(1)、a(2)a(9)依次比较,哪个元素的值比a(0)小,就将它与a(0)的值交换,这样就将最小的数送到了a(0)中。再将a(1)与a(2)、a(3)a(9)依次比较,哪个元素的值比a(1)小,就将它与a(1)的值交换,这样就将最小的数送到了a(1)中。重复以上步骤。对于n个数,比较排序法的总运行次数为:(n-1)+(n-2)+3+2+1=n*(n-1)/2.,/17,1.比较法排序,1.比较

10、法排序,#include main()int i,j,a10;srand(time(0);for(i=0;iaj)ai=aj=ai=aj;for(i=0;i10;i+)printf(%4d,ai);,/17,2.冒泡法排序,是一种交换类排序方法,它是通过相邻数据元素的交换逐步将线性表变成有序。首先将a0与a1、a1与a2、a2与a3、an-2与an-1相邻两个数进行比较,若为逆序(比如a0a1)则两者交换,这样就将将最大的数放在an-1中;再将a0、a1、an-2这n-1个数进行同样的相邻两数比较,若为逆序则两者交换,这样就将这n-1个数中最大的数被放在an-2中;重复以上步骤,经过n-1趟比

11、较交换完成冒泡法排序。,/17,用冒泡法排序将10个整数按从小到大的次序排列出来。,2.冒泡法排序,/17,#include#define N 10/数据的个数 main()int aN=5,12,29,47,9,18,13,50,38,2;int i,j,k,t;for(i=0;iaj+1)t=aj;aj=aj+1;aj+1=t;printf(n最后的排序结果:n);for(i=0;iN;i+)printf(%5d,ai);,2.冒泡法排序,数组应用II-插入,向一个有序数组中插入一个数字,插入后不改变原有顺序,插入数字前,插入数字后,/17,方法1:找到插入点后再移位。从前向后循环,从第1

12、个元素开始依次将数组元素与要插入的数x比较,当x=i;j-)aj+1=aj;ai=x;/插入数据后退出整个循环 break;,数组应用II-插入,/17,方法2:边找插入点边移位。从后向前循环,直接从最后1个元素开始,将其与要插入的数x比较,如果xx,因此x要赋值给ai+1。,/从最后1个元素开始,依次将要插入的数与每个元素比较for(i=8;i=0;i-)/如果要插入的数比元素值小,则该元素直接向后移位 if(xai)ai+1=ai;else break;/表示找到插入点,退出循环ai+1=x;/插入数据,数组应用II-插入,数组应用III:不改变顺序,删除指定的数字,main()int i

13、,j,del=0,int a10=1,2,3,4,5,6,7,8,9,10,x=5;for(i=0;i10;i+)printf(%4d,ai);putch(n);for(i=0;i10-del;i+)/删除后数组的容量减小一if(x=ai)for(j=i;j10;j+)aj=aj+1;i-;/还原到删除位置,以处理连续删除 del+;for(i=0;i10-del;i+)printf(%4d,ai);,删除前:1 2 3 4 5 5 7 8 9 10删除后:1 2 3 4 7 8 9 10,二分法检索(在序列x中检索y的位置)前提:有序数列(以递增序为例)原理:等分区间;若y小于中间数,则取左

14、半边,否则取右半边。再等分,再比较 例:对于区间a,b 等分为若 y=xk 则位置为k若yxk 则取新区间 k+1,b(即a=k+1),数组应用IV二分查找(检索),二分法查找递增序列,main()int x10=34,56,78,87,88,90,101,112,520,888;int y,i,k,a=0,b=9;for(i=0;ib)printf(ERROR);else printf(nx%d=%dn,k,xk);getch();,/17,4.2 二维数组 二维数组的定义和初始化,1.定义需要两个下标才能标识数组中某个元素的位置,也称为矩阵。Use a two-dimensional ar

15、ray if two other identifiers are needed to determine the value of interest.定义格式为:类型定义符 数组名常量表达式1 常量表达式2,列数,行数,int a23;,逻辑结构,存储结构,/17,二维数组的定义和初始化,2.二维数组的初始化和引用两种初始化方式:按行初始化:每一对花括号对应一行的元素。按存放顺序初始化:按内存中的存放顺序将初始值分别赋值给对应的元素。,int a23=1,2,3,4,5,6;int a23=1,2,3,4,5,6;int a3=1,2,3,4,5,6;,/17,二维数组的定义和初始化,int

16、d34=1,2,3,4,5,6;int d4=1,2,3,4,5,6;int d34=1,0,0,0,2,3,0,0,4,5,6;int d4=1,0,0,0,2,3,0,0,4,5,6;,int e34=0,0,0,1,0,0,2,3,0,4,5,6;int e4=0,0,0,1,0,0,2,3,0,4,5,6;int e34=0,0,0,1,0,0,2,3,0,4,5,6;,/17,二维数组的定义和初始化,3.二维数组在内存中的存放M行N列的二维数组a,aij 的位置公式为:i*N+j+1数组元素aij存储映射关系为:aija0N*i+j,Real computer memory has

17、only one dimension,i.e.each location is identified with only one component of address.因此,二维数组元素可用它相对数组首元素00位置的偏移量来表示(称为存储映射关系storage mapping)。对二维数组元素的操作除了用二重循环外,还可以用一重循环实现。In C,or any other language supporting arrays with dimension sizes greater than one,two-dimensional arrays simulate the effect of

18、 using two components of address.To do this,the array is mapped into consecutive memory with row 0s values first,then row ones values,etc.You can think of this as a set of one dimensional arrays holding the column values as a single value in the rows values.,/17,二维数组元素的引用,对二维数组int a34中各元素的输出操作for(i=

19、0;i3;i+)for(j=0;j4;j+)printf(%4d,aij);for(i=0;i3;i+)for(j=0;j4;j+)/用相对a00位置的偏移量来表示 printf(%4d,a04*i+j);for(i=0;i12;i+)/用相对a00位置的偏移量 printf(%4d,a0i);,求矩阵 特征值之和,#define N 3main()int i,j,s=0,aNN=1,1,1,2,1,1,2,2,1;/显示矩阵 a33printf(对于矩阵 a%d%dn,N,N);for(i=0;iN;i+)for(j=0;jN;j+)printf(%4d,aij);putch(n);/主对角

20、线元素之和for(i=0;iN;i+)s+=aii;printf(n主对角线元素之和 s=%dnn,s);,二维数组的应用举例矩阵,/副对角线元素之和s=0;for(i=0;iN;i+)s+=aiN-1-i;printf(副对角线元素之和 s=%dnn,s);/上元素之和s=0;for(i=0;iN;i+)for(j=i;jN;j+)s+=aij;printf(“上元素之和 s=%dnn,s);,二维数组的应用举例矩阵(续1),/下元素之和s=0;for(i=0;iN;i+)for(j=0;j=i;j+)s+=aij;printf(下元素之和 s=%dnn,s);/周边元素之和s=0;for(

21、i=0;iN;i+)for(j=0;jN;j+)if(i=0|i=N-1|j=0|j=N-1)s+=aij;printf(周边元素之和 s=%dnn,s);getch();,二维数组的应用举例矩阵(续2),Tips:对于int型一维数组a和二维数组b用 sizeof(a)/sizeof(int)得到数组a的大小;用 sizeof(b)/sizeof(b0)二维数组b的行数 sizeof(b0)/sizeof(int)二维数组b的列数,【例】显示二维数组b的各元素#include main()int b4=0,1,0,0,1,0,0,0,2,6,4,i,j;for(i=0;isizeof(b)/

22、sizeof(b0);i+)for(j=0;jsizeof(b0)/sizeof(int);j+)printf(%5d,bij);printf(n);,二维数组的应用举例sizeof的使用,main()int x43=1,2,3,2,3,4,3,4,5,0,0,1;int i,j,k,row=0,column=0,min,m=4,n=3;for(i=0;imax)max=xij,row=i,column=j;for(k=0;k-1,应用举例:求二维数组的鞍点saddle point,即该位置上的元素是该行上的最大值,是该列上的最小值。鞍点可能不存在,main()int a53=1,2,3,2,

23、3,4,3,4,5,4,5,6,5,6,7;int i,j,max5,min3;/先把每行第1个数当最大值每列第1个数当最小值 for(i=0;imaxi)maxi=aij;if(aijminj)minj=aij;/如最大值最小值是同1个数,找到鞍点for(i=0;i5;i+)for(j=0;j3;j+)if(maxi=minj)printf(a%d%d=%d是鞍点n,i,j,aij);,寻找鞍点方法二:直接找出所有行的最大值所有列的最小值。一比对,若该行的最大值与该列的最小值相等,该位置的数就是鞍点。,4.2.3 多维数组,当需要用多个下标来确定数组元素时,数组称为多维数组。There is

24、 no limit in the language as to the number of dimensions that an array may be given.Each dimension requires a size specifier within a pair of brackets.1.多维数组的定义类型 数组名常量表达式1常量表达式2常量表达式n;【例如】定义一个整型三维数组:int b234;,以下标 0、1为变量 i,下标0、1、2为变量j,下标0、1、2、3为变量k,就可以用三重循环结构对数组的每一个元素进行处理了。,多维数组初始化,对于三维数组,可将其看作多个二维表

25、格,即可以把它看成是由多个二维数组构成的。依此类推,一个n维数组可以看成是由多个n-1维数组构成的。前面数组b有24个元素,它们在内存中排列顺序跟二维数组类似:先变化第三个下标,然后变化第二个下标,最后变化第一个下标。【例如】以三维数组初始化为例:int b234=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24;由第一维为2,可认为b数组由两个二维数组组成,每个二维数组为3行4列。初始化时,对每个二维数组以按行初始化的方法,分别用花括号把各行元素值括起来,并且将三行的初值再用花括号括起来。,多维数组的一维表示,多维数

26、组元素也可用它相对数组首元素位置的偏移量来表示。三维数组 bLMN的数组元素bijk的存储映射关系为:bijk b00M*N*i+N*j+kExample:int b234;causes the compiler to reserve space for 2 arrays of 3 arrays of 4 integers in contiguous memory.Thus 24 contiguous integers are reserved.A storage mapping function is used to translate an array reference into a p

27、ointer reference.In this case,the storage mapping function maps:bijk*(b000+3*4*i+4*j+k),4.3 字符型数组,在C语言中,存储字符串必须使用类型为char的字符型数组。字符型数组的每个数组元素存放一个字符的ASCII码。字符串的结束标志是 0。在存储一个字符串时,系统自动在其末尾添加一个结束标志 0(数字0)。0 不包括在字符串长度内。The string in C programming language is actually a one-dimensional array of characters w

28、hich is terminated by a null character 0.例如,对于定义的字符数组 char a10=Hello;,通常,一个字符串用一维字符型数组来存放,多个字符串用二维字符型数组来存放。如果要将三个字符串置于字符数组s中 How are you Good morning Good bye 可定义为:char s313;,4.3 字符型数组,4.3.1 字符数组的初始化,char a=abcde;char c5=Boy,Girl;以下赋值语句也是合法的:char a6=abcde;char a6=abcde;char a6=a,b,c,d,e;char a=a,b,c

29、,d,e,0;char c25=Boy,Girl;char c5=Boy,Girl;char c25=Boy,Girl;,注意,(1)字符数组的长度应该大于实际存储的字符串长度。否则按语法错误处理。(2)使用字符常量初始化时,如果字符末尾没有0,则字符数组不能按字符串处理,只能对字符逐个进行处理。比如,数组a用单个字符来初始化,char a5=a,b,c,d,e;最后一个元素不是0,它就不是字符串,就不能用字符串方法(如gets()、puts()、scanf()或printf()中%s格式)来操作。(3)一维字符数组在初始化时,可以省略其长度,默认长度为初始化字符串的长度加1。如果没有初始化赋

30、值,则必须说明数组的长度。(4)单引号是字符常量定界符,双引号是字符串常量定界符。(5)不能使用赋值语句将一个字符串常量或字符数组直接赋给一个字符数组。char a5;a=abcde;/是错误的。,4.3.1 字符数组的初始化,字符数组的输入从键盘输入的三种方法,1、用gets函数输入整个字符串 能输入含空格字串并把回车转成02、在scanf函数中用格式符%s 输入整个字串 只能输入不含空格符的字符串 char a10;scanf(%s,a);3、在scanf函数中用格式符%c逐个输入字符 char a12;int i;for(i=0;i12;i+)scanf(%c,对于二维字符数组,可看成若

31、干个一维字符数组(每个一维字符数组是一个字符串),使用时用二维字符数组行下标来表示二维字符数组中各个字符串的首地址。main()char s313;int i;for(i=0;i3;i+)gets(si);for(i=0;i3;i+)printf(%s,si);执行时输入:How are you Good morning Good bye 程序中的si 是一维数组名,它是一个地址常量。,二维字符数组的输入,字符数组的输出从屏幕输出的三种方法,1、puts函数输出整个字符串 这种输出方式遇到0就自动换行2、printf函数格式符%s输出整个数组 遇到遇到0不换行 3、printf函数格式符%c逐

32、个输出数组元素,char s12=How are you;int i;for(i=0;i13;i+)printf(%c,si);,例:输入0-99数字,显示读法(由于汉字为双字节码,所以不能用一维数组,要用二维数组。)main()int x,i,j,k;char a113=零,壹,贰,叁,肆,伍,陆,柒,捌,玖,拾;scanf(%d,字符数组的应用举例,4.3.4 字符串函数,在C语言中,由于字符串的处理通常要用字符数组,而字符数组名是地址常量不是变量(不能出现在赋值号的左边),所以对字符串的连接、复制、比较等操作就比较麻烦。C语言提供了一些专门用于字符串处理的函数,以方便用户的使用。C su

33、pports a wide range of functions that manipulate null-terminated strings,such as strlen(),strcat(),strcpy(),strcmp(),strlow()and strupr().,常用的字符串处理函数,1、测字串长度函数 string length strlen()2、字串连接函数 string cast strcat()3、字串复制函数 string copy strcpy()strncpy()4、字串比较函数 string compare strcmp()5、小写转换函数 string low

34、er strlwr()6、大写转换函数 string upper strupr()因为字符串处理函数不是C语言的组成部分而是系统提供的公共函数,因此调用字符串处理函数前,通常要加预编译命令:#include,strlen(字符数组)测试字符串长度,不包含“0”在内。例如:#include main()char s=How do you do;int c;c=strlen(s);printf(%dn,c);运行结果是:13,改为 s30=How do you do0 运行结果也是13,常用的字符串处理函数-求字符串长度,例:显示一个字串中的大写字母main()char c,s30,i;print

35、f(输入一个字串:);gets(s);for(i=0;i=A,常用的字符串处理函数-求字符串长度函数举例,例:指针表示法显示一个字串中的大写字母main()char c,s30,*p;printf(输入一个字串:);gets(s);for(p=s;p-s=A,连接两个字符数组中的字符串:把字符数组2接在字符数组1的后面,放到字符数组1中,并得到一个函数值,该函数值是字符数组的起始地址。注1:字符数组1必须足够大;注2:字符数组2也可以是一个字符串常量。,常用的字符串处理函数-字符串连接,strcat(字符数组1,字符数组2),例如#include main()char c30=abcden,s

36、20=How do you do;strcat(c,s);/将S接在C的后边/printf(%sn,c);运行结果是:abcde How do you do,strcat(c,How do you do);printf(%sn,c);,常用的字符串处理函数-字符串连接举例,常用的字符串处理函数-字符串拷贝,将字符数组2拷贝到字符数组1中。复制后的结果放在字符数组中,字符数组不变。函数值是字符数组1的地址。字符数组1必须写成数组名形式,如s。字符数组2可以是字符数组名,也可以是一个字符串常量。说明:(1)字符数组1定义时其长度要大于等于字符数组2的长度。(2)复制时连同字串中的0一起被复制到字串

37、中。(3)若字符数组中原存有字符,则原有字符不再存在。字串间的赋值不能用 a=b;只能用 strcpy(a,b),strcpy(字符数组1,字符数组2),strncpy(字符数组1,字符数组2,n)将字符数组2的前n个字符拷贝到字符数组1中。复制后的结果放在字符数组中,字符数组不变。函数值是字符数组1的地址。例如:main()char a=hello world!;strncpy(a,HELLO WORLD!,2);puts(a);getch();显示:HEllo world!,常用的字符串处理函数-字符串拷贝,strcmp(字符串1,字符串2)如果两个字符串一样大,函数值为0;如果字符串1大

38、,函数值为一正整数;如果字符串2大,函数值为负整数。对于字符数组a和b而言:strcmp(a,b)=0 a、b两字串相等strcmp(a,b)0 a字串b字串strcmp(a,b)0 a字串b字串(字符串比大小,按ASCII码比较,先比第1个字符。),常用的字符串处理函数-字符串比较,#includemain()char c7=abcdef,s4=abc,t=acb;int a,b;a=strcmp(c,s);b=strcmp(c,s);printf(%dn%d,a,b);,常用的字符串处理函数-字符串比较举例,在TC2.0中的运行结果:100-1,在VC+中的运行结果:1-1,数据比较时应注

39、意,判断两个字符串是否相等时:不能使用 if(a=b)应使用 if(strcmp(a,b)=0)相等比较的总结,例如main()int i=0;char a=abcd,b=abcd;if(a=b)printf(Yes);else printf(No);结果居然是No,将if语句改为:if(strcmp(a,b)=0)后,结果就为Yes。,字符串比较时应注意,strlwr(字符串)将字符串中的大写字母转换成小写字母strupr(字符串)将字符串中的小写字母转换成大写字母,例:大小写转换函数应用main()char s100;gets(s);strupr(s);puts(s);strlwr(s);

40、puts(s);,常用的字符串处理函数-字母大小 写转换,#include main()char a=wang,b=1234,user100,psw100;dosystem(cls);printf(请输入用户名);gets(user);strlwr(user);printf(请输入密码);gets(psw);while(strcmp(a,user)!=0|strcmp(b,psw)!=0);printf(n欢迎您:%s,user);,字符串应用举例:用户名和密码的验证 I,#include main()char a=wang,b=1234,user100,psw100;int i;dosyst

41、em(cls);printf(请输入用户名);gets(user);strlwr(user);printf(请输入密码);i=-1;doi+;pswi=getch();putch(*);while(pswi!=13);pswi=0;while(strcmp(a,user)!=0|strcmp(b,psw)!=0);printf(n欢迎您:%s,user);,字符串应用举例:用户名和密码的验证 II,#include main()char a1020=广州,武汉,上海,北京,成都,太原,郑州,南京,石家庄,天津,t20;int i,j;for(i=0;i0)strcpy(t,ai),strcpy

42、(ai,aj),strcpy(aj,t);for(i=0;i10;i+)printf(%st,ai);,字符串应用举例:字符串的排序,4.4 指针和数组,指针的应用与数组是密不可分的。数组a的指针是指数组a的起始地址,即&a0,数组元素的指针就是该数组元素的地址。,int a6;int*p=a;,实际上,下标表达式ai就是按照指针表达式*(a+i)定义的。,指向数组的指针变量的赋值方法,方法1:在定义指针变量时赋值。int a10,*p=a;方法2:在定义指针变量后赋值。int a10,*p;p=a;结果:p是数组a的指针,指向a 数组的第一个元素a0的首地址 main()int i,a6=0

43、,1,2,3,4,5,*p;p=a;for(i=0;i6;i+)printf(%d,ai);,可替换为*(a+i)或*(p+i),在程序中使用指针变量时应当注意,指针的变化+-使指针按它所指向的类型所规定的字节数在内存区中移动(跳动而不是滑动)。指针变量的运算+和*是同优先级,从右至左的结合方向。*p+和*(p+)等价*+p和*(+p)等价(*p)+表示p所指向的元素值加1。,通过指针的算术运算引用数组元素,指向数组的指针可以指向数组中的其它元素。main()int a10=2,4,5,8;int*p=a;/p指向a0 printf(“%4d”,*p+);/输出a0,p指向a1 printf(

44、“%4d”,*p+);/输出a1,p指向a2 printf(“%4d”,*p+);/输出a2,p指向a3 printf(“%4d”,*p+);/输出a3,p指向a4 运行结果是:2 4 5 8,用*p+遍历整个数组,main()int a=9,8,7,6,5,4,3,2,1,0,*p=a,i;for(i=0;isizeof(a)/sizeof(int);i+)printf(%d,*p+);getch();注意:这种方法造成了指针p的移动。,同样,可以用p+和地址偏移量遍历整个数组main()int a10=9,8,7,6,5,4,3,2,1,0,*p;for(p=a;p-a10;p+)prin

45、tf(“%d,*p);,运行结果:9,8,7,6,5,4,3,2,1,其中p中存放的是地址,p-a10表示p单元中的值减去数组a的首地址所得的单元数不超过10。注意:这种方法也造成了指针p的移动,用p+与地址偏移量遍历整个数组,通过带下标的指针变量引用数组元素,指向数组的指针变量也可以带下标定义了:int a10,*p=a;后:可以使用 ai或pi或*(a+i)或*(p+i)这4种方法引用a数组中的第i个元素。注意:这些方法都不造成指针p的移动。,输出数组元素四种方法,main()int a10=10,9,8,7,6,5,4,3,2,1,*p,i;p=a;for(i=0;i10;i+)prin

46、tf(%d,ai);putch(n);for(i=0;i10;i+)printf(%d,pi);putch(n);for(i=0;i10;i+)printf(%d,*(a+i);putch(n);for(i=0;i10;i+)printf(%d,*(p+i);,利用指针变量对数组元素赋值,通过指针变量p实现数组元素的赋值:int a5,*p=a,i;for(i=0;i5;i+)printf(a%d=,i);scanf(%d,可替换成&pi或 a+i或 p+i或 p+,利用p+和地址偏移量p-a实现数组元素的赋值for(p=a;p-a5;p+)printf(a%d=,p-a);scanf(%d,

47、p);,总结:数组遍历的6种方法,造成指针p的移动的2种方法(p必须初始化)*p+p+配合*p不造成指针p的移动的4种方法*(p+i)pi*(a+i)ai 数组在C语言中是个二等公民:不能作为整体操作数组。但将指针变量指向一个数组后,就可以用对指针变量的操作去整体操作一个数组了。,在程序中使用指针变量时应当注意,常见的指针变量运算*(+p)先移指针,取出下一个单元的值。*(p+)先取出当前单元的值,再移指针。(*p)+先取出当前单元值,再使当前单元加1。不移指针。+(*p)先使前单元的值加1,再取出。不移指针。注意:*p+和*(p+)是等价的。数组和指针的统一性是C语言的长处之一。用指针可以很

48、方便地访问数组和模拟动态分配的数组。但是,说数组和指针等价并不表示它们相同,甚至也不能互换。“等价”的意思是:指针算术和数组下标运算等价,指针和数组是不同的。(Wayne Throop),遍历数组时指针的移动,在用指针变量遍历数组时,要特别注意指针是否移动。main()int*p,i,x10=10,9,8,7,6,5,4,3,2,1;p=x;for(i=0;i10;i+)printf(%d,*p+);printf(n);for(i=0;i10;i+)printf(%d,*p+);运行时并没有显示二行相同的 9,8,7,6,5,4,3,2,1,0,输出值发生错误,为什么?实际上,把*p+换成*(

49、p+i),也可以避免出错。为什么?,第一个循环后p已经指向数组x的末尾。在第二个for循环开始后,发生错误,应该将在第二个for循环语句前加一句:p=x;,用指针实现比较法排序,#include main()int i,j,a10,*p=a;srand(time(0);for(i=0;i*(p+j)*(p+i)=*(p+j)=*(p+i)=*(p+j);for(p=a;p-a10;p+)printf(%4d,*p);getch();,在C语言中有两种方法用指针变量表示一个字符串:,在右例中:字符指针p只存放地址,而字串内容放在内存中另一地方,字串可被再次赋值:p=“hello world”;这

50、种做法称为:p指向了一个无名的字符数组。,字符串和指针,直接使用字符指针表示字串时,可以输出和被赋值,但不可用gets()函数输入一个新的字串。下面这个程序会出现运行时错(Run error):main()char*p;p=HELLO WORLD;puts(p);p=Hello world;puts(p);gets(p);/无名字符数组不能用于gets()函数puts(p);,字符串和指针,通常做法是:定义一个字符型指针并将它指向一个字符型数组,然后用对指针的操作代替对数组和数组元素的操作。,main()char a100,*p=a;int i;printf(输入一个字串:);gets(p);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号