C语言-数组教程_第1页
C语言-数组教程_第2页
C语言-数组教程_第3页
C语言-数组教程_第4页
C语言-数组教程_第5页
已阅读5页,还剩125页未读 继续免费阅读

下载本文档

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

文档简介

C语言-数组教程数组的定义和初始化

数组的赋值、输入和输出

字符数组

向函数传递一维数组和二维数组常用算法:排序、查找、求最大最小值等使用字符串处理函数处理字符串C的数据类型:

◎基本类(简单类)—字符型/整型/实型/枚举型◎构造类(组合类)—数组/结构体/共用体◎指针类◎空类型(void)元素编号从0开始,a[0]表示第1个元素,a[4]表示第5个元素(最后一个)对于变量基本类型——单个出现的变量,每个变量可以代表一个确定的数据(变量值)如intx,y;但变量间不存在确定的相互关系。构造类型——由基本类型按一定规则组成。其中:数组:由一组有序数据(数组元素)组成。每个元素:有相同类型,统一数组名;用下标确定其顺序;但可以取各自值。

如inta[5];

其中:[]表示a是个数组,而不是一个简单变量a。

5表示该数组共有5个元素数组的用处很多。简单例子:要读入某班全体50位同学某科学习成绩,然后进行简单处理(求平均成绩、最高分、最低分……)若用简单变量,需50个不同变量名,要用很多个scanf命令。如

intscore1,score2,…score50;scanf(“%d,%d,%d”,&score1,&score2,&score3);scanf(“%d,%d,%d”,&score4,&score5,&score6);而用数组,可共用一个scanf命令,并利用循环结构读取。

intscore[50],i;for(i=0;i<50;i++)scanf(“%d”,&score(i));数组是一组有序的同类型数据。数据称为数组的元素。数组保存大量同类型的相关数据如矩阵运算,表格数据等

数组的用处快速地随机访问一旦定义,不能改变大小数组的特点数组的定义:数组在使用前要进行定义:名称、类型、维数、大小定义格式:

其中:(1)常量表达式可为常数、符号常数。但不包含变量,值必须是大于0的整数。(2)表达式的个数表明数组的维数。类型标识符数组名[常量表达式1][常量表达式2]……§6.1数组的定义与初始化如:inta[10];floatb[15];charc[30];×

inta[0][3];inti=3,j=4;inta[i][j];×

数组元素的引用:

数组元素是通过数组名加上该元素在数组中的位置(下标)来访问的。

引用格式:数组名[表达式]说明:1、下标从0开始。如:数组A[n]的元素个数为n。下标取值范围是0——n-1.2、数组名代表该数组在内存中的首地址。因此可用数组名代表数组中0号元素的地址。

数组的存储结构:数组一经定义,系统则根据数组的数据类型为每一个元素安排相同长度的、连续的存储单元。同时根据其存储类型确定将其安排在内存数据区或寄存器。①一维数组:从左到右顺序存放。

如有数组inta[5];其中数据为:2、4、23、6、78则存放情况如下:

……..

4的高位字节4的低位字节2的高位字节2的低位字节20002002200420062008a[0]a[1]a[2]a[3]a[4]数组在内存中的首地址即a=2000inta[5]={2,4,23,6,78};

a00

a01…….

a0n-1

a10

a11……..

a1n-1……….

am-10

am-11……..

am-1n-1②二维数组:按行的顺序存放。

200020022004……….

am-10am-11……am-1n-1

a00a01……..a0n-1

a10a11……..a1n-1

….

按行优先顺序存放A[m][n]=则存放情况如下:若有数组b[2][3];其中数据为:111213

212223

111213212223

b[0][0]b[0][1]b[0][2]b[1][0]b[1][1]b[1][2]

200020022004……二维数组可看成数组的数组A=(s0,

s2,

……..

,

sm-1)(0<=i<=m-1)

a00a01……..a0n-1

a10a11……..a1n-1

am-10am-1……..am-1n-1

….A[m][n]=

s0……..

sm数组的初始化定义数组时把数据赋予该数组。(用一对大花括号括起来)intdata[10]={50,30,82,12,23,34,123,55,567,10};说明:(1)若初始化列表中初值个数少于数组元素个数,则自动以0补充。1、一维数组的初始化(3)可隐含定义数组大小。如:inta[]={0,1,2,3,4,5,0};

注:初始化列表中必须列出全部初值(4){}号中的初值可以省略,但逗号不能省,缺省的部分被视为0。如:floatarray[5]={,2,3,4,};(2)若初始化列表中初值个数多于数组元素个数,则给出错误信息。2、二维数组的初始化如:inta[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};等效于:inta[4][3]={1,2,3,4,5,6,7,8,9,10,11,12};将全部的值放在一对{}中(以行为准)。每一行的数据又可以分别放在一对{}号中。(1)可以对数组进行部分初始化,未初始化部分自动清0。(注:不能省略对数组长度的说明)比较下面两种初始化情况,有何不同:inta[2][3]={{5,6},{7,8}};与inta[2][3]={5,6,7,8};(2)可以省略第一维长度,但第二维长度不可省略。如:inta[][4]={{1,2,3,4},{5,6,7,8}};说明:数组的赋值:数组的赋值不同于数组初始化。只能对数组元素进行赋值而不能对数组名实施整体赋值。赋值的方法:(1)无规律的,各元素分别赋值。(2)有规律的,利用循环进行赋值。一维数组用单循环、二维数组用双重循环即可。§6.2数组的赋值、输入和输出数组常用的循环形式法一inti,a[100];for(i=0;i<100;i++)a[i]=i;法二inti,a[100];for(i=0;i<=99;i++)a[i]=i;C程序中常用的是第一种方法。此法中,循环变量的终值是“小于”而非“等于”数组长度!否则将导致“越界”的发生。例1:inta[5],i;for(i=0;i<5;i++)a[i]=(i+1)*100;×

inta[5],i;a={100,200,300,400,500};不可写成:/*错误编程*/main(){inta[4]={1,2,3,4],b[4];a=b;}解决方法法1:逐个元素赋值

b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];法2:通过循环赋值

inti;for(i=0;i<4;i++)b[i]=a[i];原因:数组名表示数组的首地址,其值不可改变!如何使两个数组的值相等:应用示例:下列程序的功能是显示如下图形,请填空。1000021000321004321054321main(){inta[5][5],i,j;

for(i=0;i<5;i++){for(j=0;j<5;j++){if(

【1】

)a[i][j]=0;elsea[i][j]=【2】;printf("%3d",a[i][j]);}printf("\n");}}【分析】这类题的元素值排列很有规律,一般要从分析行列数i、

j与元素值的关系着手.当i<j

时的各元素值均为0;而i>=j时,元素值随行数i增加而增加,随列数j

增加而减小,这样就很容易得出其元素值与i,j

的关系是i+1-j。1000021000321004321054321a[5][5]分析:a00a01a02a03a04a10a11a12a13a14a20a21a22a23a24a30a31a32a33a34a40a41a42a43a44main(){inta[5][5],i,j;

for(i=0;i<5;i++){for(j=0;j<5;j++){if(

【1】

)a[i][j]=0;elsea[i][j]=【2】;printf("%3d",a[i][j]);}printf("\n");}}i<ji+1-ja[5][5]分析:a00a01a02a03a04a10a11a12a13a14a20a21a22a23a24a30a31a32a33a34a40a41a42a43a441000021000321004321054321矩阵运算

【例】有一3×4矩阵,编程求其元素最大值并输出其行、列号。main(){inti,j,x,y,max;inta[][4]={3,5,8,1,6,9,7,12,-6};

max=a[0][0];for(i=0;i<3;i++)for(j=0;j<4;j++)if(a[i][j]>max){max=a[i][j];x=i;y=j;}printf("maxisa[%d][%d]=%d\n",x,y,max);}358169712-6000要点:用两重循环遍历所有元素。【讨论】如果求最小值?例2:建立一个2*3的数组b,要求其各元素值是行、列下标之和。注意:条件判断时不可写成i<=2、j<=3,这样将造成下标超界。intb[2][3],i,j;for(i=0;i<2;i++)for(j=0;j<3;j++)b[i][j]=i+j;只能逐个对数组元素进行操作(字符数组例外)输入方法:inta[10],i;输入第i个数组元素:scanf("%d",&a[i]);输入整个数组元素:for(i=0;i<10;i++)scanf("%d",&a[i]);输出方法:输出第i个数组元素:printf("%d",a[i]);输出整个数组元素:for(i=0;i<10;i++)printf("%d",a[i]);一维数组的输入和输出兔子生崽问题1,2,3,5,8,13,21,34,55,89,144,233,…

一维数组的应用——例6.1#include<stdio.h>#defineYEAR_MONTH12main(){

intf[YEAR_MONTH+1]={0,1,1};

intmonth;

for(month=3;month<=YEAR_MONTH;month++) { f[month]=f[month-1]+f[month-2]; }

for(month=1;month<=YEAR_MONTH;month++) {

printf("%d\t",f[month]); }

printf("\nsum=%d\n",f[YEAR_MONTH]);}例6.1例6.2从键盘输入某班学生一门课的成绩(人数不超过40人),打印出最高分及其学生学号从键盘输入学生人数n;从键盘输入所有学生的学号和成绩分别存入数组num和score假设其中的一个学生成绩为最高,同时记录其学号,即令

maxScore=score[0] maxNum=num[0];对所有学生成绩进行比较,即

for(i=0;i<n;i++){

若score[i]>maxScore, 则修改maxScore值为score[i], 并记录其学号maxNum=num[i];

}打印最高分maxScore及其学号maxNum;#include<stdio.h>#defineARR_SIZE40main(){

floatscore[ARR_SIZE],maxScore;

intn,i;

longmaxNum,num[ARR_SIZE];

printf("Pleaseentertotalnumber:");

scanf("%d",&n);

printf("Pleaseenterthenumberandscore:\n");

for(i=0;i<n;i++) {

scanf("%ld%f",&num[i],&score[i]); } maxScore=score[0]; maxNum=num[0];

for(i=1;i<n;i++) {

if(score[i]>maxScore) { maxScore=score[i]; maxNum=num[i]; } }

printf("maxScore=%.0f,maxNum=%ld\n",maxScore,maxNum);}数组的输出#include<stdio.h>main(){inti,a[10]={1,2,3,4,5,6,7,8,9,10};for(i=0;i<10;i++){printf("

%2d",a[i]);if(i==4||i==9)printf("\n");}}例:将含有10个元素的a数组分两行输出。例2:按矩阵形式输出二维数组b[3][4](部分程序):for(i=0;i<3;i++){for(j=0;j<4;j++)printf("%6.2f",b[i][j]);printf(“\n”;)}..数组定义后的初值仍然是随机数,一般需要我们来初始化inta[5]={12,34,56,78,9};inta[5]={0};inta[]={11,22,33,44,55};数组大小最好用宏来定义,以适应未来可能的变化#defineSIZE10

inta[SIZE];数组大小定义好后,将永远不变总结——关于数组数组的下标都是从0开始对数组每个元素的使用与普通变量无异可以用任意表达式作为下标,动态决定访问哪个元素for(i=0;i<SIZE;i++)

a[i]=2*i;下标越界是大忌!使用大于最大下标的下标,将访问数组以外的空间。那里的数据是未知的,可能带来严重后果sizeof可以用来获得数组大小关于数组讨论:

如果下标值小于0或超过数组长度时会出现什么情况?例:main(){inta=1,b[5],c=2,i;for(i=0;i<=5;i++)b[i]=i+1;……}运行程序或单步执行观察变量变化情况可以看到,变量c的值因数组越界而被悄悄破坏了(可能产生严重的错误后果!)1234560123456数组名做函数参数1、传址方式:实参将自己的地址传递给形参,可理解为实参与形参共用一个地址单元。因此,对形参的操作就是对实参的操作2、传值方式:系统将实参中的数值复制一份给形参,实参与形参分别有各自的存储单元,被调过程中的操作是在形参自己的存储单元中进行,过程调用结束后,形参的存储单元被系统回收。回顾:函数参数传递的两种方式

用数组名作参数,就是将数组的首地址传递给函数实参数组与形参数组占用同一段内存在函数中对形参数组元素修改的结果,会影响主调函数中的实参数组数组名做函数参数简单变量作函数参数

数组作函数参数

数组名做函数的实参和形参在主调函数和被调函数中分别定义数组。实参数组和形参数组类型应一致。实参数组和形参数组大小不一定一致,形参数组可以不指定大小,但形参数组名后面的方括号不能省略。

由于数组名代表数组的起始地址,故数组名做函数的实参和形参时不是“值传递”,而是“地址传递”。因此,形参数组各元素的值如果发生变化,会使实参数组各元素的值发生同样的变化。1、传值10

实参a20实参b

只是x,y的值互换10形参x20形参yx形参y2010形参x子函数内部main(){…….inta=10,b=20;jh(a,b);……..}jh(intx,inty){intz;z=x;x=y;y=z;}2、传址

1020

p[0]p[1]

a[0]a[1]

起始地址ffd4main(){…….inta[2]={10,20};jh(a);……..}ffd4实参数组名a形参数组名pffd4jh(intp[]){intz;z=p[0];p[0]=p[1];p[1]=z;}2010p[0]p[1]20p[0]10p[1]函数体内一维数组名做函数参数(传址方式)例:现有两个整数,编写一个函数实现二者交换分别用传值和传址两种方式实现见实例jh1.c,jh2.cmain()jh1.c{inta=10,b=20;printf("theadressofais:%x\n",&a);printf("theadressofbis:%x\n",&b);printf(“beforeexchangea,bis:a=%d,b=%d\n",a,b);jh(a,b);printf(“afterexchangea,bis:a=%d,b=%d\n",a,b);}jh(intx,inty){intz;printf("theadressofxis:%x\n",&x);printf("theadressofyis:%x\n",&y);printf(“beforeexchangex,yis:x=%d,y=%d\n",x,y);z=x;x=y;y=z;printf(“afterexchangex,yis:x=%d,y=%d\n",x,y);}main()

jh2.c{

inta[2];a[0]=10;a[1]=20;printf("theadressofais:a=%x\n",a);printf(“beforeexchange:a[0]=%d,a[1]=%d\n",a[0],a[1]);jh(a);printf(“afterexchange:a[0]=%d,a[1]=%d\n",a[0],a[1]);}jh(intp[]){intz;printf("theaddresofpis:p=%x\n",p);z=p[0];p[0]=p[1];p[1]=z;printf("p[0]=%d,p[1]=%d\n",p[0],p[1]);}数组作函数参数1号2号swap(intx,inty){intp;p=x;x=y;y=p;}main(){inta,b;scanf(“%d,%d”,&a,&b);

if(a<b)swap(a,b);printf(“%d,%d\n”,a,b);}交换形参变量值普通变量作函数参数运行情况:5,95,9普通变量作函数参数1号2号3号4号#include<stdio.h>#defineARR_SIZE40floatFindMax(floatarr,intn);main(){

floatscore[ARR_SIZE],maxScore;

intn,i;

printf("Pleaseentertotalnumber:");

scanf("%d",&n);

printf("Pleaseenterthescore:\n");

for(i=0;i<n;i++) {

scanf("%f",&score[i]); } maxScore=FindMax(score,n);

printf("maxScore=%.0f\n",maxScore);}floatFindMax(floatarr[],intn){

floatmax;

inti;

max=arr[0];

for(i=1;i<n;i++) {

if(arr[i]>max)max=arr[i]; } returnmax;}例—打印出最高分一维数组名做函数参数二维数组名做函数参数voidTotal(int

score[][COURSE],

intsum[],

floataver[],intn){

inti,j;

for(j=0;j<COURSE;j++) { sum[j]=0;

for(i=0;i<n;i++) { sum[j]=sum[j]+score[i][j]; } aver[j]=(float)sum[j]/n; }}例6.7、6.8计算总分和平均分设有矩阵1234要求编程实现:

5678(1)将其存入数组(2)并以以下矩阵形式15存入另一数组

263748(3)分别输出两数组例1、定义数组a[2][4]、b[4][2]2、将数据送入a数组3、根据数据排列的情况将a数组数据赋予b数组

a、b数组间关系为:

a的行=b的列

a的列=b的行

b[j][i]=a[i][j]4、分别输出a、b数组数据问题分析:main(){inta[2][4]={1,2,3,4,5,6,7,8},b[4][2],i,j;for(i=0;i<2;i++){for(j=0;j<4;j++)printf("%4d",a[i][j]);printf("\n");}for(i=0;i<2;i++){for(j=0;j<4;j++){b[j][i]=a[i][j];}printf("\n");}for(j=0;j<4;j++){for(i=0;i<2;i++)printf("%4d",b[j][i]);printf("\n");}}例:设有矩阵0123451234562345673456784567895678910(1)将矩阵存入一个二维数组要求:(2)将二维数组中的数据送入一个一维数组(3)分别输出两个数组问题分析:1、定义数组2、将数据送入a数组

a[6][6]、b[36]

b[k]=a[i][j]4、分别输出a、b数组数据3、将a数组数据赋予b数组a数组的数据可自动生成

a[i][j]=i+j

for(i=0;i<36;i++)

main()

inta[6][6],b[36];

for(i=0;i<6;i++)for(j=0;j<6;j++)

printf(“\n”);{}printf(“%d”,b[i]);

inti,jk=0;K++;}{{}a[i][j]=i+j;b[k]=a[i][j];printf(“%d\t”,a[i][j]);

printf(“\n”);§6.3字符数组

字符数组是每个元素存放一个字符型数据的数组。字符数组的定义形式和元素的引用方法与一般数组相同。

说明:C语言中没有专门的字符串变量,因此利用字符型数组来处理字符串。3.字符串常量是用双引号包围的字符序列。如:

“china”,作为字符串的结束标志的‘\0’可以不显式写出.2.C语言中约定用‘\0’作为字符串的结束标志,它占内存空间,但不计入串的实际长度。即“china”

“china\0”两种用法:(1)作为字符(单个字符操作)(2)作为字符串(整体操作)一、字符数组的初始化The\0\0【注意】如果初值个数小于数组长度,则多余的数组元素自动为空字符(’\0’)

charrat[5]={‘T’,‘h’,‘e’,‘

’};1、用字符型数据对字符数组初始化2、用字符串常量对字符数组初始化

charpanic[6]={"HELLO"};HELLO\0注意:数组中的字符除了H,E,L,L,O之外,系统自动加入结束标志‘\0’。为了用一个字符数组来存储长度为N的字符串,要求字符数组的大小至少为N+1.初始化时也可省略花括号。

charpanic[]="HELLO";×

HELLO\0系统自动加入下面的初始化是错误的:charneg[5]="doublearrow";【例】比较以下字符数组长度是否相同:

chara[]=”ABCD”;charb[]={“ABCD”};charc[]={‘A’,’B’,’C’,’D’};字符常量与字符串常量的区别

字符常量字符串常量

单引号双引号1个字符多个字符字符变量字符数组一个字节

字符串中字节数+1(\0结束标志)

引用形式:存放内容:赋值对象:占用空间:例如:‘a’“a”不同1个字节2个字节

回顾——应用举例:例1:作为普通数组处理

main(){charary1[10]={‘P’,’L’,’O’,’T’},ary2[10];charch;inti,j;for(i=0;i<4;i++)printf(“%c”,ary1[i]);

printf(“请输入一行字符\n”);for(i=0;i<10;i++){scanf(“%c”,&ch);if(ch==‘\n’)break;ary2[i]=ch;}for(j=0;j<i;j++)printf(“%c”,ary2[j]);}例2:作为字符串处理

main(){charary1[10]=“PLOT”,ary2[10];printf(“%s”,ary1);printf(“请输入一行字符\n”);scanf(“%s”,ary2);printf(“%s”,ary2);}注意:Printf、scanf处理字符串数组时可使用数组名作为函数参数。对于一个二维数组,C编译程序将其视为一个一维数组,这个一维数组中每个元素又是一个一维数组。这一概念对字符型数组仍适用。3、二维字符数组的初始化aa\0\0bbb\0c\0\0\0charch[3][4]={″aa″,″bbb″,″c″};第一维的长度代表要存储的字符串的个数,可以省略。第二维的长度不能省略,且应按最长的字符串长度设定二、字符数组的输入输出1、按C格式符一个字符一个字符地单独输入输出例:main(){inti;charstr[10];for(i=1;i<10;i++)scanf(“%c”,&str[i]);for(i=1;i<10;i++)printf(“%c”,str[i]);}2、按S格式符将字符串作为一个整体输入输出①用scanf函数加%s实现字符串输入注意:(1)输入的字符串中不能有空格、回车或跳格符(Tab),因为系统遇到这些分隔符时,会认为输入结束。上例中若输入:helloworld则实际存入str的只有"hello"例如:charstr[10];scanf("%s",str);②用printf函数加%s实现字符串输出

printf("%s",str);(2)要保证字符数组的长度足够大。(3)数组名前不用加&符号,因为数组名本身代表该数组的首地址。数组名【例】下列程序段的运行结果是:

chara[5]={‘a’,’b’,’\0’,’d’,’\0’};printf(“%s”,a);说明:%s的作用是输出一个字符串,直到遇到’\0’为止。3、用字符串处理函数gets或puts输入输出一个字符串

gets()函数——专门用于输入字符串一般形式是:gets(字符数组名);

其中:函数参数只能使用数组名而不能是字符串常量与scanf函数的不同是:

gets()函数将用户键入的换行符之前的所有字符(包括‘\t’和‘’)存入字符数组,然后加上‘\0’,但换行符被丢掉与scanf函数相同的是:

gets()函数也不检查用户输入字符串长度是否超过了字符数组的容纳能力,因此编程者要确保数组足够大。gets()函数——#include<stdio.h>/*必须加上*/#defineLATH80main(){charname[LATH];printf("你好,请输入姓名:\n");gets(name);printf("真是个好名字:%s\n",name);}例:#include<stdio.h>#defineLEN80main(){charname1[LEN];printf(“请输入一个姓名:\n");scanf("%s",name1);printf("读入的名字是%s\n",name1);}输入:于航输出:于1.输入多个数据时,格式控制串中没有非格式字符,则输入时数据间的分隔符可用空格、TAB键、回车键。

2.输入字符数据时,若格式控制符中无非格式符,则认为所有输入的字符均为有效字符。

scanf(“%c%c%c”,&a,&b,&c);printf(“a=%c,b=%c,c=%c”,a,b,c);

输入:A,B,C

输出:a=A,b=,,c=B

Scanf函数的%c格式小结:

Scanf函数的%s格式输入的字符串中不能有空格、回车或跳格符(Tab),因为系统遇到这些分隔符时,会认为输入结束。不检查用户输入字符串长度是否超过了字符数组的容纳能力例如:charstr[10];scanf("%s",str);若输入:helloworld则实际存入str的只有"hello"

gets()函数将用户键入的换行符之前的所有字符(包括‘\t’和‘

’)存入字符数组,然后加上‘\0’,但换行符被丢掉不检查用户输入字符串长度是否超过了字符数组的容纳能力容易引起缓冲区溢出

scanf()不能读入带空格的字符串,gets()可以其中:函数参数可以是字符串常量,也可以是字符串变量。

puts()函数——专门用于输出字符串一般形式是:puts(字符串);与printf()的不同:

Puts()函数打印字符串的全部内容,直至遇到'\0'为止,然后自动多打印一个'\n',起到换行的作用。而printf函数无此功能。#include<stdio.h>#definePREDEF"这是预定义字符串"main(){charstr[]=“这是初始化字符串”;puts("这是直接使用字符串常量");puts(PREDEF);puts(str);}例:建议:当多种类型的混合输入输出时,选用scanf和printf;

当大量文字信息输入输出时,使用gets和puts。这些函数的原型存放在string.h文件中。

strlen()函数——测试字符串的长度

strcat()函数——字符串连结

strcmp()函数——字符串比较

strcpy()函数——字符串的拷贝三、字符串处理函数1、strlen()函数功能:测试字符串的长度。一般形式是:length=strlen(字符串)其中:函数参数可以是字符串常量,或者字符变量。整型变量length用于保存函数的返回值。字符串的长度是包围在双引号内的有效字符数,不包括双引号和‘\0’。如:"ABC"长度为3。"abc\n"长度为4""长度为0例:#include<stdio.h>#include<string.h>main(){charmsg[]="RockandRoll";intlnth;lnth=strlen(msg);printf("字符串:%s的长度是:%d\n",msg,1nth);printf(“空字符串的长度是:%d\n",strlen(""));}2、strcat()函数功能:用于连结两个字符串。一般形式:strcat(字符串1,字符串2);

将字符串2连结到字符串1的后面注意:(1)strcat函数不检查字符串1的空白位置是否装得下字符串2。连结前应用strlen函数进行检验,确保不发生溢出。(2)长度加1,为新字符串的结束符‘\0’留一个位置。其中:参数1必须是字符串变量,而参数2可以是字符串常量或变量。例:#include<stdio.h>#include<string.h>#defineSIZE30main(){charbook[SIZE];

charmsg[]="的确是本好书!";puts("你喜欢什么书?");gets(book);

if(strlen(book)+strlen(msg)+1<=SIZE){/*长度加1,为新串的'\0'留一个位置*/strcat(book,msg);puts(book);}elseputs("字符数组空间不够,无法进行连结!");}示例#include"string.h"main(){chara[80]=”AB”,b[80]=”LMNP”;inti=0;strcat(a,b);while(a[i++]!=’\0’)b[i]=a[i];puts(b);}结果:LBLMNP【注意】

b[i]=a[i]是从i=1开始3、strcmp()函数功能:比较两个字符串的大小。一般形式:i=strcmp(字符串1,字符串2);比较方法:从左至右逐个比较其ASCII码值大小其中:(1)字符串1、字符串2均可为字符串常量或变量.(2)i是用于存放比较结果的整型变量。比较结果的规定:①字符串1<字符串2,函数返回一个负值。②字符串1=字符串2,函数返回零。③字符串1>字符串2,函数返回一个正值。#include<stdio.h>#include<string.h>main(){inti;

i=strcmp("A","A");printf("%d\n",i);

i=strcmp("A","B");printf("%d\n",i);printf("%d\n",strcmp("B","A"));printf("%d\n",strcmp("C","A"));printf("%d\n",strcmp("disk","disks"));}例正确的做法是用strcmp函数进行比较。

if(strcmp("ABC","DEF")字符串的比较是比较字符串中各对字符的ASCII码。因此无论两个字符串是什么样,strcmp函数最多比较到其中一个字符串遇到结束符'\0'为止。×

如:if(“ABC”>“DEF”)注意:字符串是数组类型而非简单类型,不能用关系运算进行大小比较。#include<stdio.h>#include<string.h>#defineSIZE80#definePASSWORD"zhang"#defineTIMES3main(){inttry;charinput[SIZE];try=0;/*猜测次数变量清0*/

puts("请输入密码");

do{gets(input);if(strcmp(input,PASSWORD)!=0)puts("密码输入错,请再试一次");

elsebreak;

}while(++try<TIMES);

/*如果少于TIMES次,允许再试*/

if(try<TIMES)/*在规定次数内输入正确*/

puts("密码正确,请继续运行程序...");

elseputs("非法用户,不能使用本程序");}例:密码检查程序4、strcpy()函数功能:用于实现两个字符串的拷贝。一般形式:strcpy(字符串1,字符串2)

将字符串2拷贝到字符串1中

其中:字符串1必须是字符串变量,不能是字符串常量。注意:由于字符串是数组类型,所以两个字符串复制不能通过赋值运算进行。如:t=s;——错误的字符串复制*/

strcpy(t,s);——正确的字符串复制例10:#include<stdio.h>#include<string.h>#defineSIZE80main(){chars[]="Chinese";chart[SIZE];printf("原字符串是%s\n",s);strcpy(t,s);printf("拷贝的字符串是%s\n",t);printf("拷贝后原字符串是%s\n",s);}如果只需考贝字符串的一部分…

如果是考贝字符串的一部分,可用函数strncpy(目的字符数组,源字符串,考贝字符数)

#include“string.h”main(){chars[]=”Thisisasourcestring.”,b[20];strncpy(b,s,16);b[16]=’\0’;printf(“%s\n”,b);}结果:Thisisasource例6.9从键盘任意输入5个学生的姓名,编程输出按字典顺序排在最前面的学生姓名等价于求最小字符串#include<stdio.h>#include<string.h>#defineARRA_SIZE80main(){

intn,num;

charstr[ARRA_SIZE],min[ARRA_SIZE];

printf("Pleaseenterfivenames:\n"); gets(str); strcpy(min,str);

for(n=1;n<5;n++) { gets(str);

if(strcmp(str,min)<0) { strcpy(min,str); } } printf("Theminis:"); puts(min);}morestringfunctions…strupr()和strlwr()

大小写转换函数

strupr(字符串)

小写→大写

strlwr(字符串)

大写→小写数据分档(分类)、数据排序、数据检索§5.4

几个常用算法

一、数据分档缺点:程序冗长、占机时多常用数据分类的方法利用if语句利用switch语句例:随机输入一组数据,数据在1~4之间,输入结束统计出各类数据的个数。分析问题给出算法一:1、输入数据到x2、判断该数据属于那类,分别记数4、分别输出a、b、c、d的值3、反复执行1、2步骤直到数据输完为1记入a中为2记入b中为3记入c中为4记入d中编程方法一:(用基本数据类型)

main(){Loop:scanf(“%d”,&x);if(x==1)a+=1;if(x==2)b+=1;if(x==3)c+=1;if(x==4)d+=1;gotoloop;

intx,a,b,c,d;

a=b=c=d=0;

if(x==9999)gotoend;

if(x>=5||x<1)gotoloop;}

end:printf(“1的个数为:%d”,a);printf(“2的个数为:%d”,b);printf(“3的个数为:%d”,c);printf(“4的个数为:%d”,d);下标标量的引进,为分档问题提供了一种巧妙的方法,使程序明显简化。分析问题给出算法二:2、输入数据到x3、判断该数据属于那类,分别记数5、分别输出a[1]~a[4]的值4、反复执行2、3步骤直到数组输完

a[1]中记1的个数1、设定一个数组a存放统计结果

a[5]

a[4]中记4的个数

a[3]中记3的个数

a[2]中记2的个数

a[X]+=1main(){inta[5]={0,0,0,0,0},x,i,j;scanf("%d",&x);while(x<=4&&x>=1){a[x]=a[x]+1;scanf("%d",&x);}for(i=1;i<5;i++)printf("\na[%d]=%d",i,a[i]);}编程方法二:(用数组)二、数据排序数据排序又称为排队问题。所谓排序就是对一个数值大小不规则的数列按从小到大(从大到小)的顺序重新组成一个新的数列。

内部排序:插入~、选择~、交换~、归并~排序的分类

外部排序1、交换排序——“冒泡”排序法特点:逐个对数组中每相邻二数进行比较,若条件满足,则互相交换,否则保持原位置不变。若有n个数据,需要进行i=n-1轮比较。每轮中比较的次数为j=n-i+1次。排序过程:(设数据存于A数组中,n个数据,按递增次序排序)A[0]与A[1]比较A[0]<A(1)不换,否则对调A[1]与A[2]比较A[1]<A[2]不换,否则对调:A[n-2]与A[n-1]比较A[n-2]<A[n-1]不换,否则对调交换排序:俩俩比较待排序记录的键值,若逆序,则交换,直到全部满足为止4936416511第六趟排序后第五趟排序后第四趟排序后第三趟排序后第二趟排序后第一趟排序后初始关键字7836653641563641654136415611783636414911564925252511494956111111252525251、冒泡排序例:教材193页例6.32、选择排序——简单选择排序法简单选择排序:从1到n选出键值最(大)小的记录,交换到第一个位置上,然后从2到n选出键值最(大)小的记录,交换到第二个位置上,….5471582931547158293154715829315471582931i=0初态k=0数组下标01234j=1k=0j=2k=0j=3k=3j=4k!=i,交换第一趟互换i=0判断a[j]<a[k]?用选择法对数组inta[5]={54,71,58,29,31}进行升序排序k=jk=1j=2i=12971585431j=3k=2i=1第二趟29715854312971585431i=1k=3j=42971585431i=1k=4k!=i,交换互换29

31585471判断a[j]<a[k]?k=jk=jk=j29

31585471i=2k=2j=329

31

58

5471i=2k=3j=429

31

545871互换第三趟k!=i,交换i=3k=3j=4k=i,不交换第四趟判断a[j]<a[k]?三、查找查找的方法很多。如:顺序查找、二分法查找、散列法等等。1、顺序查找:最简单的查找方法,基本思想是利用循环顺序扫描整个数组,依次将每个元素与待查找值比较,直至找到或找不到。对于无序数组,顺序查找是唯一可行的办法对大批量数据用顺序查找占机器时间较多。intSearch(longa[],intn,longx){

inti;

for(i=0;i<n;i++){

if(a[i]==x){

return(i);}}

return(-1);}2、二分法查找/折半查找:二分法查找的条件:必须

温馨提示

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

评论

0/150

提交评论