




已阅读5页,还剩209页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言程序设计(二),第5章 循环程序设计,5.1 循环程序结构特点与组成 5.2 循环程序的控制方法 5.3 单重循环程序设计 5.4 多重循环程序设计 5.5 应用举例,引言(1),方法探索,1,2,3,1,s+2,s+3,S+100,s,s = s + i; /* 投入i 枚硬币到s中*/ i = i + 1; /* 计算下次投币数 */,100,i,引言(2),循环语句组成,(a) “先工作后判断”循环结构形式 (b)“先判断后工作”循环结构形式,引言(3),循环的三种语句,for语句 while语句 do-while语句,构成当型循环结构,构成直到型循环结构,while语句(1),while循环格式: while (表达式) 语句 其中的语句可以是一条语句,或相当于一条语句的复合语句,称为循环体。 while语句的执行过程为: (1) 计算表达式的值; (2)判断表达式的值,若为非0,则执行循环体;若为 0,则结束循环,执行while语句后面的语句。 (3)执行完循环体转步骤(1),while语句(2),图5-2 while循环结构流程图,图5-3例5-1流程图,例5-1,while语句(3),/* EX5-1.C */ main() int i,s; i=1;s=0; while(i=100) /* 循环控制 */ s=s+i; i=i+1; printf(“1到100的和为%dn“,s); ,程序代码,计算1到100之间所有3的倍数的和,思考,while语句(4),(1) 程序设计中应避免出现 “死循环”。 (2)循环执行的次数用以下公式计算: 循环次数 = (终值-初值)/ 步长 + 1 例如上例循环次数为: (100 1)/1 + 1,即100次。 步长也可以为负数,例如下面也能计算1+2+100: int i,s; i=100;s=0; while(i=1) s=s+i; i=i-1; 实际上,计算100991 (3)注意循环体中语句的先后次序对执行结果的影响。,注意,while语句(5),例1:用 求的近似值,直到某一项的绝对值小于10-4为止。求绝对值用数学函数fabs()。,/* EX5-2.C */ #include “math.h“ #include “stdio.h“ main() int sign; float i; float sum,temp; sum=0; sign=1; temp=1; i=1;,while(fabs(temp)=1e-4) sum=sum+temp; i=i+2; sign=-sign; temp=sign/i; sum=sum*4; printf(“pi=%fn“,sum);,do-while语句(1),do-while语句的一般格式为: do 语句 while(表达式); do-while语句的执行过程为: 先执行循环体语句 再判断表达式的值,若值为0,则结束循环,执行do-while语句后面的语句;若值为非0,则继续执行循环体。,do-while语句(2),/* EX5-3.C */ main( ) int i,s; i=1;s=0; do s=s+i; i=i+1; while(i=100); printf(“s=%dn“,s); ,可见do-while循环和while循环可以完成相同的任务。,计算s=1+2+3+100,do-while语句(3),do-while先做后循环,而while循环先判断后做 例如下面两个程序:,main() int n=1; do printf(“%d:*n”,n+) while(n1); printf(“%d:$n”,n); ,main() int n=1; while(n1) printf(“%d:*n”,n+); printf(“%d:$n”,n); ,由于程序循环条件不成立,左边的程序循环体一次也没执行,运行结果为1:$ ;虽然右边的程序循环条件也不成立,但循环体却执行了一次,运行的结果为1:* 2:$ 。,for语句(1),for语句语法如下: for(表达式;表达式;表达式) 循环体语句 表达式通常用于循环的初始化,包括循环变量的赋初值、其他变量的准备等;,初始化表达式,循环条件,修正表达式,表达式为循环的条件,如果缺省则条件为真;,表达式通常设计为循环的调整部分,主要是循环变量的变化部分;,for语句(2),for语句的执行 (1)计算表达式; (2)计算表达式,当值为非0则执行循环体语句;当值为0则跳出循环,执行for语句后面的语句; (3)若执行完循环体语句,则接着执行表达式,然后转到步骤(2)继续循环。,for语句(3),【例5-4】使用for编写程序,求123100的和。 /* EX5-4.C */ main() int i,sum; for(i=1,sum=0;i=100;i+) sum+=i; printf(“1到100的和为%dn,sum”); ,for编写程序,求123n的值,如果n值很大,思考,for语句(4),注意,for循环可以用以下while循环代替: 表达式; while (表达式) 循环体语句; 表达式; (2)表达式可以放在for循环的前面,但后面的分号不能少,例如:表达式; for(;表达式;表达式)循环体语句; (3)表达式也可以省略,此时循环条件始终为真 for(表达式; ;表达式) 循环体语句; if(条件)break; /*结束循环*/ ,for语句(5),思考,(4) 表达式也可以省略,但作为循环变量的调整功能不能缺少,可以在循环体中完成,例如下面的for循环: for(i=1,s=0;i=100;) s = s + i;i+; (5) 如果表达式和都省略的话,相当于while循环,例如下面的程序形式: i=1,s=0; for(;i=100;) /*相当于 while(i=100)*/ s+=i+;,for语句(6),思考,(6)表达式、表达式、表达式均省略,即: for (;) 循环体语句; 相当于while (1)循环体语句; (7)如果全省略,即如以下形式: for (;); 这将构成一个死循环。,for语句(7),例,使用for循环语句编写程序,求解满足条件123n1000的最小n和s的值。,/* EX5-6.C */ main() int n,s; for(n=1,s=0;s=1000;n+)s+=n; n-; printf(“n=%d,s=%dn“,n,s); ,其他控制语句(1),为了使循环控制更加灵活,语言提供了break语句和continue语句。 1一般格式: break; continue; 2功能 (1)break:强行结束循环,转向执行循环语句的下一条语句。 (2)continue:对于for循环,跳过循环体其余语句,转向循环变量增量表达式的计算;对于while和do-while循环,跳过循环体其余语句,但转向循环继续条件的判定。,其他控制语句(2),3break和continue语句对循环控制的影响如图所示。,4说明 (1)break能用于循环语句和switch语句中,continue只能用于循环语句中。 (2)循环嵌套时,break和continue只影响包含它们的最内层循环,与外层循环无关。,其他控制语句(3),main() int n,s; n=1; s=0; for(;n=10;n+) if(n%2=0) continue; if(n%10=7) break; s+=n; printf(“s=%dn“,s);,main() int n,s; n=1; s=0; while(n=10) if(n%2=0) continue; if(n%10=7) break; s+=n; n+; printf(“s=%dn“,s);,左边的程序的结果是:s=9,右边的程序进入死循环。,?,单循环程序设计(1),素数问题,【例5-7】从键盘输入一个整数,判断它是否为素数,并输出结果。,/* EX5-7.C */ #include “math.h“ main() int n,i,k; printf(“请输入数值N:n “); scanf(“%d“,单循环程序设计(2),公倍数问题,【例5-8】输入两个正整数m和n,求其最大公约数和最小公倍数。,/* EX5-8. C*/ main() int m,n,a,b,t; printf(“从键盘读入 m 和 n: “); scanf(“%d,%d“, ,单循环程序设计(3),Fibonacci数列问题,【例5-10】求Fibonacci数列的前40个数。该数列的生成方法为:F1=1,F2=1,Fn=Fn-1+Fn-2(n=3),即从第3个数开始,每个数等于前2个数之和。 /* EX5-10. C*/ main() long f1,f2,f3; int i; f1=1; f2=1; printf(“%10ld%10ld“,f1,f2); for(i=3;i=40;i+) f3=f1+f2; printf(“%10ld“,f3); if(i%5=0)printf(“n“); f1=f2; f2=f3; ,如何逆序输出?,?,多重循环程序,【例5-14】计算100以内的所有素数之和。 内循环首先判断当前的循环变量的值是否为素数,是则累加求和;外循环控制产生1到100的数的循环 程序如下: /* EX5-15.C */ main() int i,j,s=0; for(i=2;ii-1) /* i是素数,因为2 i-1没有i的因子 */ s=s+i; printf(“100以内所有素数和为:%dn“,s);,求和专题(1),【例5-9】利用公式求sinx的近似值(精度为,/* EX5-9. C*/ #include “math.h“ #define PI 3.14159 main() int n,xx; float t,sum,x; printf(“输入弧度X“); scanf(“%d“,t=x; n=1; sum=0; do sum=sum+t; t=-t*x*x/(n+1)*(n+2); n=n+2; while (fabs(t)=1e-6); printf(“sin(PI/%d=%fn“,xx,sum); ,求和专题(2),【例5-13】计算s=1+(1+2)+(1+2+3)+(1+2+3+4+n),/* EX5-14.C */ main() int i,j,s,n; printf(“请输入数值N: “); scanf(“%d“, ,/* EX5-13.C */ main() int s,t,i,n; s=0; t=1; printf(“请输入数值N: “); scanf(“%d“, ,求和专题(3),?,习题: 1、利用下面公式求s的值(10项之和) 2、求S1!2!n! 3、,图形输出专题,【例5-11】输出九九乘法表,main() int i,j; for(i=1;i=9;i+) for(j=1;j=i;j+) printf(“%d*%d=%2d “,j,i,i*j); if (j=i) printf(“n“); ,如何输出?,?,穷举专题(1),例求1到500之间的全部“同构数”之和。所谓“同构数”是指一个数,它出现在它的平方数的右端。如6的平方是36,6出现在36的右端,6就是同构数。 main( ) int n, sum=0; long sn; for(n=3;n=500;n+) sn=n*n; if(n=sn%10|n=sn%100|n=sn%1000) sum=sum+n; printf(“sum=%dn“,sum); ,穷举专题(2),【例5.17】穷举法计算搬砖问题:36块砖,36人搬;男搬4,女搬3,两个小孩抬一砖。要求一次全搬完,问男、女、小孩各多少人?,根据题意知,男人为:08;女人为:011;小孩为:036。 /* EX5-18.C */ main() int men,women,children; for (men=0;men=8;men+) for(women=0;women=11;women+) children=36-men-women; if (men*4+women*3+children/2=36) ,迭代专题,【例】现有人口13亿,如果按年2的增长速度,10年后将有多少人?,main() int i,year=10; float n=13; for(i=1;i=year;i+) n=n*(1+0.02); printf(“10年后的人口数为:%.4f亿n“,n); ,【例5.16】用牛顿迭代法求正实数a的平方根。(参考教材),循环程序设计,1、注意for循环与while循环的联系以及while循环与do-while循环的区别。 2、在编写循环程序时,要注意避免出现死循环。 3、注意break和continue语句的区别。 4、3种循环控制语句可以相互嵌套组成多重循环,但要注意循环之间不能交叉。 5、掌握求和问题、图形输出问题、最大公约数/最小公倍数问题,最值问题和穷举法、迭代法等经典算法程序的编写。,总 结,6.1 一维数组 6.2 二维数组 6.3 字符数组与字符串 6.4 程序举例,第6章 数组,【本章导读】,前几章我们已经学习了C语言的一些基本数据类型,如整型、字符型和实型等。但是仅有这些基本类型很难满足较复杂情况下的编程需要。 在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类型数据元素的集合称为数组。 数组属于构造数据类型。一个数组可以包含多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构体数组等各种类型。,第6章 数组,【本章导读】,通过本章学习,要求达到以下目标:掌握一维数组、二维数组的定义、初始化和数组元素的引用;掌握字符数组的定义、初始化和数组元素的引用;掌握字符串的存储方法和应用;掌握有关处理字符串的系统函数的使用方法。,第6章 数组,【分析】 从键盘接收10个数,求平均数很简单,可以采用边接收边求和的方法,最后求平均数;但是输出小于平均数的数就比较麻烦了,因为从键盘接收的10个数在求和以后没有保存起来,等再比较比平均数小的数就无法实现。 要解决此问题,必须使用数组。先将10个数保存到数组中去,等求过平均数后再从数组里取出10个数进行比较。,【问题】从键盘接收10个数,求平均数并输出小于平均数的数,6.1 一维数组,6.1.1 一维数组的定义 一维数组的定义形式为: 数据类型 数组名元素个数; 例如: int a5; 定义了一个一维整型数组,数组名为a,有5个数组元素。这5 个元素分别为a0、a1、a2、a3、a4。,6.1.1一维数组的定义,【注意】 (1) 数组名用合法的标识符命名,与变量的命名方法相同。 (2) 方括号中的数组元素的个数又叫数组的长度。 (3) 数组元素的序号(下标)是从0开始。 如数组定义a5中的5表示数组a有5个元素,下标从0开始。注意下标不能越界,即不能使用数组元素a5或更大下标的元素。若使用的下标越界,系统虽然不提示错误,但可能会出现意想不到的结果,甚至可使系统出现问题。,(4) C语言不允许对数组长度作动态定义,即定义中的数组元素个数可以包括常量和符号常量,但不能包括变量。例如:下面的定义是错误的。 int n=10; int an; /*因为n为变量*/ 而下面的定义是正确的。 #define N 10 main() int aN; /*N为符号常量*/ ,(5) 数组元素具有定义语句中指定的数据类型。它可以是任一种基本数据类型或构造数据类型。同一数组中所有元素的数据类型都是相同的。 下面是常见的一维数组的定义: int a10; /*定义整型数组a,它有10个元素*/ char str20; /*定义字符型数组str,它有20个元素*/ float b5,c10; /*定义实型数组b和c,b有5个元素,c有10个元素*/,6.1.2一维数组元素的引用,数组在定义之后即可引用其中的数组元素,其引用形式为: 数组名下标 下标只能为整型常量或整型表达式。如果为小数,C语言编译时将自动取整。C语言中只能逐个引用数组元素,而不能一次引用整个数组。,【例6.1】将数字09装入一个整型数组a中,并输出。,/* EX6-1.C */ main() int a10; int i; for(i=0;i10;i+) ai=i; printf(“%d“,ai); ,6.1.3一维数组的存储和初始化,1.一维数组的存储:系统为数组按照其类型和元素个数开辟一组连续的存储单元,每个存储单元存放一个数组元素,该连续存储单元的首地址由数组名表示。 2.有两种方式对数组元素赋值: (1)数组定义时给数组元素赋以初值,这两种方式称为数组的初始化; (2)在程序执行部分用赋值语句或输入语句给数组元素赋值。,3.对一维数组的初始化通常可以采用以下方式进行: (1)对数组的全部元素赋初值,例如: int num5=1,2,3,4,5; 经过上述定义及初始化之后,num0=1, num1=2, num2=3, num3=4, num4=5。 (2)对数组的部分元素赋初值其余元素的值为0(对实数是0.0,对字符型是0),例如: int num5=1,2,3; 只给前3个元素赋初值,其余2个元素的值为0。 注意:定义普通数组时没有初始化赋值,所有元素的值都是随机的。,6.1.3一维数组的存储和初始化,(3) 对全部数组元素赋初值时,可以不指定数组的长度(元素个数),例如: int num =1,2,3,4,5; (4) 当定义的数组元素个数小于初值的个数时,作语法错误处理,例如: int num4=1,2,3,4,5; 是不合法的,因为num数组只能有4个元素。,6.1.3一维数组的存储和初始化,6.1.4 一维数组的应用,【例6.2】用数组求Fibonacci数列的前20项。 【分析】 Fibonacci 数列可按下式计算: f i =f i-1+f i-2 初值 f 0=1 ,f 1=1。,main() int i; int f20=1,1; for(i=2;i20;i+) fi=fi-2+fi-1; for(i=0;i20;i+) if(i%5=0) printf(“n“); printf(“%6d“,fi); ,【例6.2】 /* EX6-2.C */,【例6.3】从键盘输入10个数,求平均数并输出所有大于平均数的数。,main() int i,n=0; float a10,ave=0; printf(“请输入10个数:n“); for(i=0;iave) printf(“%f “,ai); n+; if(n%4=0)printf(“n“); printf(“ n“); ,/* EX6-4.C 比较排序 */ main() int a10=8,15,14,12,9,3,11,0,28,6; int i,j,temp; for(i=0;i9;i+) for(j=i+1;j10;j+) if(aiaj) temp=ai; ai=aj; aj=temp; for(i=0;i10;i+) printf(“%3d“,ai); printf(“n“); ,【例6.4】将10个整数从大到小排序,/* EX6-4.C 选择排序 */ main() int 10=8,15,14,12,9,3,11,0,28,6, i,j,t,p; for(i=0;i9;i+) p=i; for(j=i+1;j10;j+) if(apaj) p=j; if(p!=i) t=ai; ai=ap; ap=t; for(i=0;i10;i+) printf(“%3d“,ai); printf(“n“); ,【例6.4】将10个整数从大到小排序,【分析】 可先定义一个一维数组,将n个数存入该数组中,然后输入要查找的数 x,再利用循环顺序查找,当找到该数就打印该数并停止循环。 停止循环可用break语句,也可以用一个标志变量,程序如下:,【例6.5,顺序查找算法】在n个数中查找一个数x,/* EX6-5.C */ #define N 15 main( ) int aN, x, i, find; for(i=0; iN; i+) scanf(“%d”, ,【顺序查找算法】在n个数中查找一个数x,运行结果如图所示:,顺序查找需要查找的次数比较多,设有n个数,平均需要查找n/2次,用折半查找就快得多。 (1)指导思想:先将中间的数与待查的数比较,如果找到就结束查找,否则,若待查数小于中间数,应在前半部分继续查找;若待查数大于中间数,应在后半部分继续查找。在一半范围内查找还是用中间数与待查数比较,直到待查范围缩小到没有数为止。理论上,折半查找平均查找次数为log2n (2)具体方法:设三个变量mid、top和bot,分别表示查找范围的中间、最小和最大下标,查找中如果没有找到,则不断迭代这些变量,直到找到或查找范围缩小到没有数为止。程序如下:,【折半查找算法】对排好序(如从小到大)的数进行查找,/* EX6-6.C */ #define N 15 main() int aN, x, i, mid, top, bot, find; for(i=0; iN; i+)scanf(“%d”, ,【折半查找算法】对(从小到大)排好序的数进行查找,运行结果如图所示:,6.2 二维数组,6.2.1 二维数组的定义 二维数组定义的一般形式为: 数据类型 数组名行数列数; 例如: int a23; /*定义a为2行3列的整型数组*/ char c35; /*定义c为3行5列的字符型数组*/ float d45; /*定义d为4行5列的实型数组*/,6.2.2 二维数组元素的引用 数组名行下标列下标 如:s24,这里下标用来标识数组元素在数组中的位置。 下标可以是整型常量或整型表达式,如:a23, aij,sk-1i+3 等。但不能写成s2,1+3,ai,j的形式。 请注意区分数组的定义和数组元素的引用。两者从形式上看有些相似,但含义却完全不同。,6.2 二维数组,/* EX6-7.C */ main() int i, j, a34; for(i=0;i3;i+) /*变量i控制数组的行下标*/ for(j=0;j4;j+) /*变量j控制数组的列下标*/ scanf(“%d“, /*每行输出结束时换行*/ ,【例6.7】二维数组的输入与输出,6.2.3二维数组的存储和初始化,1、二维数组的存储:按行存储,即一行接一行存储。例如整型数组a34共有12个存储单元,每个存储单元4个字节。存放的顺序是按行存放:a00, a01, a02, a03, a10, a13, a20, a23。 设有一个m行n列的二维数组,元素aij (0im-1,0jn-1)在内存中存放的顺序号是该数组的第i* n+j+1个单元。 二维数组所占用的连续存储单元的首地址也用数组名表示。,6.2.3 二维数组的存储和初始化,多维数组的存储顺序:从下标全为0的元素开始,先改变最后一个下标,再变次后一个下标,最后变第一个下标,例如数组a定义为 int a234; 其存放顺序为:a000, a001, a003, a010, a013, a020, a023, a100, a103,a110, a113, a120, a123。 根据按顺序存储的性质,可以通过首地址按一维数组的方式引用二维及多维数组的元素。即将二维及多维数组元素存储的顺序号与一维数组的下标对应。,6.2.3 二维数组的存储和初始化,2.二维数组的初始化 (1) 分行给二维数组赋初值,例如: int s34=1,2,3,4,5,6,7,8,9,10,11,12; (2) 按存储顺序连续赋初值,例如: int s34=1,2,3,4,5,6,7,8,9,10,11,12;,(3)对部分元素赋初值(未赋初值的元素值为0,对实数是0.0,对字符型是0) a、按行赋初值,只对部分行的部分列赋初值,例如: int a34=1,2,3,4,5; 结果为: a00=1,a01=2, a02=3, a03=0; a10=4,a11=5,a12=0, a13=0; 行号为2的行(最后一行)元素全部为0。 b、按存储顺序对部分元素赋初值,例如: int a34=1,2,3,4,5; 结果是前5个元素被赋初值:a00=1,a01=2, a02=3,a03=4,a10=5,其余元素全部为0。,(4)完全赋初值或按行给全部行的部分列元素赋初值,可省行数,例如: int a 3=1,2,3,4,5,6; /*行数为2*/ int a 3=1,2,3; /*行数为2,只给a00、a01、a10赋初值*/ (5)按存储顺序给部分元素赋初值,省略的行数为:最后初值到达行号+1 例如: int a 3=1,2,3,4; /*行数为2*/ 注意:无论在什么情况下列数都不能省!,三维数组的初始化:与二维数组类似。 (1)按页(花括号)、行(嵌套花括号)赋初值,例如: int a232= 1,2,3,4,5,6,7,8,9,10,11,12; (2)按存储顺序赋初值,例如: int a232= 1,2,3,4,5,6,7,8,9,10,11,12; 赋全部初值可省略第一维的大小。,(3)对部分元素赋初值,例如: int a232=1,2,3,4,5,6,7; 初值情况为:第0页 1 2 第1页 7 0 3 4 0 0 5 6 0 0 或按页、行赋初值,例如: int a 32= 1,2,3,5,0,7,8,10; 初值情况为:第0页 1 2 第1页 0 7 3 0 8 0 5 0 10 0 由于明显有两页,第一维的大小可省。这种用花括号分开初值的办法可以推广到多维数组。,6.2.4 二维数组的应用,【例6.8】将矩阵a转置后存入矩阵b。,矩阵的转置即行列互换,程序编写如下:,main() int a23=1,3,5, 2,4,6,b32, i,j; for(i=0;i2;i+) for(j=0;j3;j+) printf(“%3d “,aij); printf(“n“); for(i=0;i2;i+) for(j=0;j3;j+) bji=aij; printf(“n“); for(i=0;i3;i+) printf(“%3d%3dn“,bi0,bi1); ,【例6.9】不借助另外的矩阵,将矩阵a转置。 【分析】不借助另外的矩阵,将一个矩阵转置,要求是一个方阵,即将i行j列的元素与j行i列的元素互换。但应注意下标i、j不能完全遍历,否则矩阵将转置两次等于还原。 程序如下:,/* EX6-9.C */ main() int a33=1, 2 ,3,4,5,6,7,8,9, i, j,t; for(i=0;i3;i+) /*输出矩阵a */ for(j=0;j3;j+) printf(“%3d“,aij); printf(“n“); for(i=0;i3;i+) /*转置矩阵a */ for(j=0;ji;j+) /*条件ji限制操作在下三角范围内*/ t=aij; aij= aji; aji=t; for(i=0;i3;i+) /*输出转置过的矩阵a */ for(j=0;j3;j+) printf(“%3d“,aij); printf(“n“); ,运行结果如图所示:,【例6.10】有M个人参加了N门课程的考试,编程输入所有成绩。求每个人的平均成绩和每门课程的平均分数,并找出所有成绩中的最高分数是哪个学生的哪门课程的成绩。 【分析】成绩存入M行N列的二维数组,行代表学生,列代表课程。M个学生的平均成绩存入数组aveM中,N门课程的平均分数存入数组meanN中。程序如下:,/* EX6-10.C */ #define M 5 #define N 3 main() int i,j,sMN,max=0,row,col; float aveM=0,meanN=0; printf(“输入成绩:n“); for(i=0;imax) max=sij; row=i; col=j; /*寻找最高成绩*/ avei=avei /N; ,for(j=0;jN;j+) /*求每门课程的平均分数*/ for(i=0;iM;i+) meanj+= sij; meanj= meanj/M; printf(“学生t课程1t课程2t课程3 平均n“); for(i=0;iM;i+) printf(“NO.%dt“,i+1); for(j=0;jN;j+) printf(“%5d “,sij); printf(“%.1fn“,avei); for(j=0;jN;j+) printf(“课程%d:%5.1fn“,j+1,meanj); printf(“最高分=%d, NO.%d, 课程%d.n“, max, row+1,col+1); ,运行结果如图所示:,6.3 字符数组与字符串,数组既可以存放数值数据,也可以存放字符数据。存放数值数据的数组称为数值数组,存放字符数据的数组称为字符数组。字符数组中的每一个元素存放一个字符。 C语言中没有专门的字符串变量,通常用一个字符数组存放一个字符串,6.3.1 字符数组的定义与初始化,1.字符数组的定义 字符数组的定义和前面介绍的数值数组类似。例如: char ch10; char name310; 由于字符型和整型在一定程度上可以通用,所以 char ch10; 也可以写成 int ch10;,6.3.1字符数组的定义与初始化,2.字符数组的初始化 (1) 字符数组的初始化的基本方法 char ch5=h,e,l,l,o; char ch10=h,e,l,l,o; 未赋初值的元素为0。 (2) 如果对全体元素赋初值,可以省略长度说明 如: char ch =h,e,l,l,o; (3) 二维字符数组初始化 char name310=M,u,s,i,c, A,r,t,s, S,p,o,r, t;,6.3.2 字符串,C语言用0作为字符串的结束标志,凡以0结束的一串字符均可按字符串处理。计算字符串长度(字符数)时0不包括在内。 1字符串的存储 可用一维字符数组存放字符串:以第一个0为字符串结束符。例如可用字符串直接给字符数组赋初值: char ch =“hello“; 也可以省去花括号,直接写成: char ch =“hello“; 此时,数组ch 实际有6个元素,而不是5个元素,该字符串的末尾自动加上0,表示字符串的结束。 通常,字符数为n的字符串需占用n+1个字符空间, 与上例等价的形式为:char ch6=“hello“;,【注意】 (1) 若写出字符数组长度则必须比字符串中字符的个数多1。以容纳0。 (2) 用字符串形式对字符数组初始化时,系统会自动在其末尾加上0,而采用逐个字符对字符数组初始化时,需要人为的加上0。如: char ch =h,e,l,l,o,0; 否则只是一个没有结束符的字符数组,而不是一个独立的字符串。当定义字符数组长度大于字符串中字符的个数时例外(为什么?)。 (3)我们在程序中可以依靠检测0来判定字符串是否结束。 同样,也可以对二维字符数组进行初始化。例如: char s38=“China”, “America”, “Korea”; 此时每行存放一个字符串。,2字符串的输入和输出,(1) 逐个输入输出字符串中的字符 输入:在scanf函数中用“%c”,或者用getchar函数可以逐个输入字符串中的字符,他们的共同特点是: a、系统不自动加0 ,要用单独语句输入; b、空白字符(空格、n、t等)也作为字符输入。 输出:在printf函数中用“%c”,或者用putchar函数可以逐个输出字符串中的字符。 共同特点是: 遇到0不结束输出、不换行(中间的0变成空格)。 他们的不同点是: scanf和printf一次可输入或输出多个字符; getchar和putchar一次只能输入或输出一个字符且需要#include 。,【例6-11】使用“%c“输入输出字符串 main() int i; char ch4; printf(“输入4个字符: “); for(i=0;i4;i+) scanf(“%c“, ,【例6-11】用getcharh和putchar函数输入输出字符串 #include main() int i; char ch4; printf(“输入4个字符:“); for(i=0;i4;i+) chi=getchar(); printf(“这些字符是: “); for(i=0;i4;i+)putchar(chi); printf(“n“); 运行结果相同。,a、注意:输入项为字符数组名(首地址),不能加& b、优点:可同时输入多个字符串(以空格、Tab和回车分隔) c、缺点:由于空格为scanf函数的输入分隔符,输入字符串中不能包含空格,(2)整个字符串的输入 在scanf函数中使用%s : 形式: scanf(“%s“,字符数组首地址) 例如:char str110, str210; scanf(“%s%s“,str1, str2); 键盘输入China Japan结果存储为:,(2) 整个字符串的输入 使用gets函数输入字符串 形式:gets (字符数组首地址) 例如:gets(str1); a、特点:回车转换为0 b、优点:字符串中可包含空格 c、缺点:一次只能给一个字符数组输入且需要 #include 使用scanf函数和gets函数输入字符串的共同特点: a、系统自动加0字符(scanf自动加,gets用回车转换) b、回车键不作为字符输入,(3) 整个字符串的输出 在printf函数中使用%s : 形式:printf (“%s”, 字符数组首地址或常量字符串) 例如:printf(“%s %sn “,str1,“Korea“); a、可同时输出多个字符串,每个字符串遇0结束 (0不输出) b、输出一个字符串后不自动换行; 用puts函数输出: 形式:puts (字符数组首地址或常量字符串) 例如:puts(str1); puts(“China”); a、一次只能输出一个字符串且需要#include b、自动换行(将0转换成n); 用printf和puts函数输出字符串的共同特点:遇第一个0结束字符串的输出,例:用格式化函数输入输出一个字符串,main() char str20; printf(“输入字符串:n“); scanf(“%s“,str); printf(“%sn“,str); ,例:用gets输入puts输出一个字符串,#include main() char str20; printf(“输入字符串:n“); gets (str); puts(str); ,【说明】 a、在用scanf和gets函数输入字符串时,若用字符数组元素地址代替数组名首地址,例如,若有语句scanf(“%s”,键盘输入China结果存储均为:,b、输出字符串时,若用字符数组元素地址代替数组名首地址,则输出自该元素至第一个0之间的全部字符,如有定义 char str12=”abcdefghijk”; 语句printf(“%s”, 回车换两行,3字符串函数,字符串拷贝函数 strcpy 字符串连接函数 strcat 字符串比较函数 strcmp 测字符串的长度函数 strlen,(1)字符串拷贝函数 strcpy 使用形式: strcpy(字符数组名,字符串) 【功能】将一个字符串(字符数组或常量字符串)复制到一个字符数组中。字符串结束标志0也一同拷贝。 【例6-12】将一个字符串复制到另一个字符数组中 /* EX6-12.C */ #include #include main() char str110,str2=“China“; strcpy(str1,str2); puts(str1); ,(2)字符串连接函数strcat 形式:strcat(字符数组名1,字符数组名2或字符串2) 【功能】把字符串2连接到字符串1后面,去掉字符串1后面的0,结果存放在字符数组1中,因此,字符数组1应足够长。函数返回值为字符数组1的首地址。 【例6-13】连接两个字符串 /* EX6-14.C */ #include #include main() char str150=“I Love“; char str2 =“China !“; strcat(str1,str2); puts(str1); ,(3)字符串比较函数strcmp 形式为: strcmp(字符串1,字符串2) 【功能】比较两个字符串,返回值为比较结果: 当 字符串1 =字符串2,函数返回值为0; 字符串1 字符串2,函数返回值为一正数; 字符串1 字符串2,函数返回值为一负数。 字符串的比较规则为:从两个字符串中的第一个字符开始逐个进行比较(按字符的ASCII码值的大小),直至出现不同的字符或遇到0为止。如果全部字符相同,则两个字符串相等;若出现了不相同的字符,则以第一个不同的字符的比较结果为准。,【例6-14】输入5个字符串,将其中最大的字符串输出,#include #include main() char str10,max10; int i; gets(max); for(i=0;i4;i+) gets(str); if(strcmp(max,str)0) strcpy(max,str); printf(“n The max string is: %s“,max); ,(4)测字符串的长度函数strlen 形式如下: strlen(字符串) 【功能】测字符串中第一个0之前的实际字符个数(不含0标志) 例如:strlen(“China“); 函数值为5。 【例6-15】测字符串的长度。 /* EX6-15.C */ #include main() char str =“China“; printf(“string length:%d“,strlen(str); ,6.3.3 字符串的应用,【例6-16】删除一个字符串中的某个特定字符,本题以字符s为例。 【分析】字符串存入字符数组中,要删除的字符可能不止一个,方法是将后面的字符覆盖要删除的字符。具体做法:对字符数组设定两个作为下标的变量,一个用作访问所有的元素,另一个用作复制不删除的元素,最后赋0值作为新字符串结束标志。,/* EX6-16.C */ main() char str =“this is a book“; char c=s; /*设本例中要删除的特定字符为s*/ int i,j=0; for(i=0;stri!=0;i+) if(stri!=c) strj+=stri; strj=0; printf(“%sn“,str); ,【例6.17】将输入的字符串逆序存放后输出。 【分析】字符串存入字符数组中,要逆序存放,就要将下标为0的字符与下标最大的字符交换,下标为1的字符与下标次最大的字符交换,最大下标应为字符串长度-1。,/* EX6-17.C */ #include #include main() char str20, t; int i,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年成人教育线上学习模式创新成人教育课程设计与开发实践策略分析
- 合肥市土地资源承载力:综合评价与发展策略探究
- 产业园区合作共建协议5篇
- 良好习惯课件
- 2025内蒙古呼伦贝尔根河市事业单位文旅岗位引进人才2人备考及答案详解参考
- 聚焦群众身边腐败问题和不正之风的问题整改措施
- 2025年二级建造师考试建筑工程管理与实务试题与参考答案
- 2025年教师招聘之《小学教师招聘》综合提升试卷附完整答案详解(夺冠)
- 2025年教师招聘之《幼儿教师招聘》考前冲刺测试卷包附答案详解【考试直接用】
- 2025呼伦贝尔农垦集团有限公司社会招聘50人考试备考及1套完整答案详解
- 家事财产申请表
- 2025病历书写基本规范
- 学校用电协议书范本
- 安徽离婚协议书范本
- 2025年公共营养师考试历年真题与试题答案
- DB15T 3943-2025紫花苜蓿冬春灌技术规程
- 《时尚品牌市场调研》课件
- 2025年一季度全院难免压疮风险评估上报总结分析(二篇)
- 网页设计的交互设计研究-洞察分析
- 微信零钱被冻结的保全复议申请书
- 《矿山安全技能培训》课件
评论
0/150
提交评论