工学《C语言程序设计》第5章-数组、字符串、指针课件_第1页
工学《C语言程序设计》第5章-数组、字符串、指针课件_第2页
工学《C语言程序设计》第5章-数组、字符串、指针课件_第3页
工学《C语言程序设计》第5章-数组、字符串、指针课件_第4页
工学《C语言程序设计》第5章-数组、字符串、指针课件_第5页
已阅读5页,还剩155页未读 继续免费阅读

下载本文档

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

文档简介

第5章数组、字符串、指针第5章数组、字符串、指针本章要求:1、掌握C语言数组在内存中的存储形式2、掌握一维数组和二维数组的定义及使用3、掌握使用指针处理数组的方法4、掌握使用字符数组及指针处理字符串数据的方法5、掌握与数组有关的基本算法(如排序、查找、插入、删除等)的程序设计本章要求:1、掌握C语言数组在内存中的存储形式重点:一维数组、二维数组的定义与使用方法,使用指针访问数组和字符串的方法。难点:二维数组与指针;与数组有关的常用算法(排序、查找与插入等)。重点:5.1数组概述例.输入10个数,求出他们的平均数。main(){intn,a,s=0;floatave;for(n=1;n<=10;n++){scanf(“%d”,&a);

s=s+a;

}ave=s/10;printf(“Ave=%d\n”,ave);

}并打印出其中大于平均数的数a

变量a中只能存放一个整数

需要10个变量的内存空间才可以保留10个整数5.1数组概述例.输入10个数,求出他们的平均数。并如果使用:a1,a2,a3,a4,a5,a6,a7,a8,a9,a10这10个变量,代码:intn,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;floatave;scanf(“%d%d%d%d%d%d%d%d%d%d”,

&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,

&a10);s=a1+a2+a3+a4+a5+a6+a7+a8+a9+a10;ave=s/10;if(a1>ave)printf(“%d”,a1);

if(a2>ave)printf(“%d”,a2);

if(a3>ave)printf(“%d”,a3);………..

/*实际程序是不能这样写*/如果使用:a1,a2,a3,a4,a5,a6,a7,a8,a思考:发现:如果不是10个数,而是100,1000,甚至是10000,此时按上面方法编写程序就非常冗长。

如果可以使用循环来编写,程序可以简洁许多。要使用循环:必须使用ai(i=1,2…10)的形式来代表a1,a2…a10在C语言中使用“数组”来实现:a[i]a[0]a[1]…a[9]思考:发现:如果不是10个数,而是100,1000,甚至是1#include<stdio.h>voidmain(){intn,i;

floats=0,ave,a[10];

for(i=0;i<10;i++){scanf("%f",&a[i]);s=s+a[i];}ave=s/10;for(i=0;i<10;i++)if(a[i]>ave)printf("%f",a[i]);}声明有10个元素的一维数组aa[0]a[1]…a[9]a[i]a[i]a[i]a[i]#include<stdio.h>声明有10个元素的一维数在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。在C语言中,数组属于构造数据类型。按类型分为:数值数组、字符数组、指针数组、结构数组等按维数可分为:一维数组、二维数组、多维数组。数组在内存中占用一片连续的存储单元在程序设计中,为了处理方便,把具有相同类型的若干变量按有序5.2一维数组只有一个下标变量的数组,称为一维数组。

5.2.1一维数组定义

一般形式为:

类型符数组名[常量表达式];

其中:类型说明符是任一种基本数据类型或构造数据类型,数组名是用户定义的标识符;方括号中的常量表达式表示数据元素的个数,也称为数组的长度。5.2一维数组只有一个下标变量的数组,称为一维数组。例如:inta[10];floatb[10],c[20];charch[20];

数组在内存中占据一片连续的存储空间:

以inta[5]为例,在内存中为:a[0]a[1]a[2]a[3]a[4]相当于声明了5个整型变量例如:a[0]a[1]a[2]a[3]a[4]相当于声明了5说明:数组的所有元素的数据类型都是相同的。数组取名规则应符合标识符的规定,数组名不能与同一函数中其它变量名相同:

inta;floata[10];

是错误的。C语言中规定数组的下标从0开始,方括号中常量表达式表示数组元素的个数。不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。例如:intn=5,a[n];

是错误的。说明:数组的所有元素的数据类型都是相同的。5.2.2一维数组的初始化1、数组声明时初始化

在编译阶段进行的。这样将减少运行时间,提高效率。数组初始化的一般形式为:

类型符数组名[常量表达式]={值,值…值};例如:inta[10]={0,1,2,3,4,5,6,7,8,9};

相当于a[0]=0;a[1]=1;...a[9]=9;

5.2.2一维数组的初始化1、数组声明时初始化

说明:inta[10]={0,1,2,3,4};inta[10]=1;staticinta[3];inta[]={1,2,3,4,5};inta[5]={1,2,3,4,5,1};给前5个元素赋值,其余赋0值不能给数组整体赋值,改成{1}可以省略数组元素个数。静态存储类型,初值为0初值的个数不能超过元素个数说明:inta[10]={0,1,2,3,4};给前5个元2、使用赋值语句初始化

用赋值语句初始化是在程序执行过程中实现的。例如:inta[3];a[0]=5;a[1]=8;a[2]=9;对于数组的元素用赋值语句初始化,常常使用循环来完成,例如:intk,a[10];for(k=0;k<10;k++)a[k]=1;/*对数组中所有元素赋初值为1*/2、使用赋值语句初始化用赋值语句初始化是在程序执行过5.2.3数组元素的引用

数组元素是组成数组的基本单元,数组元素可以看成一种变量。引用数组元素有下标法和指针法。本小节介绍下标法,指针法将在5.5节中介绍。使用下标法引用一维数组元素的一般形式为:

数组名[下标]

其中,的下标只能为整型常量或整型表达式。若为小数时,C编译将自动取整。5.2.3数组元素的引用数组元素是组成数组的基本单说明:intn=3,a[10];

a[n]=5;a[n+1]=10;inta[10],x,y;

a[10]=5;inta[10];

printf("%d",a);

正确代码。引用数组元素的时候,可以用变量。错误代码。最大下标为9,没有a[10]元素。错误代码。不能用一个语句输出整个数组。说明:intn=3,a[10];

a[n]=5;a[n+5.2.4一维数组的基本操作可通过循环给数组元素输入数据

inta[10],i,;for(i=0;i<10;i++)scanf(“%d”,&a[i]);也可通过循环输出数组元素

for(i=0;i<10;i++)printf(“%d”,a[i]);例,输入5个数,再按倒序输出5-1.c5.2.4一维数组的基本操作可通过循环给数组元素输入数据求数组中最大元素#defineN10main()

{inti,p,max,a[N];printf("Enter%dNumbers\n",N);for(i=0;i<N;i++)scanf("%d",&a[i]);max=a[0];for(i=1;i<N;i++)if(a[i]>max)max=a[i];printf("TheMax=%d\n",max);}p=0;a[%d]=%d\n",p,max);{p=i;}及其下标求最大、最小值以及排序算法中的最大、最小值确定都可以采用类似方法:把第一个元素假想为当前找到的最大、最小值,在后续的比较中进行更新。5-2.c求数组中最大元素#defineN10p=0;a[%d]一维数组的倒置for(i=0;i<N/2;i++){t=a[i];a[i]=a[N-i-1];a[N-i-1]=t;}002468135791924681357029746813520397568134204975381642059753186420a[0]a[1]…a[9]类似问题:字符串的回文比较5-3.c一维数组的倒置for(i=0;i<N/2;i++)00245.2.5一维数组的应用举例例:如果要统计0~9,10~19,20~29,….80~89,90~99分数段及100分的人数。

编程分析:a数组用来存放20个学生成绩;另用数组bn来存各分数段的人数:bn[0]存0~9分的人数,bn[1]存10~19分的人数,…bn[9]存90~99分的人数,bn[10]存100分的人数。5-4.c5.2.5一维数组的应用举例例:如果要统计0~9,10~一维数组的应用举例:

5.8.1排序问题(教材P.166)数据的排序就是将一批数据由小大到(升序)或由大到小(降序)进行排列。常用的有选择法、冒泡法。首先要将需要排序的数据放到数组中,这样,便于我们排序。一维数组的应用举例:

5.8.1排序问题(教材P.166)1.选择法排序算法描述:从剩下的元素集中找一个最小的元素依次放到第i个位置。i从0开始原始数据:869327第一轮后:269387第二轮后:239687第三轮后:236987第四轮后:2367

89第五轮后:236789a[0]a[1]a[2]a[3]a[4]a[5]8693276个数需要经历5轮选择(i=0~4)每一轮做的工作:从第i个到最后一个中找一个最小的。与第i个交换。放到a[i]这个位置。1.选择法排序算法描述:从剩下的元素集中找一个最小的元素依次代码:for(i=0;i<5;i++){p=i;for(j=i+1;j<6;j++)if(a[j]<a[p])p=j;t=a[i];a[i]=a[p];a[p]=t;}i<N-1;i<N;

从第i个到最后一个中找一个最小的。与第i个交换。6个数需要经历5轮选择(i=0~4)5-5.c代码:for(i=0;i<5;i++)i<N-1;2.冒泡法排序(升序)算法描述第一轮:8693268932689326839268329①②③④

683296382963289①②③第二轮:5个数共4轮即可…2.冒泡法排序(升序)算法描述86666①②代码:

for(i=0;i<4;i++)for(j=0;j<4-i;j++)if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}i<N-1;i<N-i-1;每轮需要经过4-i次比较发现前面的数比后面的数大则需要交换,把大的换到后面去。5个数需要经历4轮选择(i=0~3)5-6.c代码:for(i=0;i<4;i++)i<N-5.3二维数组与多维数组5.3.1二维数组的声明二维数组说明的一般形式是:

类型符数组名[常量表达式1][常量表达式2];其中:常量表达式1表示第一维下标的长度常量表达式2表示第二维下标的长度。例如:inta[3][4];

floatb[4][4];

charc[5][10];

5.3二维数组与多维数组5.3.1二维数组的声明inta[3][4];

该数组的下标变量共有3×4个,即:a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]…a[2][3]二维数组在内存的存放顺序是“先行后列”注意:C语言允许二维数组a[3][4]可分解为三个一维数组,其数组名分别为a[0],a[1],a[2]。这三个一维数组都有4个元素。inta[3][4];该数组的下标变量共有3×4个,即:5.3.2二维数组元素的引用二维数组的元素的引用形式为:

数组名[下标][下标]使用二维数组的情况举例:学生多门功课的成绩,如:

a[100][3]可以用来记录100个学生3门功课的成绩。矩阵,如:

a[3][3]可以用来记录3×3的矩阵。一个数组元素正好存放一个矩阵的元素。5.3.2二维数组元素的引用二维数组的元素的引用形式为:5.3.3二维数组的初始化

二维数组初始化也是在类型说明时给各下标变量赋以初值。1.按行分段赋值可写为

int[5][3]={{80,75,92},{61,65,71},

{59,63,70},{85,87,90},{76,77,85}};

2.按行连续赋值可写为

inta[5][3]={80,75,92,61,65,71,59,63,

70,85,87,90,76,77,85};

注意:这两种赋初值的结果是完全相同的。5.3.3二维数组的初始化二维数组初始化说明:inta[3][3]={{1},{2},{3}};inta[][3]={1,2,3,4,5,6,7,8};100200300123456780说明:inta[3][3]={{1},{2},{3}};15.3.4二维数组的基本操作二维数组的操作一般需要使用二重循环。1.二维数组的输入输出

设数组己定义

inta[N][M];

其程序段如下:for(i=0;i<N;i++)for(j=0;j<M;j++)scanf(“%d”,&a[i][j]);for(i=0;i<N;i++){for(j=0;j<M;j++)printf(“%d”,a[i][j]);printf(“\n”);}5.3.4二维数组的基本操作二维数组的操作一般需要使用二重2.求最大元素及其所在的行和列

编程基本思路与在一维数组求最大值元素相同,row,column存放最大值所在行列号。3.矩阵的转置(方阵)对比一维数组的倒置,注意:哪些元素要交换?和谁交换?a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[3][0]a[3][1]a[3][2]a[3][3]

如果不是方阵,则要定义另一个数组。b[j][i]=a[i][j]2.求最大元素及其所在的行和列编程基本思路与在一维数5.3.6多维数组的声明和引用

在处理三维空问题等其它复杂问题时要使用到三维及三维以上的数组,通常把三维及三维以上的数组称为多维数组。定义多维数组的格式如下:

类型符数组名[常量1][常量2][常量3]…;例如:inta[5][5][5];/*声明a是三维数组*/floatb[2][6][10][5];/*声明b是四维数组*/注意:操作多维数组常常要用到多重循环。5.3.6多维数组的声明和引用在处理三维空问题等2.6指针变量

2.6.1地址与指针的概念

数据存放在内存中,每个字节内存单元按顺序编号,称为“内存地址”。通过内存单元的地址即可准确地找到该内存单元。变量的地址就是变量的指针5x2003变量名变量值变量地址p指针变量2.6指针变量

2.6.1地址与指针的概念数据存放2.6.3指针变量的定义

指针变量定义的一般形式:

类型符*标识符;说明:“*”直接修饰的“标识符”是指针变量。

int*p,x;

/*p是指针变量,x是整型变量*/指针所指对象的类型称为指针的基准类型。

int*p1;

/*p1的基准类型为整型,即p1所指向对象的类型是整型*/

char*p2;

/*p2的基准类型为字符型,即p2所指向对象的类型是字符型*/2.6.3指针变量的定义指针变量定义的一般形式:

2.6.4指针变量的初始化#include<stdio.h>voidmain(){int*p;*p=5;printf("*p=%d\n",*p);}错误代码:可能引起严重后果不定值p指向不可预料的内存空间*p可以表示p变量所指的变量2.6.4指针变量的初始化#include<stdio初始化指针变量的方法主要有以下3种:inta,*p;

p=&a;

inta,*p1,*p2=&a;

p1=p2;

使用malloc函数或calloc函数,给它们分配一个自由的内存空间地址。apap1p2初始化指针变量的方法主要有以下3种:inta,*p;

p2.6.5指针变量的访问格式为:

*指针变量例:inta=5,*p=&a;a为整型变量,变量里存放的是5p为指针变量,变量里存放的是变量a的地址&a表示变量a的地址*p表示变量p所指向的变量,即5ap&a5*p2.6.5指针变量的访问格式为:

*指针变量ap+1p-1++--运算p+1p-15.4数组与指针

5.4.1一维数组与指针

1、使用指针引用数组元素系统给一个一维数组在内存中分配的一片连续存储空间,C语言规定其数组名就是数组在内存中的首地址。

使用指针引用数组元素的准备工作:

inta[10],*p/*定义数组与指针变量*/

做赋值操作:p=a;p=&a[0];两种方法效果完全一样5.4数组与指针5.4.1一维数组与指针

1、使用指使用指针引用数组元素使用指针变量p指向数组a:方法一:

inta[10],*p;

p=a;方法二:

inta[10],*p=a;a[0]a[1]a[2]...a[i]...a[9]pp+1或a+1p+2或a+2p+i或a+ip+9或a+9a数组注意:指针变量p的运算*(p+0)*(p+1)*(p+2)*(p+i)*(p+9)使用指针引用数组元素使用指针变量p指向数组a:a[0]a[1说明:p+i指向元素a[i]

使用指针法引用一维数组的第i个元素的方法:使用指针变量*(p+i)访问元素a[i]。使用数组名*(a+i)访问元素a[i]。指向数组的指针变量也可以带下标,即:

p[i]与*(p+i)等价,表示元素a[i]。说明:p+i指向元素a[i]例子:方法一分析inti,imax,max,a[N];for(i=0;i<N;i++)

scanf("%d",&a[i]);max=a[0];

imax=0;for(i=1;i<N;i++)

if(a[i]>max){max=a[i];

imax=i;}printf(“Max:a[%d]=%d\n",imax,max);*(a+i)*(a+i)a+i*(a+i)替代a[i]a+i指向元素a[i],即为a[i]的地址,替代&a[i]例子:方法一分析inti,imax,max,a[N];*例子:方法二分析inti,imax,max,a[N];for(i=0;i<N;i++)

scanf("%d",&a[i]);max=a[0];

imax=0;for(i=1;i<N;i++)

if(a[i]>max){max=a[i];

imax=i;}printf(“Max:a[%d]=%d\n",imax,max);,*p;(p=a;p<a+N;p++)p变量指向a[1]p变量开始指向a[0],然后逐个指向数组中的各个元素。pp=a+1;,p++)*p*p例子:方法二分析inti,imax,max,a[N];,三种方法的比较:方法一与老方法的下标法执行效率是相同的,C编译系统是将a[i]转换为*(a+i)处理,即先计算元素的地址。方法二比方法一和下标法执行效率高,用指针变量直接指向元素,不必每次都重新计算地址,有规律地改变地址值(p++)能大大提高程序执行效率。用下标法比较直观,能直接知道是第几个元素。使用指针法,一定要知道当前指针指向哪个元素,否则可能得到意想不到的结果。三种方法的比较:方法一与老方法的下标法执行效率是相同的,C编例,输入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例,输入5个数,再按倒序输出使用指针引用数组元素,应注意以下指向数组元素的指针的一些运算inta[10],*p=a;p++*p++*(p++)*(++p)(*p)++5a[0]8a[1]2a[2]...3a[i]...4a[9]pp&a[0]同③a[0]pa[1]66p指向数组元素的指针的一些运算inta[10],*p=a;55.4.2二维数组与指针

1.二维数组的指针例:inta[3][4];a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]…a[2][3]在内存中:5.4.2二维数组与指针1.二维数组的指针a[0][二级指针常量。因为数组名可以看成是由3个元素a[0]、a[1]、a[2]构成的一维数组,每个元素指向该行的首地址。因此,二维数组名是一个二级指针常量。一级指针常量。a[0]可以看成是由a[0][0]、a[0][1]、a[0][2]、a[0][3]构成的一维数组,可以将a[0]这个特殊数组名理解为指向int类型的一级指针常量。a[1]与a[0]具有同样性质,a[1]与a[0]的偏移量是一行元素的长度。二级指针常量。因为数组名可以看成是由3个元素a[0]、a[1[工学]《C语言程序设计》第5章___数组、字符串、指针课件

2.使用指向元素的指针变量来引用定义一个指向二维数组元素类型的指针变量,通过指针变量来引用数组元素。voidmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,*p;p=a[0]; for(i=0;i<12;i++){printf("%4d",*p++);if((i%4==0)printf("\n");}}2.使用指向元素的指针变量来引用定义一个指向二维数组元素类3.使用行指针变量来引用数组元素

对于二维数组,可以定义一个指向一行(即一个一维数组)的行指针变量,行指针变量就是一个二级指针变量,其性质与二维数组名相同。行指针的定义形式如下:

类型标识符(*指针变量名)[元素个数];例如:int(*p)[4];定义一个指向一行有4个整型元素的行指针变量。3.使用行指针变量来引用数组元素对于二维例使用行指针变量voidmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};inti,j,(*p)[4];p=a;for(i=0;i<3;i++){for(j=0;j<4;j++)printf("%4d",*(*p+j));p++;printf("\n");}}例使用行指针变量

注意:

不要将int(*p)[4]写成int*p[4]int*p[4]

表示定义一个包含4个元素的一维数组,每个元素为整型的指针变量。

int(*p)[4]定义的是一个指向一个为数组的行指针变量指针变量p,每执行一次p++,指向二维数组的下一行。*p+j指向当前行第j个元素的地址,

*(*p+j)为当前行第j个元素的值。二维数组名a是一个行指针常量,不能进行a++、a--的运算,p是行指针变量,可以进行p++等指针运算操作。注意:不要将int(*p)[4]写成int*p[4]5.5字符数组与字符串5.5.1字符数组与初值化

例如:charc[10];

例如:charch[5][10];字符数组也可在定义时作初始化赋值。(1)逐个元素初始化,当初始化数据少于数组长度,多余元素为“空”('\0'),当初始化数据多于元素个数时,将出错。

charc[10]={'c','','p','r','o','g','r','a','m'};5.5字符数组与字符串5.5.1字符数组与初值化chard[2][10]={{'I','','a','m','','a','','b','o','y'},{'G','o','o','d','','b','o','y'}}(2)

指定初值时,若未指定数组长度,则长度等于初值个数。charc[]={'I','','a','m','','h','a','p','p','y'};

chard[2][10]={{'I','','a',5.5.3字符串与字符数组

在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。字符串总是以‘\0’作为串的结束符。因此当把一个字符串存入一个数组时,也把结束符‘\0’存入数组,并以此作为该字符串是否结束的标志。字符数组可以用字符串来初始化:charc[]={"Cprogram"};

或:charc[]="Cprogram";Cprogram\05.5.3字符串与字符数组在C语言中没有专门5.5.4字符数组的输入输出

字符数组的输入输出一般采用下面两种方法:可用printf函数和scanf函数中使用。

1、用“%c”格式符逐个输入输出。

2、用“%s”格式符按字符串输入输出。例:

charc[8];printf("Input:");scanf("%s",c);printf("%s",c);Hello\0运行时输入:Helloc5.5.4字符数组的输入输出字符数组的输入说明:输出时,遇'\0'结束,且输出字符中不包含'\0'。“%s”格式输出字符串时,printf()函数的输出项是字符数组名,而不是元素名。charc[]="Good!";printf("%s",c);printf("%c",c[0]);printf("%s",c[0]);

/*错误*/“%s”格式输出时,即使数组长度大于字符串长度,遇‘\0’也结束。例如:charc[10]={"Good!"};printf("%s",c);

/*只输出5个字符*/说明:输出时,遇'\0'结束,且输出字符中不包含'\0'。“%s”格式输出时,若数组中包含一个以上‘\0’,遇第一个‘\0’时结束。例如:charc[]={"Good!\0boy"};printf("%s",c);

/*输出结果:Good!*/输入时,遇回车键、空格键结束,但获得的字符中不包含回车键本身,而是在字符串末尾添'\0'C语言中,数组名代表该数组的起始地址,scanf()函数中不需要地址运算符&。charstr[13];scanf("%s",str);scanf("%s",&str);

/*错误的*/“%s”格式输出时,若数组中包含一个以上‘\0’,遇第一个‘一个scanf函数输入的字符串中有空格时要特别注意。例如:charstr[13];scanf(“%s”,str);运行时输入:Howareyou?结果只有“How”被放入str解决方案:输入到多个字符串:charstr1[5],str2[5],str3[5];scanf("%s%s%s",str1,str2,str3);使用逐个字符输入:

for(i=0;i<=11;i++)c[i]=getchar();c[12]='\0';

一个scanf函数输入的字符串中有空格时要特别注意。例如:运5.6字符串字符指针5.6.1指向字符串的指针例:chars[10];

s[]="Welcome";s="Welcome";C语言中使用字符指针来处理字符串的很方便。首先需要定义一个基类型为字符型的指针变量。例如:char*s;两种赋值方法:

char*s="Welcome";char*s;s="Welcome";{}两种方法:s变量得到的都是字符串的首地址。5.6字符串字符指针5.6.1指向字符串的指针例:写出程序的运行结果。voidmain(){char*p;chars[]="ABCD";for(p=s;p<s+4;p++)printf("%s\n",p);getch();}ABCD\0spppp例:已知字符串chars1[]=“Howareyou”;将s1中的空格删除后放入字符数组s2中。5-8.c5-9.c例:写出程序的运行结果。voidmain()ABCD\0s5.6.2使用字符串指针变量与字符数组的区别三者含义:字符串指针变量本身是一个变量,用于存放字符串的首地址。字符串本身是存放在一块连续的内存空间中并以‘\0’作为字符串的结束。字符数组是由若干个数组元素组成的,它可用来存放整个字符串。注意:char*ps=“CLanguage”;

char*ps;ps=“CLanguage”;

charst[]={“CLanguage”};

charst[20];st={"CLanguage"}。√√√×5.6.2使用字符串指针变量与字符数组的区别三者含义:√

5.6.3字符串处理函数

用于输入输出的字符串函数,应包含头文件“stdio.h”。1.字符串输出函数:

格式:puts(str);说明:①str为数组名或指针变量。

②等价于:printf(“%s\n”,str);有换行。2.字符串输入函数

格式:gets(str);说明:①str为数组名或指针变量。

②将输入的字符串加上结束标志‘\0’。

③以回车最为输入结束。5.6.3字符串处理函数用于输入输出的字使用其它字符串函数应包含头文件"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);

结果在函数的返回值中,可以赋值给其他变量。使用其它字符串函数应包含头文件"string.h"。3.字符5.7指针数组与多级指针变量5.7.1指针数组概念:指针数组是一个数组,该数组中的每一个元素是指针变量。定义:

类型标识符*数组名[数组元素个数];例如:int*p[4];

定义一个指针数组,数组名p,有4个元素,每一个元素是指向整型变量的指针。注意与指向数组的指针变量的区分:int(*p)[4]定义一个指针变量,它指向有4个元素的一维数组。5.7指针数组与多级指针变量5.7.1指针数组

指针数组的用途:处理多个字符串。先来看使用二维数组存放多个字符串:

charch[][16]={"Followme","BASIC","GreatWall","FORTRAN","ComputerDesign“}使用二维数组处理浪费较多内存。指针数组的用途:处理多个字符串。先来看使用二维数组存放多个使用指针数组char*pc[]={"Followme","BASIC","GreatWall","FORTRAN","ComputerDesign"};说明:pc是一维数组,里面存放着5个指向字符型变量的指针。pc[0]pc[1]pc[2]pc[3]pc[4]Followme\0BASIC\0Great

Wall\0FORTRAN\0ComputerDesign\0使用指针数组char*pc[]={"Followme例将若干字符串按字母顺序输出。#include"stdio.h"#include"string.h"voidmain(){char*temp;inti,j,k,n=5;char*pc[]={"Followme","BASIC","GreatWall","FORTRAN","ComputerDesign“};例将若干字符串按字母顺序输出。#include"stdfor(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(pc[k],pc[j])>0)k=j;

temp=pc[i];pc[i]=pc[k];pc[k]=temp;}for(i=0;i<n;i++)printf("%s\n",pc[i]);}

if(k!=i){}for(i=0;i<n-1;i++)if(k!=5.7.2指向指针的指针

用于存放某个指针变量地址的指针变量被称为指向指针的指针,定义形式如下:类型名**变量名;例:

int**p;

例:intx,*pc,**p;

x=5;pc=&x;p=&pc;5xpc&xp&pc5.7.2指向指针的指针用于存放某个指针5.8应用程序举例5.8.2数据查找1.顺序查找法36845129710a[0]a[1]…………a[9]4x用循环结构比较:xVsa[i](循环变量i最大为9)还有一个循环结束的条件:找到了:x=a[i]5.8应用程序举例5.8.2数据查找3684512971#defineN10voidmain(){inta[N]={12,34,1,3,67,89,28,61,9,87};intindex,x,i;printf("inputthenumber:\n");scanf("%d",&x);for(i=0;i<N;i++)if(x==a[i])break;if(i>=N)printf(“Notfound!\n");elseprintf(“ItistheNO.%d!\n",i);}思考:如果数据中有相同的数据,要求将所有数据都查找出来,如何修改?5-10.c#defineN10思考:如果数据中有相同的数据,要求将2.折半查找法(只能对有序数列进行查找)124910152635363954596871757779959699bottopmid=(bot+top)/2比较:xVsa[mid]的情况①x=a[mid]则找到②x<a[mid]则到前半部分找,则bot不变,top=mid-1③x>a[mid]则到后半部分找,则top不变,bot=mid+126xtopbotmid循环结束的条件:①找到了:x=a(mid)②bot>top25bottopmidbottopmid此时bot=top=mid而x>a(mid)则bot=mid+1则bot>top0123456789101112131415161718192.折半查找法(只能对有序数列进行查找)1249101526#defineN10voidmain(){inta[N]={1,4,7,13,16,19,28,36,49,60};intmid,bot,top,x,i;scanf("%d",&x);bot=0;top=N-1;while(bot<=top){mid=(top+bot)/2;if(x==a[mid])break;elseif(x<a[mid])top=mid-1;elsebot=mid+1;}if(bot>top)printf("Notfound!\n");elseprintf("ItistheNO.%d!\n",mid);5-11.c#defineN105-11.c5.8.3插入法12561016254895994x①确定插入的位置p:for(p=0;p<n;p++)if(x<a[p])break;p0100a[0]a[1]…………a[9]②移位和插入for(i=n;i>p;i--)a[i]=a[i-1],a[p]=x;

5.8.3插入法12561016254895994x①确此时q为最后一个元素地址①确定插入的位置p:for(p=0;p<n;p++)if(x<a[p])break;②移位和插入for(i=n;i>p;i--)a[i]=a[i-1],a[p]=x;下标法:intp;①确定插入的位置:for(p=a;p<q;p++)if(x<*p)break;②移位和插入for(q=a+N;q>p;q--)*q=*(q-1),*p=x;指针法:int*p,*q;此时q为最后一个元素地址①确定插入的位置p:②移位和插入下5.8.4字符串的处理1.简单加密和解密2.统计文本单词的个数5.8.4字符串的处理1.简单加密和解密[工学]《C语言程序设计》第5章___数组、字符串、指针课件第5章数组、字符串、指针第5章数组、字符串、指针本章要求:1、掌握C语言数组在内存中的存储形式2、掌握一维数组和二维数组的定义及使用3、掌握使用指针处理数组的方法4、掌握使用字符数组及指针处理字符串数据的方法5、掌握与数组有关的基本算法(如排序、查找、插入、删除等)的程序设计本章要求:1、掌握C语言数组在内存中的存储形式重点:一维数组、二维数组的定义与使用方法,使用指针访问数组和字符串的方法。难点:二维数组与指针;与数组有关的常用算法(排序、查找与插入等)。重点:5.1数组概述例.输入10个数,求出他们的平均数。main(){intn,a,s=0;floatave;for(n=1;n<=10;n++){scanf(“%d”,&a);

s=s+a;

}ave=s/10;printf(“Ave=%d\n”,ave);

}并打印出其中大于平均数的数a

变量a中只能存放一个整数

需要10个变量的内存空间才可以保留10个整数5.1数组概述例.输入10个数,求出他们的平均数。并如果使用:a1,a2,a3,a4,a5,a6,a7,a8,a9,a10这10个变量,代码:intn,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;floatave;scanf(“%d%d%d%d%d%d%d%d%d%d”,

&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,

&a10);s=a1+a2+a3+a4+a5+a6+a7+a8+a9+a10;ave=s/10;if(a1>ave)printf(“%d”,a1);

if(a2>ave)printf(“%d”,a2);

if(a3>ave)printf(“%d”,a3);………..

/*实际程序是不能这样写*/如果使用:a1,a2,a3,a4,a5,a6,a7,a8,a思考:发现:如果不是10个数,而是100,1000,甚至是10000,此时按上面方法编写程序就非常冗长。

如果可以使用循环来编写,程序可以简洁许多。要使用循环:必须使用ai(i=1,2…10)的形式来代表a1,a2…a10在C语言中使用“数组”来实现:a[i]a[0]a[1]…a[9]思考:发现:如果不是10个数,而是100,1000,甚至是1#include<stdio.h>voidmain(){intn,i;

floats=0,ave,a[10];

for(i=0;i<10;i++){scanf("%f",&a[i]);s=s+a[i];}ave=s/10;for(i=0;i<10;i++)if(a[i]>ave)printf("%f",a[i]);}声明有10个元素的一维数组aa[0]a[1]…a[9]a[i]a[i]a[i]a[i]#include<stdio.h>声明有10个元素的一维数在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。在C语言中,数组属于构造数据类型。按类型分为:数值数组、字符数组、指针数组、结构数组等按维数可分为:一维数组、二维数组、多维数组。数组在内存中占用一片连续的存储单元在程序设计中,为了处理方便,把具有相同类型的若干变量按有序5.2一维数组只有一个下标变量的数组,称为一维数组。

5.2.1一维数组定义

一般形式为:

类型符数组名[常量表达式];

其中:类型说明符是任一种基本数据类型或构造数据类型,数组名是用户定义的标识符;方括号中的常量表达式表示数据元素的个数,也称为数组的长度。5.2一维数组只有一个下标变量的数组,称为一维数组。例如:inta[10];floatb[10],c[20];charch[20];

数组在内存中占据一片连续的存储空间:

以inta[5]为例,在内存中为:a[0]a[1]a[2]a[3]a[4]相当于声明了5个整型变量例如:a[0]a[1]a[2]a[3]a[4]相当于声明了5说明:数组的所有元素的数据类型都是相同的。数组取名规则应符合标识符的规定,数组名不能与同一函数中其它变量名相同:

inta;floata[10];

是错误的。C语言中规定数组的下标从0开始,方括号中常量表达式表示数组元素的个数。不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。例如:intn=5,a[n];

是错误的。说明:数组的所有元素的数据类型都是相同的。5.2.2一维数组的初始化1、数组声明时初始化

在编译阶段进行的。这样将减少运行时间,提高效率。数组初始化的一般形式为:

类型符数组名[常量表达式]={值,值…值};例如:inta[10]={0,1,2,3,4,5,6,7,8,9};

相当于a[0]=0;a[1]=1;...a[9]=9;

5.2.2一维数组的初始化1、数组声明时初始化

说明:inta[10]={0,1,2,3,4};inta[10]=1;staticinta[3];inta[]={1,2,3,4,5};inta[5]={1,2,3,4,5,1};给前5个元素赋值,其余赋0值不能给数组整体赋值,改成{1}可以省略数组元素个数。静态存储类型,初值为0初值的个数不能超过元素个数说明:inta[10]={0,1,2,3,4};给前5个元2、使用赋值语句初始化

用赋值语句初始化是在程序执行过程中实现的。例如:inta[3];a[0]=5;a[1]=8;a[2]=9;对于数组的元素用赋值语句初始化,常常使用循环来完成,例如:intk,a[10];for(k=0;k<10;k++)a[k]=1;/*对数组中所有元素赋初值为1*/2、使用赋值语句初始化用赋值语句初始化是在程序执行过5.2.3数组元素的引用

数组元素是组成数组的基本单元,数组元素可以看成一种变量。引用数组元素有下标法和指针法。本小节介绍下标法,指针法将在5.5节中介绍。使用下标法引用一维数组元素的一般形式为:

数组名[下标]

其中,的下标只能为整型常量或整型表达式。若为小数时,C编译将自动取整。5.2.3数组元素的引用数组元素是组成数组的基本单说明:intn=3,a[10];

a[n]=5;a[n+1]=10;inta[10],x,y;

a[10]=5;inta[10];

printf("%d",a);

正确代码。引用数组元素的时候,可以用变量。错误代码。最大下标为9,没有a[10]元素。错误代码。不能用一个语句输出整个数组。说明:intn=3,a[10];

a[n]=5;a[n+5.2.4一维数组的基本操作可通过循环给数组元素输入数据

inta[10],i,;for(i=0;i<10;i++)scanf(“%d”,&a[i]);也可通过循环输出数组元素

for(i=0;i<10;i++)printf(“%d”,a[i]);例,输入5个数,再按倒序输出5-1.c5.2.4一维数组的基本操作可通过循环给数组元素输入数据求数组中最大元素#defineN10main()

{inti,p,max,a[N];printf("Enter%dNumbers\n",N);for(i=0;i<N;i++)scanf("%d",&a[i]);max=a[0];for(i=1;i<N;i++)if(a[i]>max)max=a[i];printf("TheMax=%d\n",max);}p=0;a[%d]=%d\n",p,max);{p=i;}及其下标求最大、最小值以及排序算法中的最大、最小值确定都可以采用类似方法:把第一个元素假想为当前找到的最大、最小值,在后续的比较中进行更新。5-2.c求数组中最大元素#defineN10p=0;a[%d]一维数组的倒置for(i=0;i<N/2;i++){t=a[i];a[i]=a[N-i-1];a[N-i-1]=t;}002468135791924681357029746813520397568134204975381642059753186420a[0]a[1]…a[9]类似问题:字符串的回文比较5-3.c一维数组的倒置for(i=0;i<N/2;i++)00245.2.5一维数组的应用举例例:如果要统计0~9,10~19,20~29,….80~89,90~99分数段及100分的人数。

编程分析:a数组用来存放20个学生成绩;另用数组bn来存各分数段的人数:bn[0]存0~9分的人数,bn[1]存10~19分的人数,…bn[9]存90~99分的人数,bn[10]存100分的人数。5-4.c5.2.5一维数组的应用举例例:如果要统计0~9,10~一维数组的应用举例:

5.8.1排序问题(教材P.166)数据的排序就是将一批数据由小大到(升序)或由大到小(降序)进行排列。常用的有选择法、冒泡法。首先要将需要排序的数据放到数组中,这样,便于我们排序。一维数组的应用举例:

5.8.1排序问题(教材P.166)1.选择法排序算法描述:从剩下的元素集中找一个最小的元素依次放到第i个位置。i从0开始原始数据:869327第一轮后:269387第二轮后:239687第三轮后:236987第四轮后:2367

89第五轮后:236789a[0]a[1]a[2]a[3]a[4]a[5]8693276个数需要经历5轮选择(i=0~4)每一轮做的工作:从第i个到最后一个中找一个最小的。与第i个交换。放到a[i]这个位置。1.选择法排序算法描述:从剩下的元素集中找一个最小的元素依次代码:for(i=0;i<5;i++){p=i;for(j=i+1;j<6;j++)if(a[j]<a[p])p=j;t=a[i];a[i]=a[p];a[p]=t;}i<N-1;i<N;

从第i个到最后一个中找一个最小的。与第i个交换。6个数需要经历5轮选择(i=0~4)5-5.c代码:for(i=0;i<5;i++)i<N-1;2.冒泡法排序(升序)算法描述第一轮:8693268932689326839268329①②③④

683296382963289①②③第二轮:5个数共4轮即可…2.冒泡法排序(升序)算法描述86666①②代码:

for(i=0;i<4;i++)for(j=0;j<4-i;j++)if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}i<N-1;i<N-i-1;每轮需要经过4-i次比较发现前面的数比后面的数大则需要交换,把大的换到后面去。5个数需要经历4轮选择(i=0~3)5-6.c代码:for(i=0;i<4;i++)i<N-5.3二维数组与多维数组5.3.1二维数组的声明二维数组说明的一般形式是:

类型符数组名[常量表达式1][常量表达式2];其中:常量表达式1表示第一维下标的长度常量表达式2表示第二维下标的长度。例如:inta[3][4];

floatb[4][4];

charc[5][10];

5.3二维数组与多维数组5.3.1二维数组的声明inta[3][4];

该数组的下标变量共有3×4个,即:a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]…a[2][3]二维数组在内存的存放顺序是“先行后列”注意:C语言允许二维数组a[3][4]可分解为三个一维数组,其数组名分别为a[0],a[1],a[2]。这三个一维数组都有4个元素。inta[3][4];该数组的下标变量共有3×4个,即:5.3.2二维数组元素的引用二维数组的元素的引用形式为:

数组名[下标][下标]使用二维数组的情况举例:学生多门功课的成绩,如:

a[100][3]可以用来记录100个学生3门功课的成绩。矩阵,如:

a[3][3]可以用来记录3×3的矩阵。一个数组元素正好存放一个矩阵的元素。5.3.2二维数组元素的引用二维数组的元素的引用形式为:5.3.3二维数组的初始化

二维数组初始化也是在类型说明时给各下标变量赋以初值。1.按行分段赋值可写为

int[5][3]={{80,75,92},{61,65,71},

{59,63,70},{85,87,90},{76,77,85}};

2.按行连续赋值可写为

inta[5][3]={80,75,92,61,65,71,59,63,

70,85,87,90,76,77,85};

注意:这两种赋初值的结果是完全相同的。5.3.3二维数组的初始化二维数组初始化说明:inta[3][3]={{1},{2},{3}};inta[][3]={1,2,3,4,5,6,7,8};100200300123456780说明:inta[3][3]={{1},{2},{3}};15.3.4二维数组的基本操作二维数组的操作一般需要使用二重循环。1.二维数组的输入输出

设数组己定义

inta[N][M];

其程序段如下:for(i=0;i<N;i++)for(j=0;j<M;j++)scanf(“%d”,&a[i][j]);for(i=0;i<N;i++){for(j=0;j<M;j++)printf(“%d”,a[i][j]);printf(“\n”);}5.3.4二维数组的基本操作二维数组的操作一般需要使用二重2.求最大元素及其所在的行和列

编程基本思路与在一维数组求最大值元素相同,row,column存放最大值所在行列号。3.矩阵的转置(方阵)对比一维数组的倒置,注意:哪些元素要交换?和谁交换?a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[3][0]a[3][1]a[3][2]a[3][3]

如果不是方阵,则要定义另一个数组。b[j][i]=a[i][j]2.求最大元素及其所在的行和列编程基本思路与在一维数5.3.6多维数组的声明和引用

在处理三维空问题等其它复杂问题时要使用到三维及三维以上的数组,通常把三维及三维以上的数组称为多维数组。定义多维数组的格式如下:

类型符数组名[常量1][常量2][常量3]…;例如:inta[5][5][5];/*声明a是三维数组*/floatb[2][6][10][5];/*声明b是四维数组*/注意:操作多维数组常常要用到多重循环。5.3.6多维数组的声明和引用在处理三维空问题等2.6指针变量

2.6.1地址与指针的概念

数据存放在内存中,每个字节内存单元按顺序编号,称为“内存地址”。通过内存单元的地址即可准确地找到该内存单元。变量的地址就是变量的指针5x2003变量名变量值变量地址p指针变量2.6指针变量

2.6.1地址与指针的概念数据存放2.6.3指针变量的定义

指针变量定义的一般形式:

类型符*标识符;说明:

温馨提示

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

评论

0/150

提交评论