版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第4章章 指针与数组指针与数组第一节第一节 一维数组一维数组第二节第二节 二维数组二维数组第三节第三节 字符数组与字符串字符数组与字符串第四节第四节 指针数组指针数组指针小结指针小结c语言程序设计语言程序设计 龙昭华主编1 /113课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)2 /113 迄今为止,我们使用的都是属于基本类型,如:整型、字符型、实型等类型的数据。而c还提供了构造类型,如:数组类型、结构体类型、公用体类型等。构造类型数据是由基本类型数据按一定规则组成的,因此有些书称它们为“导出类型”。 在程序
2、设计中,常常需要处理大量同类型的相关数据,如每个学生的成绩记录,多个相同类型数据的排序等。这类数据在计算机语言中可以通过数组来表示。所谓数组数组就是具有相同数据类型的有序集合。 在c语言中,数组具有以下几个特点: 数组的所有元素使用一个共同的名字,称为数组名数组名,数组名使用标识符来表示。每个数组元素的使用由数组的下标来确定。 数组元素的个数必须在定义时确定,程序中不可改变。 在c语言中,数组下标是从0开始,到数组元素个数减1结束的。 同一数组中的每一元素具有相同的数据类型相同的数据类型(可以是基本类型或构造类型等)。 同一数组在内存中占据一段连续的存储单元连续的存储单元。 数组中元素的作用相
3、当于简单变量。 数组必须先定义后使用。课件制作:刘达明课件制作:刘达明、一、一维数组的定义和引用一维数组的定义和引用第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)3 /1131 1、一维数组的定义、一维数组的定义 一维数组是指只有一个下标的数组元素所组成的数组。一维数组的定义方式为: 类型说明符类型说明符 数组名数组名 常量表达式常量表达式 ; 例如:int a10; 它表示数组名为a,此数组有10个元素,分别为a0、a1、a2、a3、a4、a5、a6、a7、a8、a9。 又如:存放30个学生的数学成绩,用一维数组定义如下:int grad
4、e30; 其元素分别为:grade0,grade29共30个。课件制作:刘达明课件制作:刘达明维数组的定义说明一维数组的定义说明第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)4 /113 数组名数组名定名规则和变量名相同,遵循标识符标识符定名规则。它表示各数组元素的统一名字,用以唯一标识数组。 数组名后是用方括号方括号的常量表达式常量表达式,不能用圆括号代替。 如int a(20);是错误的。 常量表达式的值表示数组中所包含的元素的个数,即数组的长度。 如int a20;表示数组a有20个元素,分别为a0、a1、a19。 注意不能使用数组元
5、素a20。 常量表达式中可以包括常量常量和符号常量符号常量,不能包含变量。即在c语言中不允许对数组进行动态定义,数组的大小不会随着程序运行中的变化而改变。 错误定义:int n;scanf(“%d”,&n); float bn;。 正确定义:#define n 30 float bn; int i10;。 类型说明符表示数组元素具有的数据类型,可以是int、 short、long、char、unsigned、float、double等。 相同类型的数组可以在同一个类型说明符下一起说明,互相间用“,”隔开。如:int a4,b10,c20;。 注意:注意:数组必须先定义,后使用。课件制作
6、:刘达明课件制作:刘达明 023-668341102 2、一维数组的引用、一维数组的引用第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)5 /113 数组的具体使用对象是其中的数组元素。在一个数组定义好后,在内存中分配一组连续的存储空间。如:int a5; 存储方式见右图。 数组元素的引用格式为: 数组名数组名 下标下标 ; 这里的下标与数组定义时不同,不仅可以是整型常量或整型表达式,还可以是含有已赋值变量的整型表达式。数组的下标从0开始算起。 如:b0=b5+b7-b2*3。 又如:int i15; int n=3; i0=-10; i5=6; in*4=9;a0=1
7、内存用户数据区内存用户数据区a1=3a2=2592000200220042008a3=-1a4=-10200600000001000000001111011011111111000000110000000000000011000000011111111111111111课件制作:刘达明课件制作:刘达明维数组的引用说明一维数组的引用说明第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)6 /113 数组元素和普通基本型变量一样的使用,可出现在c语言表达式中的任何地方。 c语言规定只能逐个引用数组元素,而不能一次引用整个数组。 c语言不提供数组下标
8、越界的保护,设计时要注意。 如:int b5; 只能有效引用b0、b1、b2、b3、b4。 如果程序中出现b5 ,这时c的编译系统不会出错,但b5的值是 不确定的。课件制作:刘达明课件制作:刘达明 023-668341103 3、一维数组的初始化、一维数组的初始化第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)7 /113a0=1内存用户数据区内存用户数据区a1=3a2=2592000200220042008a3=-1a4=-1020060000000100000000111101101111111100000011000000000000001100000001111
9、1111111111111 数组在定义后,它所占有的存储单元中的值是不确定的,引用数组元素之前,必须保证数组的元素已经被赋以确定的值。 对数组元素的初始化可以用以下方法实现: 通过赋值语句或输入语句对数组中的元素赋值。 在数组定义时对数组中的元素赋值。对数组元素赋值的方法是从数组的第一个元素开始依次给出初始表,表中各值之间用逗号分开。一般格式为: static static = 如:int a5=1,3,259,-1,-10; static int b5=1,3,259,-1,-10; char word5=a,b,c,d,e;课件制作:刘达明课件制作:刘达明维数组
10、的初始化说明:一维数组的初始化说明:第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)8 /113 是用逗号分隔的数据。 若对数组中的所有元素都赋初值,可不必指出元素个数,即可以不指定数组长度。 如: int a=1,3,259,-1,-10; 也表示数组a有5个元素。它等价于: int a5=1,3,259,-1,-10; 也等价于 a0=1;a1=3;a2=259; a3=-1;a4=-10。 而没有给出数组长度的赋初值,即使后面每个元素的初值全是0,也要写出来。 如:int b=1,2,3,0,0,0; 认为是6个元素的数组,它等价于: int b6=1,2,3;。
11、 中数据的类型必须与所指定的数据类型一致。 在c语言中,数组元素的下标值依次为0、1、2、,在n个元素组成的一维数组中,最后一个元素的下标为n-1。课件制作:刘达明课件制作:刘达明维数组的初始化说明(续):一维数组的初始化说明(续):第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)9 /113 c语言规定对数组进行置初值时,如果是静态存储(static为关键字)数组和外部存储(extern)数组。在数组不赋初值时,系统会对所有数组元素自动赋以0值或0值。 如:static int a3; 等价于 static int a3=0,0,0; 。
12、如果只定义int a5;而不赋初值时,则各元素的值是不确定的。 对数组的全部元素都赋0为初值,可以写成:int a5=0,0,0,0,0; 而不能写成:int a5=0*5; 。 可以只给数组中的前面一部分元素赋初值,后面没有赋初值的元素系统自动赋以0值或0值。 如:int a5=1,2,3; 等价于:int a5=1,2,3,0,0; 也等价于:int a=1,2,3,0,0; 。课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)10 /113 1 1、指向基本数据类型变量的指针变量、指向基本数据类型变量的指针变
13、量二、二、指向指向一维数组的指针变量一维数组的指针变量3i变量名变量名变量值变量值存储单元存储单元变量变量i=3内存用户数据区内存用户数据区2000变量变量j=6变量变量k=9变量变量i_pointer200020022004301000001001000000000000001100000000000001100000000020002000i_pointeri30103间接访问:间接访问:2000i3直接访问:直接访问: int i,j,k,*i_pointer=&i; i=3; j=6; k=9;执行执行i_pointer+后,后, i_pointer已不再指向已不再指向i了,了
14、,而是指向了下一个而是指向了下一个j,但在这里这样用无意义。,但在这里这样用无意义。int i;给变量i分配2个字节的存储单元i=3; 在i的存储单元中的值为3。课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)11 /113200032000i_pointeri3010*i_pointer&b&bp2b* p2&a&ap1a* p1指向基本数据类型变量的指针变量指向基本数据类型变量的指针变量( (续续1)1)int i,*i_pointer;i_pointer=&i;若:i
15、=3;则:*i_pointer也为3。float a,*p1;p1=&a;char b,*p2;p2=&b;指针与指针变量通过指针与指针变量通过&建立联系:建立联系:int i,*pi,*pi1;pi=&i; /* 指针变量pi已指向变量i */pi1=pi; 这时*pi和*pi1都相当于变量i。即:*pi=3; 或*pi1=3; 等价于 i=3;char c,*pc;pc=&c; /* 指针变量pc已指向变量c */这时*pc相当于变量c。即:*pc=3; 等价于 c=3;float f,*pf;pf=&f; /* 指针变量pf已指向变量f *
16、/这时*pf相当于变量f。即:*pf=3.6; 等价于 f=3.6; 错误赋值:错误赋值:pf=1000; 但pf=null除外。间接运算符间接运算符*与取地址运算符与取地址运算符&同级,同级,且右结合且右结合。如:*&i=3; 等价于 i=3;或*(&i)=3; 又:int a,*p=&a; 则:&*p等价于&(*p)或&a都表示变量a的地址。而*&a则与*p等价,都表示变量a的内容。课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)12 /113指
17、针变量的运算:指针变量的运算: 指针变量是一个变量,因此可以进行某些运算。但指针的本质是一个地址,其运算具有一些特别的性质,不能用普通变量的规则运算来作为指针运算的方式。 指针指针变量加变量加( (减减) )一个整数的一个整数的算术运算算术运算:只有:加、减(+、-、+ +、- -)运算。 +、+ +代表指针前移,-、- -代表指针后移。指针变量每加(或减)1,就指向它指定的数据类型的下一个(或上一个)元素的位置。c c语言规定语言规定,一个指针变量加(减)一个整数并不是简单地将指针变量的原值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数相加(减)。
18、如:p+i(p是指针变量,i是整数),代表的地址计算:p+c*i(c为指针变量所指向的数据类型所占内存的字节数)。运算:p+、p-,+p,p-=i,p+=i,p=p+i,p=p-i等(这里i表示整型数据)。这些运算的结果仍为指针结果仍为指针。如: int a,b,c,d,*p; p=&b; 当执行p+;(或p=p+1;)时,p就指向变量c,相当于p=&c;而执行p-时,p就指向变量a,相当于p=&a。又如:float e,f,x,y,z,*p2; p2=&x; 当执行p2=p2+2;(或p+=2;)时,p2就指向变量z,相当于p=&z;而执行p2=p2-
19、2;(或p-=2;)时,p2就指向变量e,相当于p=&e。 两个指针变量之间的两个指针变量之间的算术算术运算运算:只有减法(-)运算。只有指向同一数组的两个指针变量之间才能进行这种运算,否则两个指针变量之间的运算毫无意义(但在程序中不会报错)。指向同一数组的两个指针变量之差,是两个指针之间的元素个数。结果为个数结果为个数。指向基本数据类型变量的指针变量指向基本数据类型变量的指针变量( (续续2)2)课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)13 /113如:p1=&a1;p2=&a4
20、;则p2-p1=4-1=3,表示p1与p2之间有3个数组元素。而p1-p2=-3。注意:注意:两个指针变量进行加法运算,如p1+p2,并无实际意义,并且是非法的指针运算。 两个指针变量之间的两个指针变量之间的比较比较( (关系关系运算运算) ):两个指针之间关系运算是比较两个指针所指向的地址关系,其运算符有:=、!=、=。比较运算结果为:真真(1)(1)或假或假(0)(0)。如: p1=&a1;p2=&a4; 则:p1=p2为假(0),p1!=p2为真(1),p1p2为假。p1=p2;p1=p2; 表示p1、p2指向同一数组元素地址。p1p2;p1p2; 表示p1比p2的地址值
21、大,处于高地址位置。p1p2;p1p2; 表示p1比p2的地址值小,处于低地址位置。注意:注意:只有两个指针指向同一数组的元素时,进行比较才有意义,这时指向前面的元素的指针变量“小于”指向后面的元素的指针变量。特别注意:如果两个指针变量不是指向同一数组,则这两个指针变量进行比较毫无意义(但在程序中不会报错)。 指针标量可以指向一个空值:指针标量可以指向一个空值:即该指针变量不指向任何变量。在stdio.h文件中有如下定义:#define null 0 ,当定义int *p=null;时,相当于int *p; p=null;或p=0;表示p不指向任何变量,而是指向地址为0的单元,表明p是空指针。
22、也就是说,有效数据的指针不指向0单元。注意:注意:空指针与未对p赋值是两个不同概念。空指针p是对p赋0值,而未对p赋值并不等于p无值,只是它是一个无法预料的值,这就可能影响有用单元。因此在引用指针变量之前,一定要对它赋值。任何指针变量或地址都可以与null作相等或不相等的比较。如:p=null,如果结果为真(1),表明p为空指针,否则p不是空指针。指向基本数据类型变量的指针变量指向基本数据类型变量的指针变量( (续续3)3)课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)14 /113 数组是同一类型变量组成的有
23、序集合,其本身存储的是各种类型的数据;而指针是专门用来存放其它变量的地址,当一个指针变量指向某一数组时,在对该数组元素的存取方式上,通过数组的下标与通过数组指针的运算访问数组元素是十分相似的。 一个变量可以有一个地址相对应,而一个数组包含若干个元素。每个数组元素都在内存中占用存储单元,同样有一个地址相对应。指针变量可以指向变量,所以也可以指向数组和数组元素,即把数组起始地址或某一元素的地址放到一个指针变量中。 所谓数组的指针数组的指针是指数组的起始地址,而数组元素的指针数组元素的指针是指数组元素的地址。实际上,定义的数组名就是一个指针数组名就是一个指针,表示数组的首地址,是一个固定值,一个常量
24、,与定义的指针变量是不同的。对数组的访问,即对数组元素的操作,可使用:下标法下标法,即直接使用数组的下标方式,如:a0、a4等;和指针法指针法,即通过指向数组元素的指针找到所需的数组元素。 指向数组元素的指针指向数组元素的指针 定义:int a10,*p; 数组元素相当于一个变量,因此每个元素的地址都可以赋给对应类型的指针变量。如:p=&a0;、p=&a2;、p=&a9;等都是合法的。p=&a8; 表示指针变量p指向了数组的第9个元素,而p=&a0;则表示指针变量p指向了数组的第1个元素。这时指针变量p与数组a就建立了关系,我们可以通过指针变量p访问数组
25、a了。 注意:注意:数组的类型与指针变量的类型应一致。2 2、指向一维数组的指针、指向一维数组的指针课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)15 /113 c语言规定数组名代表数组的首地址,即第0号元素的地址。因此:当定义int a10,*p;时,赋值语句:p=&a0;与p=a;是等价的。这时指针变量p就指向了数组a。注意:注意:数组a不代表整个数组元素,“p=a;”的作用是“把数组a的首地址赋给指针变量p”,而不是“把数组a各元素的值赋给p”。但是,这时就把数组a与指针变量p建立起了一种关系,我
26、们可以通过指针变量p访问数组a了。如下定义与赋值:int a10; int *p; p=a;与:int a10; int *p; p=&a0;是等价的。与:int a10; int *p=a; 也是等价的。与:int a10; int *p=&a0; 也是等价的。“int *p=a;”的作用是将数组a的首地址(即a0的地址)赋给指针变量p,而不是赋给*p。指向数组的指针指向数组的指针内存用户数据区内存用户数据区a0=1a1=3a2=2592000200220042008a3=-1a4=-1020060000000100000000111101101111111100000011
27、000000000000001100000001111111111111111120043010pp=&a2;p=&a0;或或p=a;p课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)16 /113有如下定义:int a20,*p;如果p的初值赋值为:p=a;或p=&a0; 则有:p或a均表示数组a的首地址,即&a0。这时的*p=2;或*a=2;都表示对a0元素赋值为2,即相当于:a0=2;。p+i或a+i就是ai的地址,即&ai。因此*(p+i)或*(a+i)就是p+i或
28、a+i所指向的数组元素ai,这时*(p+i)=3;或*(a+i)=3;就相当于ai=3;。因此*(p+i),*(a+i),ai是等价的。注意:注意:在c编译时,对数组ai的处理实际上就是处理成*(a+i)的,即按数组首地址加上相对位移量得到要找的元素的地址,然后找出该单元中的内容。因此*(a+i)的表示法比ai的表示法在程序执行时要快得多。由此可知,下标运算符实际上是变址运算符变址运算符,即将ai按a+i计算地址,然后找出此地址单元中的值。通过指针引用数组元素通过指针引用数组元素a数组存储区数组存储区a0a1a22000200220042000+2*iai3010pp , ap+2,a+2p+
29、i,a+ia192038p+19,a+19p+1,a+1课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)17 /113指向数组的指针变量也可以带下标。如:pi与*(p+i)是等价的,也与*(a+i)和ai是等价的。注意:注意:pi是数组元素的值而不是指针。因此*(p+i),*(a+i),ai,pi等价。如果:int a10,*p; p=&a4; 则:p2表示a6元素,p-3表示a1元素。引用数组元素的三种方法引用数组元素的三种方法引用数组元素的方法分为两大类:下标法下标法(如:a2)和指针法指针法(又有两
30、种方式:通过数组名计算数组元素地址,找出元素的值,如:*(a+2);和用指针变量指向数组元素,如:*(p+2)。例例 4.1 有一个整型数组,共有一个整型数组,共10个元素,输出数组中的全部元素。个元素,输出数组中的全部元素。 (详见教材详见教材p107)下标法:#include main() int a10,i; for (i=0;i10;i+) scanf(“%d”,&ai); printf(“n”); for (i=0;i10;i+) printf(“%6d”,ai); 通过数组名计算元素地址:#include main() int a10,i; for (i=0;i10;i+)
31、 scanf(“%d”,&ai); printf(“n”); for (i=0;i10;i+) printf(“%6d”,*(a+i); 通过指针变量操作数组元素:#include main() int a10,i,*p; for (i=0;i10;i+) scanf(“%d”,&ai); printf(“n”); for (p=a;p(a+10);p+) printf(“%6d”,*p); 课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)18 /113在例4.1中,所使用的三种方法的比较如下:
32、第1和第2种方法执行效率是相同的,都是将ai转换为*(a+i)处理。这两种方法找数组元素费时较多。 第3种方法比第1和第2种方法执行快,用指针变量直接指向元素,不必每次都重新计算地址,像p+这样的自加操作是比较快的,它是有规律地改变地址值的。 用下标法比较直观,能直接知道是第几个元素。如a5表示第5号元素(从0开始)。 用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪个元素。如进行多次p+操作后p值已改变,就要分析当前指针变量p指向哪个元素。但使用指针变量方式在复杂的数据结构中就显示出它的灵活性。使用指针变量对数组操作时应注意的问题使用指针变量对数组操作时应注意的问题 指针变量可
33、以实现使本身的值改变,而数组名是表示一个固定不变的数组首地址。如:int a10,*p=a; 则,执行p+(或p+=1或p=p+1)后,p就指向下一个元素a1。当定义int a10,*p; p=&a6; 执行-p(或p-=1或p=p-1)后,p就指向上一个元素a5。但是:for(p=a;a(p+10);a+) printf(“%d”,*a);则是非法的,不能实现a+且无意义。 定义int a10,*p; p=&a9;,这时再执行p=p+1;操作,p就指向了数组a以后的内存单元了,而不再指向数组a了。如果引用a10,c系统不作为非法,而是转换为*(a+10)处理,但它已超出数组a
34、的范围了,因此不能得到预期的结果。所以,在使用数组a或指针变量p时,应保证数组在有效范围内引用,保证指针变量是指向数组中有效的元素的。课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)19 /113特别注意指针变量的当前值。如以下程序: 指针变量的运算 p+(p+(或或p+=1p+=1) ),使p指向下一元素,如果p的初值为数组a的首地址的话,这时p就指向a1元素了。若再执行*p,就取出了a1的值。 * *p+p+,由于+和*同一优先级,结合方向为自右而左,因此它等价于*(p+)。作用是#include main(
35、) int a10,i,*p; p=a; for (i=0;i10;i+) scanf(“%d”,p+); printf(“n”); for (i=0;i10;i+,p+) printf(“%6d”,*p);这是错误的程序。第一个循环中的p+运行完后使它不指向数组a了。#include main() int a10,i,*p; p=a; for (i=0;i10;i+) scanf(“%d”,p+); printf(“n”); p=a; for (i=0;ia1,则交换;然 后比较第二个数与第三个数;依次类推,直至第n-1个数和第 n个数比较为止第一趟冒泡排序,结果最大的数被安置在 最后一个元
36、素位置上(2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在 第n-1个元素位置(3)重复上述过程,共经过n-1趟冒泡排序后,排序结束 注:在第一趟比较中要进行n1次两两比较,在第j趟比较中要进行nj次比较。p=a;while(pa+100) printf(“%6d”,*p+);p=a;while(pai+1真假a i ai+1输入n个数给a1到an输出a1到an课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)23 /113例例4.2(4.2(续续2)2)#include main() int a11,
37、i,j,t; printf(input 10 numbers:n); for(i=1;i11;i+) scanf(%d,&ai); printf(n); for(j=1;j=9;j+) for(i=1;iai+1) t=ai; ai=ai+1; ai+1=t; printf(the sorted numbers:n); for(i=1;i11;i+)printf(%d ,ai);#include main() int a11,i,j,t,*p; printf(input 10 numbers:n); p=a+1; for(i=1;i11;i+) scanf(%d,p+); printf
38、(n); for(j=1;j=9;j+) for(i=1;iai+1) t=ai; ai=ai+1; ai+1=t; printf(the sorted numbers:n); p=a+1; for(i=1;i11;i+,p+)printf(%d ,*p);或课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)24 /113例例4.2(4.2(续续3)3)以输入6个整数为例说明其执行过程:第一次循环示意图(共6个数,循环5次):第一次第二次第三次第四次第五次结果最大课件制作:刘达明课件制作:刘达明 023-66834
39、110第一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)25 /113例例4.2(4.2(续续4)4)第三次第四次结果 第二次循环示意图如下(共5个数,循环4次) :85420第一次第二次次大课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)26 /113例例4.2(4.2(续续5)5)024589 结果20第一次02结果 第五次循环4520 第二次4250第三次4205结果 第三次循环示意图如下:4520 第一次240第二次204结果240第一次 第四次循环示意图如下:课件制作:刘达明课件制
40、作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)27 /113例例4.34.3 求斐波那契fibonacci数列:1,1,2,3,5,8,的前40项。 解:在第三章中讲过 (详见教材p77的例3.31),这里使用数组实现。#include main() int i,f40=1,1; for(i=2;i40;i+) fi=fi-2+fi-1; for(i=0;i40;i+) if(i%4=0) printf(n); printf(%12d,fi); f0=1,f1=1for i=0 to 39输出:fifor i=2 to 39fi=f
41、i-1+fi-2)3(2 1)2(12) 1(1 1 nnfnfnfnfnf课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)28 /113例例4.44.4 用选择法对10个数排序。输入n 个数给a1 到 anfor i=1 to n-1for j=i+1 to najak真假k=j输出a1 到 ank=iaiaki != k真假排序过程排序过程: (1)首先通过n-1次比较,从n个数中找出最小的数的下下标标,通过下标找到对应的元素并与第一个数交换第一趟选择排序,结果最小的数被安置在第一个元素位置上。 (2)再通过
42、n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换第二趟选择排序。 (3)重复上述过程,共经过n-1趟排序后,排序结束。课件制作:刘达明课件制作:刘达明 023-6683411029 /113例例4.44.4(过程)(过程)例初始: 49 38 65 97 76 13 27 kji=11349一趟: 13 38 65 97 76 49 27 i=22738二趟: 13 27 65 97 76 49 38 三趟: 13 27 38 97 76 49 65 四趟: 13 27 38 49 76 97 65 五趟: 13 27 38 49 65 97 76 六趟: 13 27
43、 38 49 65 76 97 kkkkjjjjjjjjjj课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)30 /113例例4.44.4(程序)(程序)#include main() int a11,i,j,k,x; printf(input 10 numbers:n); for(i=1;i11;i+) scanf(%d,&ai); printf(n); for(i=1;i10;i+) k=i; for(j=i+1;j=10;j+) if(ajak) k=j; if(i!=k) x=ai; ai=ak;
44、 ak=x; printf(the sorted numbers:n); for(i=1;i11;i+)printf(%d ,ai);课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)31 /113例例4.54.5 用折半法查找一个数。 有15个数按由大到小的顺序存放在一个数组中,输入一个数,要求用折半法找出该数在数组中第几个元素的值位置。如果该数不在数组中,则打印出“无此数”。 对于无序的一组数据,只能使用顺序查找法顺序查找法查询数据。折半查找折半查找(也称对分查找)的前提是已经排好序。 折半查找法的思想折半查找
45、法的思想:使用均分确定的方法,先测区间的中点元素;如果被查找信息的关键字小于中点元素,则关键字在测中点的前半部分(降序时为后半部分);如果被查找信息的关键字大于中点元素,则关键字在测中点的后半部分(降序时为前半部分)。继续该过程直到找到该关键字或无法二分为止。课件制作:刘达明课件制作:刘达明一节第一节 一维数组一维数组(第四章(第四章 指针与数组)指针与数组)32 /113例例4.54.5 程序。#include #define n 15main() int bins(int a,int n,int x); int an,i=1,x; scanf(“%d”,&
46、;a0); while(i=ai-1) i+; scanf(“%d”,&x); pos=bins(a,n,x); if(pos!=-1) printf(“%d,%d”,pos,x); else printf(“not found”);/* 升序的折半法查找 */int bins(int a,int n,intx) int low,high,mid; low=0; high=n-1; while(lowamid) low=mid+1; else if(x1课件制作:刘达明课件制作:刘达明维数组可看成若干元素的一维数组二维数组可看成若干元素的一维数组第二节第二节
47、 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)39 /113 在c语言中,二维数组采用类似于float a34;的定义,使我们可以把二维数组看成是一种特殊的一维数组:它的元素又是一个一维数组。 如:float a34;把a看成是一维数组,它有3个元素:a0、a1、a2,每个元素又包括4个元素的一维数组。而a0、a1、a2就看成是包含4个元素的一维数组的数组名。 即定义:float a34;相当于定义:float a04,a14,a24;。a0 = a00 a01 a02 a03 a1 = a10 a11 a12 a13 a2 = a20 a21 a22 a23 a34 a00 a
48、01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 课件制作:刘达明课件制作:刘达明 023-668341105 5、二维数组的初始化、二维数组的初始化第二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)40 /113 二维数组与一维数组一样,可以对二维数组的元素进行赋值或者初始化。数组在定义后,它所占有的存储单元中的值是不确定的,引用数组元素之前,必须保证数组的元素已经被赋以确定的值。二维数组初始化的方法如下: 分行给二维数组赋初值分行给二维数组赋初值。 int a23=1,2,3,5,6,7; 第一个内花括号的值赋给数组的第一行,第二个
49、内花括号的值赋给数组的第二行。 所有数据写在一个花括弧内所有数据写在一个花括弧内,按顺序赋初值,按顺序赋初值。 int a23=2,3,5,6,7,8;它将第一组3个数赋给数组的第一行,第二组3个数赋给数组的第二行。该方法相对简单,但是,当数组元素较多时,容易出现混乱、遗漏、出错。在行、列数较多时,使用第一种方法较好。 对于定义的静态存储(关键字为static)数组,如果没有赋初值,则系统自动将全部元素赋以0值或0值。 如:static int a22;相当于static int a22=0,0,0,0 而对定义的int a22;如果不对其赋初值,则数组中各元素的值是不确定的。课件制作:刘达明
50、课件制作:刘达明部分元素赋初值对部分元素赋初值第二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)41 /113 数组在对部分元素赋初值时,如果后面的数组元素不赋初值,系统会对所有数组元素自动赋以0值。 如:int a23=0,2,1;相当于:int a23=0,2,0,1,0,0;。 再如:static int d23=8,5,9;相当于:static int d23=8,5,0,9,0,0;。 又如:int b23=1,0,3;相当于: int b23=1,0,3,0,0,0;。 如果对全部元素都赋初值时,则定义数组时,第一维(行)的长度可以
51、不指定,但第二维(列)的长度不能省需要指定。 如:int a4=1,2,3,4,5,6,7,8,9,10,11,12等价于:int a34=1,2,3,4,5,6,7,8,9,10,11,12;。课件制作:刘达明课件制作:刘达明盘输入赋值键盘输入赋值第二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)42 /113 通过键盘输入二维数组的数组元素,一般需要使用二重循环的形式进行。可以先行输入,也可先列输入。 先行输入方式先行输入方式 int a34; for(i=0;i2;i+) for(j=0;j3;j+) scanf(“%d”,&ai
52、j); 先列输入方式先列输入方式 int a34; for(j=0;i3;j+) for(i=0;i2;i+) scanf(“%d”,&aij);说明说明:不管是先行输入,还是先列输入,在计算机存储中数组元素仍然是按行存储的。课件制作:刘达明课件制作:刘达明过赋值语句通过赋值语句赋初值赋初值第二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)43 /113 如:int a22; a00=1; a01=2; a10=3; a11=4;。 在定义数组时也可以只对部分元素赋值,而省略第一维的长度,但应使用分行赋值方式。 如: int a4=1,
53、3,1,0,0,9; 它与 int a34=1,3,1,0,0,9; 等价。注:注:错误的初始化定义: int a33; a=1,2,3,4,5,6,7,8,9; 这是错误的。 而int a33; a33=1,2,3,4,5,6,7,8,9; 也是错误的赋值方式。课件制作:刘达明课件制作:刘达明二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)44 /113 c语言允许多维数组。多维数组的定义形式为: 类型说明符类型说明符 数组名数组名常量表达式常量表达式1 常量表达式常量表达式2常量表达式常量表达式n; 例如:定义三维数组的方法为:int a2
54、34; 定义四维数组的方法为:float f23410;等。 多维数组元素在内存中的存放顺序仍然是“按行优先”,其排列顺序为:第一维的下标变化最慢,最右边的下标变化最快。 如:int a234;定义的是一个三维数组,共有2*3*4=24个元素。其中第一维下标变化最慢,第二维下标变化次之,第三维下标变化最快。在内存的存放顺序为: a000, a001, a002, a003, a010, a011, a012, a013, a020, a021, a022, a023, a100, a101, a102, a103, a110, a111, a112, a113, a120, a121, a12
55、2, a123。二、二、多多维数组的概念维数组的概念课件制作:刘达明课件制作:刘达明二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)45 /113 分行初始化分行初始化: int a234=1,2,3,4,5,6,7,8,0,0,0,0, 13,14,15,16,17,18,19,20,21,22,23,24。 顺序赋值初始化顺序赋值初始化: int a234=1,2,3,4,5,6,7,8,0,0,0,0,13,14,15,16,17,18,19,20, 21,22,23,24;。 也可省略第一维的长度初始化也可省略第一维的长度初始化: in
56、t 34=1,2,3,4,5,6,7,8,0,0,0,0,13,14,15,16,17,18,19,20, 21,22,23,24;。 可将它看成2个二维数组a034和a134。也可看成是6个特殊的一维数组: a004、a014、a024、 a104、a114、a124 。多多维数组的初始化维数组的初始化课件制作:刘达明课件制作:刘达明二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)46 /113 1 1、二维数组的地址、二维数组的地址 关于一维数组与指针关系的结论可以推广到二维数组、三维数组等多维数组。可以把二维数组看成是这样的一维数组:它的
57、每个单元本身又是一个一维数组。 例如:int a43=1,3,5,7,9,11,13,15,17,19,21,23; 这里a是一个数组名。数组a包含4个元素(即4行):a0,a1,a2,a3,而每个元素又是一个包含3个元素(即3列元素)的一维数组。如a1代表的一维数组包括:a10,a11,a12三个元素。三、三、指向二维数组的指针变量指向二维数组的指针变量= a00 a01 a02 = a10 a11 a12 = a20 a21 a22 = a30 a31 a32 a0a1a2aa3= 1 3 5 = 7 9 11 = 13 15 17 = 19 21 23 a0a1a2aa3a0a1a2aa
58、31000100610121018a00 a01 a02a10 a11 a12a20 a21 a22a30 a31 a32a+1a+2a+3课件制作:刘达明课件制作:刘达明二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)47 /113 从二维数组的角度来看,a a代表代表整个整个二维数组的首地址二维数组的首地址,也就是二维数组a的第0行的首地址。假设二维数组a的首地址为:1000,那么,a的地址应为1000。则a+1为1006,因为第0行有3个整型数据,因此a+1a+1的含义是a1a1的地址的地址。a+2a+2代表第2行的首地址,它的值是101
59、2,是a2a2的地址的地址。a+3a+3代表第3行的首地址,它的值是1018,是a3a3的地址的地址。 既然把a0、a1、a2、a3看成是4个一维数组名,而c语言又规定了数组名代表数组的首地址。因此a0a0代表了第0行一维数组中第0列元素的地址,即&a00&a00。同样a1a1代表了第1行一维数组中第0列元素的地址,即&a10&a10。a2a2代表了第2行一维数组中第0列元素的地址,即&a20&a20。a3a3的值是&a30&a30。 作为一维数组a0的其他元素的地址可以使用a0+0、a0+1、a0+2分别表示元素a00、a01、
60、a02的地址。一般地,ai+jai+j即表示第i行第j列元素的地址,即&aij&aij。如a1的值是1006,则a1+1表示1008,它是&a11的值。有关二维数组地址的描述:有关二维数组地址的描述:课件制作:刘达明课件制作:刘达明二节第二节 二维数组二维数组(第四章(第四章 指针与数组)指针与数组)48 /113 由于a+1表示a1的地址,因此*(a+1)就是a1的值。a表示a0的地址,因此*a也就是a0的值。 一般地,a+i表示ai的地址,因此*(a+i)就是ai的值。所以* *a a与a0a0是等价的,a1a1与* *(a+1)(a+1) 是等价的。一般地,aiai与* *(a+i)(a+i)是等价的。 而a0又表示a00的地址,a1又表示a10的地址,ai又表示ai0的地址,因此* *(a+1)(a+1)、* *a a、* *(a+i)(a+i)虽然形式上是指针运算符,似乎指的是变量地址中所存储的值,但它仍然是地址仍然是地址,它们分别是a1、a0、ai的值。而a1、a0、ai仍然是地址,它们分别是a10、a00、ai0的地址。 注意:注意:a+i并不是一个变量,它是ai的地址。 a是二维数组名,代表数组首地址,不能用*a来得到a00的值。*a相当于*(a+0)即表示a0,它是第0行地址。a是行指针,*a是列指针。*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年麻精药品培训考核试题(含答案)
- 2026 年教师节感恩教育主题学习课件
- 研究生请假条模板
- 2026年广东茂名市中考模拟考试一模数学试题附答案
- 保健科易错试题与答案揭秘
- 微生物农药生产工风险识别水平考核试卷含答案
- 橡胶栽培工安全宣贯测试考核试卷含答案
- 木屋架工岗前设备性能考核试卷含答案
- 野生植物监测工安全风险能力考核试卷含答案
- 天然香料制备工成果测试考核试卷含答案
- 2026年浙江经贸职业技术学院高职单招笔试英语试题库含答案解析3套试卷
- 青海2026年省考公务员《行政职业能力测验》考试真题(完整版)
- 2026语文新教材 2026年秋期新教材统编版六年级上册语文教材分析解读 教学课件
- 《中华人民共和国生态环境法典》应知应会测试题100道
- 2025年重庆市从“五方面人员”中选拔乡镇领导班子成员考试历年参考题库含答案详解
- 诸暨水务集团招聘试卷
- 岗位hes责任制度
- 2026第二届全国红旗杯班组长大赛考试备考核心试题库500题
- 医疗器械公司介绍
- 2026湖南奥林匹克物理竞赛试题及答案
- 医疗器械有效期确认流程及报告模板
评论
0/150
提交评论