C语言程序设计》第5章数组、字符串、指针.ppt_第1页
C语言程序设计》第5章数组、字符串、指针.ppt_第2页
C语言程序设计》第5章数组、字符串、指针.ppt_第3页
C语言程序设计》第5章数组、字符串、指针.ppt_第4页
C语言程序设计》第5章数组、字符串、指针.ppt_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章 数组、字符串、指针,本章要求:,1、掌握C语言数组在内存中的存储形式 2、掌握一维数组和二维数组的定义及使用 3、掌握使用指针处理数组的方法 4、掌握使用字符数组及指针处理字符串数据的方法 5、掌握与数组有关的基本算法(如排序、查找、插入、删除等)的程序设计,重点: 一维数组、二维数组的定义与使用方法,使用指针访问数组和字符串的方法。 难点: 二维数组与指针;与数组有关的常用算法(排序、查找与插入等)。,5.1 数组概述,例. 输入10个数,求出他们的平均数。 main() int n,a,s=0; float ave; for (n=1;n=10;n+) scanf(“%d”, ,并打印出其中大于平均数的数,变量a中只能存放一个整数,需要10个变量的内存空间才可以保留10个整数,如果使用:a1,a2,a3,a4,a5,a6,a7,a8,a9,a10 这10个变量,代码:,int n,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10; float ave; scanf(“%d%d%d%d%d%d%d%d%d%d”, /* 实际程序是不能这样写*/,思考:,发现:如果不是10个数,而是100,1000,甚至是10000,此时按上面方法编写程序就非常冗长。 如果可以使用循环来编写,程序可以简洁许多。 要使用循环:必须使用ai (i=1,210)的形式来代表a1,a2a10 在C语言中使用“数组”来实现: ai,#include void main() int n,i; float s=0, ave, a10; for(i=0;iave) printf(“%f “,ai); ,声明有10个元素的一维数组a,在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。 在语言中, 数组属于构造数据类型。 按类型分为: 数值数组、 字符数组、 指针数组、结构数组等 按维数可分为:一维数组、二维数组、多维数组。 数组在内存中占用一片连续的存储单元,5.2 一维数组,只有一个下标变量的数组,称为一维数组。 5.2.1 一维数组定义 一般形式为: 类型符 数组名 常量表达式 ; 其中: 类型说明符是任一种基本数据类型或构造数据类型, 数组名是用户定义的标识符; 方括号中的常量表达式表示数据元素的个数,也称为数组的长度。,例如: int a10; float b10,c20; char ch20; 数组在内存中占据一片连续的存储空间: 以 int a5为例,在内存中为:,相当于声明了5个整型变量,说明:,数组的所有元素的数据类型都是相同的。 数组取名规则应符合标识符的规定,数组名不能与同一函数中其它变量名相同: int a; float a10; 是错误的。 C语言中规定数组的下标从0开始,方括号中常量表达式表示数组元素的个数。 不能在方括号中用变量来表示元素的个数, 但是可以是符号常数或常量表达式。例如:int n=5,an; 是错误的。,5.2.2 一维数组的初始化,1、数组声明时初始化 在编译阶段进行的。这样将减少运行时间,提高效率。 数组初始化的一般形式为: 类型符 数组名常量表达式=值,值值; 例如: int a10= 0,1,2,3,4,5,6,7,8,9 ; 相当于a0=0; a1=1;. a9=9;,说明:,int a10=0,1,2,3,4; int a10=1; static int a3; int a =1,2,3,4,5; int a5=1,2,3,4,5,1 ;,给前5个元素赋值,其余赋0值,不能给数组整体赋值,改成1,可以省略数组元素个数。,静态存储类型,初值为0,初值的个数不能超过元素个数,2、使用赋值语句初始化,用赋值语句初始化是在程序执行过程中实现的。例如: int a3; a0=5;a1=8;a2=9; 对于数组的元素用赋值语句初始化,常常使用循环来完成,例如: int k,a10; for(k=0;k10;k+) ak=1; /*对数组中所有元素赋初值为1*/,5.2.3 数组元素的引用,数组元素是组成数组的基本单元,数组元素可以看成一种变量。引用数组元素有下标法和指针法。本小节介绍下标法,指针法将在5.5节中介绍。 使用下标法引用一维数组元素的一般形式为: 数组名下标 其中,的下标只能为整型常量或整型表达式。若为小数时,C编译将自动取整。,说明:,int n=3,a10; an=5; an+1=10; int a10,x,y; a10=5; int a10; printf(“%d“,a);,正确代码。引用数组元素的时候,可以用变量。,错误代码。最大下标为9,没有a10元素。,错误代码。不能用一个语句输出整个数组。,5.2.4 一维数组的基本操作,可通过循环给数组元素输入数据 int a10,i,; for(i=0;i10;i+) scanf(“%d”, 例,输入5个数,再按倒序输出,5-1.c,求数组中最大元素,#define N 10 main() int i,p,max,aN; printf(“Enter %d Numbersn“,N); for(i=0;i max) max = ai; printf(“ The Max =%dn“,max); ,及其下标,求最大、最小值以及排序算法中的最大、最小值确定 都可以采用类似方法: 把第一个元素假想为当前找到的最大、最小值,在后续的比较中进行更新。,5-2.c,一维数组的倒置,for(i=0;i N/2;i+) t=ai; ai=aN-i-1; aN-i-1=t; ,a0 a1 a9,类似问题:字符串的回文比较,5-3.c,5.2.5 一维数组的应用举例,例:如果要统计09,1019,2029,. 8089,9099分数段及100分的人数。 编程分析: a数组用来存放20个学生成绩; 另用数组bn来存各分数段的人数: bn0存09分的人数, bn1存1019分的人数, bn9存9099分的人数, bn10存100分的人数。,5-4.c,一维数组的应用举例: 5.8.1 排序问题(教材P.166),数据的排序就是将一批数据由小大到(升序)或由大到小(降序)进行排列。常用的有选择法、冒泡法。 首先要将需要排序的数据放到数组中,这样,便于我们排序。,1选择法排序,算法描述:从剩下的元素集中找一个最小的元素依次放到第i个位置。i从0开始,原始数据:8 6 9 3 2 7 第一轮后:2 6 9 3 8 7 第二轮后:2 3 9 6 8 7 第三轮后:2 3 6 9 8 7 第四轮后:2 3 6 7 8 9 第五轮后:2 3 6 7 8 9,6个数需要经历5轮选择(i=04) 每一轮做的工作: 从第i个到最后一个中找一个最小的。 与第i个交换。放到ai这个位置。,代码:,for(i=0; i5; i+) p=i; for(j=i+1; j6; j+) if(ajap) p=j; t=ai; ai=ap; ap=t; ,从第i个到最后一个中找一个最小的。,与第i个交换。,6个数需要经历5轮选择(i=04),5-5.c,2冒泡法排序(升序),算法描述 第一轮:,第二轮:,5个数共4轮即可,代码:,for(i=0; iaj+1) t=aj; aj=aj+1; aj+1=t; ,每轮需要经过4-i次比较,发现前面的数比后面的数大则需要交换,把大的换到后面去。,5个数需要经历4轮选择(i=03),5-6.c,5.3 二维数组与多维数组,5.3.1 二维数组的声明 二维数组说明的一般形式是: 类型符 数组名常量表达式1常量表达式2; 其中: 常量表达式1表示第一维下标的长度 常量表达式2 表示第二维下标的长度。 例如: int a34; float b44; char c510;,int a34; 该数组的下标变量共有34个,即:,二维数组在内存的存放顺序是“先行后列”,注意:语言允许二维数组a34可分解为三个一维数组,其数组名分别为a0, a1, a2。这三个一维数组都有4个元素。,5.3.2 二维数组元素的引用,二维数组的元素的引用形式为: 数组名下标下标 使用二维数组的情况举例: 学生多门功课的成绩,如: a1003可以用来记录100个学生3门功课的成绩。 矩阵,如: a33可以用来记录33的矩阵。一个数组元素正好存放一个矩阵的元素。,5.3.3 二维数组的初始化,二维数组初始化也是在类型说明时给各下标变量赋以初值。 1. 按行分段赋值可写为 int 53=80,75,92,61,65,71, 59,63,70,85,87,90,76,77,85; 2. 按行连续赋值可写为 int a53= 80,75,92,61,65,71,59,63, 70,85,87, 90,76,77,85 ; 注意:这两种赋初值的结果是完全相同的。,说明:,int a33=1,2,3; int a 3=1,2,3,4,5,6,7,8;,5.3.4 二维数组的基本操作,二维数组的操作一般需要使用二重循环。 1二维数组的输入输出 设数组己定义 int aNM; 其程序段如下:,for(i=0;iN;i+) for(j=0;jM;j+) scanf(“%d”,for(i=0;iN;i+) for(j=0;jM;j+) printf(“%d ”,aij); printf(“n”);,2求最大元素及其所在的行和列,编程基本思路与在一维数组求最大值元素相同,row, column存放最大值所在行列号。 3. 矩阵的转置(方阵) 对比一维数组的倒置,注意: 哪些元素要交换? 和谁交换?,如果不是方阵,则要定义另一个数组。 bji = aij,5.3.6 多维数组的声明和引用,在处理三维空问题等其它复杂问题时要使用到三维及三维以上的数组,通常把三维及三维以上的数组称为多维数组。 定义多维数组的格式如下: 类型符 数组名常量1常量2常量3; 例如: int a555; /* 声明a是三维数组*/ float b26105; /* 声明b是四维数组*/ 注意:操作多维数组常常要用到多重循环。,2.6 指针变量 2.6.1 地址与指针的概念,数据存放在内存中,每个字节内存单元按顺序编号,称为“内存地址”。 通过内存单元的地址即可准确地找到该内存单元。 变量的地址就是变量的指针,指针变量,2.6.3 指针变量的定义,指针变量定义的一般形式: 类型符 *标识符; 说明: “*”直接修饰的“标识符”是指针变量。 int *p,x; /* p是指针变量,x是整型变量 */ 指针所指对象的类型称为指针的基准类型。 int *p1; /* p1的基准类型为整型,即p1所指向对象的类型是整型 */ char *p2; /* p2的基准类型为字符型,即p2所指向对象的类型是字符型 */,2.6.4 指针变量的初始化,#include void main() int *p; *p =5; printf(“*p=%dn“,*p); ,错误代码:可能引起严重后果,指向不可预料的内存空间,可以表示p变量所指的变量,初始化指针变量的方法主要有以下3种:,int a,*p; p= 使用malloc函数或calloc函数,给它们分配一个自由的内存空间地址。,2.6.5 指针变量的访问,格式为: *指针变量 例:int a=5, *p=,a为整型变量,变量里存放的是5 p为指针变量,变量里存放的是变量a的地址 &a表示变量a的地址 *p表示变量p所指向的变量,即5,p+1 p-1 + -运算,5.4 数组与指针,5.4.1 一维数组与指针 1、使用指针引用数组元素 系统给一个一维数组在内存中分配的一片连续存储空间,C语言规定其数组名就是数组在内存中的首地址。 使用指针引用数组元素的准备工作: int a10, *p /*定义数组与指针变量* / 做赋值操作: p = a; p = &a0;,两种方法效果完全一样,使用指针引用数组元素,使用指针变量p指向数组a: 方法一: int a10, *p; p=a; 方法二: int a10, *p=a;,a数组,注意:指针变量p的运算,*(p+0),*(p+1),*(p+2),*(p+i),*(p+9),说明:,p+i指向元素ai 使用指针法引用一维数组的第i个元素的方法: 使用指针变量*(p+i)访问元素ai。 使用数组名*(a+i)访问元素ai。 指向数组的指针变量也可以带下标,即: pi与*(p+i)等价,表示元素ai。,例子:方法一分析,int i,imax,max,aN; for(i=0;i max) max = ai ; imax = i; printf(“Max:a%d=%dn“,imax,max);,*(a+i),*(a+i),a+i,*(a+i)替代ai,a+i指向元素ai, 即为ai的地址,替代&ai,例子:方法二分析,int i,imax,max,aN; for(i=0;i max) max = ai ; imax = i; printf(“Max:a%d=%dn“,imax,max);,*p;,(p=a;pa+N;p+),p变量指向a1,p变量开始指向a0,然后逐个指向数组中的各个元素。,p,p=a+1;,p+),*p,*p,三种方法的比较:,方法一与老方法的下标法执行效率是相同的,C编译系统是将ai转换为*(a+i)处理,即先计算元素的地址。 方法二比方法一和下标法执行效率高,用指针变量直接指向元素,不必每次都重新计算地址,有规律地改变地址值(p+)能大大提高程序执行效率。 用下标法比较直观,能直接知道是第几个元素。使用指针法,一定要知道当前指针指向哪个元素,否则可能得到意想不到的结果。,例,输入5个数,再按倒序输出,使用指针引用数组元素,应注意以下2个问题:,若指针p指向数组a,虽然p+i与a+i、*(p+i)与*(a+i)意义相同,但注意p与a的区别: a代表数组的首地址,是不变的; p是一个指针变量,可以指向数组中的任何元素. for(p=a; a(p+10); a+) printf(“%d“, *a) 指针变量可以指向数组中的任何元素,注意指针变量的当前值。,5-7.c,指向数组元素的指针的一些运算,int a10,*p=a; p+ *p+ *(p+) *(+p) (*p)+,&a0,同,a0,a1,6,6,5.4.2 二维数组与指针,1. 二维数组的指针 例: int a34;,在内存中:,二级指针常量。因为数组名可以看成是由3个元素a0、a1、a2构成的一维数组,每个元素指向该行的首地址。因此,二维数组名是一个二级指针常量。 一级指针常量。a0可以看成是由a00、a01、a02、a03构成的一维数组,可以将a0这个特殊数组名理解为指向int类型的一级指针常量。a1与a0具有同样性质,a1与a0的偏移量是一行元素的长度。,2使用指向元素的指针变量来引用,定义一个指向二维数组元素类型的指针变量,通过指针变量来引用数组元素。 void main() int a34 = 1,2,3,4,5,6,7,8,9,10,11,12, i,*p; p=a0; for(i=0; i12; i+) printf(“%4d“, *p+); if ( (i%4 = 0) printf(“n“); ,3使用行指针变量来引用数组元素,对于二维数组,可以定义一个指向一行(即一个一维数组)的行指针变量,行指针变量就是一个二级指针变量,其性质与二维数组名相同。 行指针的定义形式如下: 类型标识符 (*指针变量名)元素个数; 例如:int (*p)4; 定义一个指向一行有4个整型元素的行指针变量。,例 使用行指针变量 void main() int a34=1,2,3,4,5,6,7,8,9,10,11,12; int i,j, (*p)4 ; p=a; for(i=0; i3; i+) for(j=0;j4;j+) printf(“%4d“, *(*p+j) ); p+; printf(“n“); ,注意:,不要将int(*p)4写成int *p4 int *p4 表示定义一个包含4个元素的一维数组,每个元素为整型的指针变量。 int(*p)4定义的是一个指向一个为数组的行指针变量指针变量p,每执行一次p+,指向二维数组的下一行。 *p+j指向当前行第j个元素的地址, *(*p+j)为当前行第j个元素的值。 二维数组名a是一个行指针常量,不能进行a+、a-的运算,p是行指针变量,可以进行p+等指针运算操作。,5.5 字符数组与字符串,5.5.1 字符数组与初值化 例如: char c10; 例如: char ch510; 字符数组也可在定义时作初始化赋值。 (1)逐个元素初始化,当初始化数据少于数组长度,多余元素为“空”(0),当初始化数据多于元素个数时,将出错。 char c10=c, ,p,r,o,g,r,a,m;,char d210= I, ,a,m, ,a, ,b,o, y,G,o,o,d, ,b,o,y,(2) 指定初值时,若未指定数组长度,则长度等于初值个数。 char c = I, ,a,m, ,h,a,p,p,y;,5.5.3 字符串与字符数组,在语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。 字符串总是以0作为串的结束符。因此当把一个字符串存入一个数组时, 也把结束符0存入数组,并以此作为该字符串是否结束的标志。 字符数组可以用字符串来初始化: char c=“C program“; 或: char c=“C program“;,5.5.4 字符数组的输入输出,字符数组的输入输出一般采用下面两种方法:可用printf函数和scanf函数中使用。 1、用“%c”格式符逐个输入输出。 2、用“%s”格式符按字符串输入输出。 例: char c8; printf(“Input:“); scanf(“%s“,c); printf(“%s“,c);,运行时输入:Hello,说明:,输出时,遇0结束,且输出字符中不包含0。 “%s”格式输出字符串时,printf()函数的输出项是字符数组名,而不是元素名。 char c = “Good!“; printf(“%s“,c); printf(“%c“,c0); printf(“%s“,c0); /* 错误 */ “%s”格式输出时,即使数组长度大于字符串长度,遇0也结束。例如: char c10 = “Good!“; printf(“%s“,c); /*只输出5个字符 */,“%s”格式输出时,若数组中包含一个以上0,遇第一个0时结束。例如: char c = “Good!0boy“; printf(“%s“,c); /*输出结果:Good! */ 输入时,遇回车键、空格键结束,但获得的字符中不包含回车键本身,而是在字符串末尾添0 C语言中,数组名代表该数组的起始地址,scanf()函数中不需要地址运算符 /* 错误的 */,一个scanf函数输入的字符串中有空格时要特别注意。例如: char str13; scanf(“%s”,str);,运行时输入:How are you?,结果只有“How”被放入str,解决方案: 输入到多个字符串: char str15,str25,str35; scanf(“%s%s%s“,str1,str2,str3); 使用逐个字符输入: for(i=0;i=11;i+) ci=getchar(); c12=0;,5.6 字符串字符指针,5.6.1 指向字符串的指针 例:char s10; s=“Welcome“; s=“Welcome“; C语言中使用字符指针来处理字符串的很方便。首先需要定义一个基类型为字符型的指针变量。例如:char *s; 两种赋值方法: char *s= “Welcome“ ; char *s; s=“Welcome“;, ,两种方法:s变量得到的都是字符串的首地址。,例:写出程序的运行结果。,void main() char *p; char s =“ABCD“; for(p=s;ps+4;p+) printf(“%sn“,p); getch(); ,例:已知字符串char s1 =“How are you”;将s1中的空格删除后放入字符数组s2中。,5-8.c,5-9.c,5.6.2 使用字符串指针变量与字符数组的区别,三者含义: 字符串指针变量本身是一个变量,用于存放字符串的首地址。 字符串本身是存放在一块连续的内存空间中并以0作为字符串的结束。 字符数组是由若干个数组元素组成的,它可用来存放整个字符串。 注意:char *ps=“C Language”; char *ps;ps=“C Language”; char st=“C Language”; char st20;st=“C Language“。, ,5.6.3 字符串处理函数,用于输入输出的字符串函数, 应包含头文件“stdio.h” 。 1.字符串输出函数: 格式: puts (str) ; 说明: str为数组名或指针变量。 等价于:printf(“%sn”,str);有换行。 2.字符串输入函数 格式: gets (str); 说明: str为数组名或指针变量。 将输入的字符串加上结束标志0 。 以回车最为输入结束。,使用其它字符串函数应包含头文件“string.h“。,3.字符串连接函数:strcat (str1,str2) 4.字符串拷贝函数:strcpy (str1,str2) 5.字符串比较函数:strcmp(str1,str2) 6. 测字符串长度函数:strlen(str) 7. 字符大写转小写函数:strlwr(str) 8. 字符小写转大写函数:strupr(str),使用方法: 例:strcat(str1,str2); 执行后结果在str1中。,例:k=strlen(str); 结果在函数的返回值中,可以赋值给其他变量。,5.7 指针数组与多级指针变量,5.7.1 指针数组 概念:指针数组是一个数组,该数组中的每一个元素是指针变量。 定义: 类型标识符 *数组名数组元素个数; 例如: int *p4; 定义一个指针数组,数组名p,有4个元素,每一个元素是指向整型变量的指针。 注意与指向数组的指针变量的区分:int(*p)4定义一个指针变量,它指向有4个元素的一维数组。,指针数组的用途:处理多个字符串。,先来看使用二维数组存放多个字符串: char ch 16=“Follow me“, “BASIC“, “Great Wall“, “FORTRAN“, “Computer Design“ 使用二维数组处理浪费较多内存。,使用指针数组,char *pc =“Follow me“, “BASIC“, “Great Wall“, “FORTRAN“, “Computer Design“; 说明:pc是一维数组,里面存放着5个指向字符型变量的指针。,例 将若干字符串按字母顺序输出。,#include “stdio.h“ #include “string.h“ void main() char *temp; int i, j, k, n=5; char *pc = “Follow me“, “BASIC“, “Great Wall“, “FORTRAN“, “Co

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论