C语言程序设计课件_第1页
C语言程序设计课件_第2页
C语言程序设计课件_第3页
C语言程序设计课件_第4页
C语言程序设计课件_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

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

文档简介

-.z.程序设计语言一般分为机器语言、汇编语言和高级语言三大类。1.机器语言对于计算机来说,一组机器指令就是程序,称为机器语言程序。2.汇编语言为了便于理解与记忆,人们采用能帮助记忆的英文缩写符号(称为指令助记符)来代替机器语言指令代码中的操作码,用地址符号来代替地址码。3.高级语言机器语言和汇编语言都是面向机器的语言,一般称为低级语言。例2.1编写一个C程序,其功能是显示字符串“Howdoyoudo!”。其C程序如下:*include"stdio.h"main(){printf("Howdoyoudo!\n");}下面针对一般的C程序作几点说明:(1)一个完整的C语言程序可以由多个函数组成,但必须包含一个且只能包含一个名为main的函数(主函数)。程序总是从main函数开始执行。(2)在一个C函数模块中,由左右花括号{}括起来的部分是函数体,其中的语句系列实现函数的预定功能。(3)C程序中的每一个语句必须以“;”结束,但书写格式是自由的。(4)*include是编译预处理命令,其作用是将双引号或尖括号括起来的文件容读到该命令的位置处。(5)在C程序的任何位置处都可以用/*......*/作注释,以提高程序的可读性。整型常量及其变量的定义1.整型常量在C语言中,有3种类型的整型常量:基本整型常量、长整型常量、无符号整型常量。在C语言中,不管是哪种类型的整型常量,都可以用3种数制表示。(1)十进制整型常量。(2)十六进制整型常量。(3)八进制整型常量。2.整型变量的定义在C程序中,用于存放整型数据的变量称为整型变量。在C语言中,可以定义基本整型、长整型、短整型和无符号整型等4种类型的整型变量。它们的定义方式如下。(1)基本整型变量定义基本整型变量的形式如下:int变量表列;(2)长整型定义长整型变量的形式如下:long[int]变量表列;(3)短整型定义短整型变量的形式如下:short[int]变量表列;(4)无符号整型定义无符号基本整型变量的形式如下:unsigned[int]变量表列;①一个类型说明语句可以同时定义多个同类型的变量,各变量之间用逗号“,”分隔。②用类型说明语句定义的变量只是说明了为这些变量分配了存储空间,以便用于存放与之相同类型的数据,在未对这些变量赋值前,这些变量中(即存储空间中)的值是随机的。③C语言允许在定义变量的同时为变量赋初值。④在为整型变量初始化或赋值时,C编译系统自动将被赋数据转换成与相应变量的类型一致。⑤由于各种整型变量所占的字节数有限,因此,它们所能存放的整数有一定的围。实型常量及其变量的定义1.实型(浮点型)常量(1)十进制数形式(2)指数形式(科学记数法)2.实型变量的定义在C程序中,用于存放实型数据的变量称为实型变量。在C语言中,实型变量有单精度与双精度两种。单精度float双精度double字符型常量及其变量的定义1.字符型常量'\n'换行'\r'回车'\b'退格'\t'制表(横向跳格)'\''单引号(单撇号)'\"'双引号(双撇号)'\ddd'1~3位八进制数所代表的ASCII码字符'\*hh'1~2位十六进制数所代表的ASCII码字符'\f'走纸换页‘\\’反斜杠字符2.字符型变量的定义字符型变量的定义方式如下:char变量表列;数据的输入与输出应包括以下几项:①输入(出)的设备②输入(出)的格式③输入(出)的容格式输出函数格式输出函数的一般形式如下:printf(*“格式控制”,输出表);其中格式控制部分要用一对双撇号括起来,它用于说明输出项目所采用的格式。1.整型格式说明符(1)十进制形式(2)八进制形式(3)十六进制形式2.实型格式说明符如果以十进制数形式输出实型数据,其格式说明符为%f或%m.nf如果以指数形式输出实型数据,其格式说明符为%e或%m.ne3.字符型格式说明符字符型数据的格式说明符为%c或%mc(1)输出表中各输出项目之间要用“,”分隔。(2)格式控制中的各格式说明符与输出表中的各输出项目在个数、次序、类型等方面必须一一对应。(3)格式控制中除格式说明符外的其他字符将按原样输出。(4)在输出格式说明符中,如果带有宽度说明,则在左边没有数字的位置上用空格填满(即输出的数字是右对齐)。但如果在宽度说明前加一个负号(-),则输出为左对齐,即在右边补空格。格式输入函数格式输入函数的一般形式如下:scanf(“格式控制”,存地址表);1.整型格式说明符(1)十进制形式用于输入十进制形式的整型数据。(2)八进制形式用于输入八进制形式的整型数据。(3)十六进制形式用于输入十六进制形式的整型数据。2.实型格式说明符用于输入的单精度实型格式说明符为%f或%e用于输入的双精度实型格式说明符为%lf3.字符型格式说明符用于输入的字符型格式说明符为%c或%mc赋值运算赋值运算符为“=”。赋值表达式为变量名=表达式(1)在C语言中,“=”为赋值运算符,而不是等号;(2)赋值运算符“=”左边必须是变量名,不能是表达式;(3)赋值运算符“=”两端的类型不一致时,系统将自动进行类型转换。算术运算在C语言中,基本的算术运算符有以下几个:+加法运算符(双目运算符),或正值运算符(单目运算符)。如*+y,+*。-减法运算符(双目运算符),或负值运算符(单目运算符)。如a-3,-*。*乘法运算符(双目运算符)。如3**。/除法运算符(双目运算符)。如*/y。%模余运算符(双目运算符)。只适用于整型数据,如9%4的值为1,11%3的值为2等。关系运算在C语言中,基本的关系运算符有以下6个:<小于<=小于或等于>大于>=大于或等于==等于!=不等于结果只有两个:true或者false执行int*=2,y=3;后表达式*=(y==3)的值是(1)逻辑运算在C语言中,逻辑常量只有两种:值非零表示“真”,值为零表示“假”。其基本的逻辑运算符有以下3个:&&(逻辑与)两个量都为真时为真(1),否则为假(0)||(逻辑或)两个量中只要有一个为真时为真(1),只有都为假时为假(0)!(逻辑非)一个量为真时为假(0),假时为真(1)自增++与自减--运算符增1运算符“++”和减1运算符“--”是两个单目(只有一个运算对象)运算符,它们的运算对象只能是整型或字符型变量。增1运算符是将运算对象的值增1;减1运算符是将运算对象的值减1。假设定义变量inta=5;intb;前缀自增b=++a;//a=6b=6后缀自增b=a++;//a=6b=5sizeof运算符sizeof运算符有以下两种用法:(1)用于求得表达式计算结果所占存的字节数。其一般形式为sizeof表达式(2)用于求得*种数据类型的量所占存的字节数。其一般形式为sizeof(类型名)逗号运算符逗号“,”是C程序中常见的符号。在C语言中,逗号除作为分隔符使用外,还可以作为运算符来使用,称为逗号运算符。逗号表达式的一般形式为子表达式1,子表达式2,…,子表达式n在使用逗号运算符(逗号表达式)时,要注意以下几点:(1)逗号运算符是所有运算符中级别最低的一种运算符。(2)一个逗号表达式又可以与另一个表达式(可以是逗号表达式,也可以不是逗号表达式)连接成新的逗号表达式。(3)在许多情况下,使用逗号表达式的目的仅仅是为了得到各个子表达式的值,而并不一定要得到或使用整个逗号表达式的值。C语言中的宏定义有两种形式:符号常量定义与带参数的宏定义。符号常量定义在C语言中,允许将程序中多处用到的“字符串”定义成一个符号常量。在C语言中定义符号常量的一般形式如下:*define符号常量名字符串①由于C语言中的所有变量名、函数名等都使用小写字母,因此,符号常量名一般用大写字母表示,以便与C语言中的保留关键字相区别。②C编译系统对定义的符号常量的处理只是进行简单的替换,不作任何语法检查。③*define是一个命令,而不是语句,因此在行末不能加“;”,并且应独立占一行。④*define命令一般应出现在程序中函数的外面,其作用域围是从*define符号常量名字符串到*undef符号常量名(或文件末)带参数的宏定义带参数的宏定义的一般形式为*define宏名(参数表)字符串其中字符串中应包含在参数表中所指定的参数,并且,当参数表中的参数多于一个时,各参数之间要用逗号分隔。在使用带参数的宏定义时,应注意以下两个问题。(1)在使用带参数的宏定义时,一般应将宏定义字符串中的参数都要用括号括起来,否则经过宏展开后,可能会出现意想不到的错误。(2)在使用带参数的宏定义时,除了应将宏定义字符串中的参数都要用括号括起来,还需要将整个字符串部分也要用括号括起来,否则经过宏展开后,还会可能出现意想不到的错误。书写一个求最大值的宏定义*defineMA*(a,b)((a>b)"(a),(b))3.1语句与复合语句在C语言中,一个表达式后面跟随一个分号就构成了一个语句,这种语句称为表达式语句。在C语言中,分号(;)是表达式语句的终结符,而不是语句之间的分隔符,也就是说,分号是表达式语句的一个组成部分,只不过它位于表达式的后面。在一个函数体部,由左、右花括号括起来的语句称为复合语句,它的一般形式为{说明部分;语句部分;}3.2if语句If语句的形式为if(表达式)语句这种选择结构的流程图如图3.1所示。下面对if语句作几点说明:(1)if语句中的逻辑表达式(即条件)必须要用一对圆括号括起来。(2)if语句后的语句可以是复合语句。(3)一个if语句最后需要强调的是,在使用if语句时,一定要注意逻辑表达式的正确写法,特别是在连续使用多个if语句时更要注意。3.3if…else结构在C语言中,if…else结构的语句形式为if(表达式)语句1else语句2下面对if…else结构作以下几点说明:(1)if…else结构中的语句1与语句2都可以是复合语句。(2)在if…else结构中,语句1与语句2都可以是空语句。(3)在if…else结构中,如果在else前面有多个if语句,则else与最近的if配对。(4)如果有多个if……else结构嵌套如下:if(表达式1)语句1elseif(表达式2)语句2else…elseif(表达式n)语句nelse语句n+1则可简写成if(表达式1)语句1elseif(表达式2)语句2…elseif(表达式n)语句nelse语句n+1在if…else结构中,如果语句1与语句2都是单一的赋值语句,并且都是给同一个变量赋值,则可以用条件运算符来进行处理。下面对条件表达式作几点说明:(1)条件运算符优先级要比赋值运算符高。(2)条件运算符的优先级比关系运算符与算术运算符都要低,因此,条件表达式中的“表达式1”、“表达式2”与“表达式3”都不必用括号括起来。(3)条件运算符的结合方向为“从右到左”。在C语言中提供了一个直接实现多路分支选择的结构,称为switch结构,其一般形式如下:switch(表达式){case常量表达式1:语句1case常量表达式2:语句2…case常量表达式n:语句ndefault:语句n+1}下面对switch结构作几点说明:(1)switch结构中的表达式、常量表达式1、…、常量表达式n必须是整型或字符型。这是因为,在switch结构中,其分支数一般是有限的,并且是离散的,因此,其表达式的值也应是有限的,且是离散的。(2)同一个switch结构中的常量表达式值必须互不相同,否则就会出现矛盾的现象,即对于“表达式”的同一个值对应多种执行方案,这是错误的。(3)在switch结构中,case与default的顺序可以任意,各case之间的顺序也可以任意。(4)在执行switch结构时,当执行完*case后的语句后,将顺序执行后面case后的语句,直到遇break语句才退出整个switch结构的执行。(5)在switch结构中,如果没有default且“表达式”值不等于任何case后常量表达式的值,则直接退出switch结构而转到其后的语句执行。例3.12计算奖金。当企业利润P等于或低于0.5万元时,奖金为利润的1%;当0.5<P≤1万元时,超过0.5万元部分的奖金为利润的1.5%,0.5万元以下仍按1%计算;当1<P≤2万元时,1万元以下部分仍按前面的方法计算,超过1万元的部分其奖金按利润的2%计算;当2<P≤5万元时,2万元以下部分仍按前面的方法计算,超过2万元部分的奖金按利润的2.5%计算;当5<P≤10万元时,5万元以下部分仍按前面的方法计算,超过5万元部分的奖金按利润的3%计算;当P>10万元时,10万元以下部分仍按前面的方法计算,超过10万元部分按3.5%计算。其中P由键盘输入,计算并输出相应的奖金数W。根据图3.5所示的流程图,用if…elseif结构写出C程序如下:*include"stdio.h"main(){floatp,w;printf("inputp:");scanf("%f",&p);if(p<=0.0)w=0.0;elseif(p<=0.5)w=0.01*p;elseif(p<=1.0)w=0.005+0.015*(p-0.5);elseif(p<=2.0)w=0.0125+0.02*(p-1.0);elseif(p<=5.0)w=0.0325+0.025*(p-2.0);elseif(p<=10.0)w=0.1075+0.03*(p-5.0);elsew=0.2575+0.035*(p-10.0);printf("w=%f\n",w);}例3.14求解一元二次方程A*2+B*+C=0。相应的C程序如下:*include"stdio.h"*include"math.h"main(){doublea,b,c,d,*1,*2,p;printf("inputa,b,c:");scanf("%lf%lf%lf",&a,&b,&c);if(a==0.0){if(b==0.0)printf("ERR\n");elseprintf("*=%f\n",-c/b);}elseif(b==0.0){d=c/a;if(d<=0.0){printf("*1=%f\n",sqrt(-d));printf("*2=%f\n",-sqrt(-d));}else{printf("*1=+j%f\n",sqrt(d));printf("*2=-j%f\n",sqrt(d));}elseif(c==0.0){printf("*1=0.0\n");printf("*2=%f\n",-b/a);}else{d=b*b-4*a*c;if(d>=0.0){d=sqrt(d);if(b>0.0)*1=(-b-d)/(2*a);else*1=(-b+d)/(2*a);*2=c/(a**1);printf("*1=%f\n",*1);printf("*2=%f\n",*2);}else{d=sqrt(-d)/(2*a);p=-b/(2*a);printf("*1=%f+j%f\n",p,d);printf("*2=%f-j%f\n",p,d);}}}当型循环结构当型循环结构的流程图如图4.1所示。while循环实现当型循环结构的C语句形式为while(表达式)循环体语句功能:当表达式值≠0时,执行循环体,执行完后继续判断表达式值,只有当表达式值=0时才退出循环。例4.2从键盘输入各学生成绩,并对90分以上(包括90分)的学生人数进行计数,直到输入的成绩为负为止,最后输出成绩在90分以上的学生人数。其流程图如图4.3所示。其中变量count为整型,用于对90分以上的学生人数进行计数。相应的C程序如下:*include"stdio.h"main(){intcount;floatgrade;count=0;scanf("%f",&grade);while(grade>=0.0){if(grade>=90.0)count=count+1;scanf("%f",&grade);}printf("count=%d\n",count);}直到型循环结构直到型循环结构的流程图如图4.4所示。do__while循环do_while循环的执行过程是,首先执行循环体,然后判断条件(即计算逻辑表达式),如果条件满足(即逻辑表达式值为真),则退出循环结构;如果条件不满足(即逻辑表达式值为假),则继续执行循环体。实现直到型循环结构的C语句形式为do循环体语句while(表达式);功能:先执行循环体,然后判断表达式值,若表达式值≠0,则再次执行循环体,如此循环,直到表达式值=0为止。例4.3计算并输出下列级数和:直到*项的绝对值小于为止相应的流程图如图4.5所示。其中f用于改变每一项的符号,因为这是一个各项符号相间的级数。相应的C程序如下:*include"stdio.h"main(){intk;doublesum,d,f;sum=1.0;k=1;f=1.0;do{k=k+1;f=-f;d=1.0/(k*(k+1));sum=sum+f*d;}while(d>=1.0e-4);printf("sum=%lf\n",sum);}当型循环结构与直到型循环结构的区别与联系当型循环结构与直到型循环结构既有共同之处,又有区别。主要体现在以下几个方面。(1)在while循环中,其循环体可以一次也不执行(即执行while循环结构的一开始,其条件就不满足)。(2)不管是while循环结构还是do—while循环结构,在循环体部必须要有能改变条件(即逻辑表达式值)的语句,否则将造成死循环。(3)对于有些问题既可以用while循环结构来处理,也可以用do—while循环结构来处理。(4)不管是while循环结构还是do—while循环结构,其循环体如果包含一个以上的语句,应以复合语句形式出现。C语言提供的for循环属于当型循环结构,其一般形式为for(表达式1;表达式2;表达式3)循环体语句(组)它等价于下列的当型循环结构:表达式1;while(表达式2){循环体语句表达式3;}下面对for循环语句作几点说明:(1)在for语句中,三个表达式中的任何一个表达式均可省略,但其中的两个“;”不能省略。(2)下列两个循环都是死循环:for(表达式1;;表达式3)循环体与for(;;)循环体因为它们都没有用于判断循环是否结束的条件(即表达式2)。(3)for循环本质上也是当型循环结构,只不过它对于事先可以确定循环次数的问题特别方便。(4)在for循环中,循环体也可以是复合语句(即用一对花括号{}括起来的语句组)。循环的嵌套所谓循环的嵌套是指一个循环体又包含了另一个完整的循环结构。C语言允许循环结构嵌套多层。循环的嵌套结构又称为多重循环。例4.6计算并输出10以(包括10)所有自然数的阶乘值。即计算1!,2!,3!,4!,5!,6!,7!,8!,9!,10!。采用的方法是,对于10以的每一个自然数分别求它们的阶乘值。其流程图如图4.7所示。显然,这是一个二重循环结构。相应的C程序如下:*include"stdio.h"main(){intn,k;doubles;for(n=1;n<=10;n=n+1){s=1.0; for(k=1;k<=n;k=k+1)s=s*k; printf("%2d!=%16.7f\n",n,s);}}break语句C语言中的break语句有以下两个功能:(1)跳出switch结构;(2)退出当前循环结构,包括while结构、do…while结构和for循环结构。continue语句continue语句的功能是结束本次循环的执行,但不退出循环结构。下面举两个例子来说明continue语句的使用。例4.10输出100~200之间所有能被7或9整除的自然数。相应的C程序如下:*include"stdio.h"main(){intn;for(n=100;n<=200;n=n+1){if(n%7!=0)&&(n%9!=0))continue;/*结束本次循环,继续进行下次循环*/printf("%d\n",n);}实际上,上述程序等价于*include"stdio.h"main(){intn;for(n=100;n<=200;n=n+1){if(n%7==0)||(n%9==0))printf("%d\n",n);}}函数的概念在C语言中,函数分为以下两种。(1)标准库函数这种函数用户不必定义,但可直接使用。例如scanf(),printf(),fabs(),sqrt(),e*p(),sin(),cos()等都是C语言中常用的库函数。(2)用户自己定义的函数这种函数用以解决用户的专门问题,一般由用户自己编写。例5.1从键盘输入两个正整数m与n(m≥n),求的值(即求)。其C程序如下:*include"stdio.h"main()/*主函数*/{intm,n;intp();/*说明本函数中要调用的函数p()是整型*/scanf("%d,%d",&m,&n);if(m>=n)printf("%d\n",p(m)/p(m-n));elseprintf("m<n!\n");}intp(k)/*计算阶乘值的函数*/intk;{ints,i;s=1;for(i=1;i<=k;i=i+1)s=s*i;return(s);}下面对函数作几点说明:(1)一个完整的C程序可以由若干个函数组成,其中必须有一个且只能有一个主函数main()。(2)一个完整C程序中的所有函数可以放在一个文件中,也可以放在多个文件中。①在编译命令行中键入各个函数所在的文件名(各文件名之间用空格分隔)。②在主函数中用*include语句将各函数所在的文件包含进来。(3)C语言中的函数没有从属关系,各函数之间互相独立,可以互相调用。函数的定义在C语言中,函数定义的一般形式为类型标识符函数名(形参表列)形参类型说明{说明部分语句部分}在定义C函数时要注意以下几点。(1)函数类型标识符同变量类型说明符,它表示返回的函数值类型。(2)如果省略函数的类型标识符,则默认为是int型。(3)C语言允许定义空函数。如dummy(){}(4)函数中返回语句的形式为return(表达式);或return表达式;(5)如果“形参表列”中有多个形式参数,则它们之间要用“,”分隔。(6)C语言允许在形参表中直接对形参的类型进行说明。函数的调用函数调用的一般形式为函数名(实参表列)(1)函数调用可以出现在表达式中(有函数值返回);也可以单独作为一个语句(无函数值返回)。(2)实参表中的各实参可以是表达式,但它们的类型和个数应与函数中的形参一一对应。(3)在调用函数中,通常要对被调用函数的返回值类型进行说明(一般在调用函数的函数体中的说明部分),包括函数类型、函数名和一对圆括号。例5.2下列程序的功能是计算输出一个圆台两底面积之和。*include"stdio.h"main(){doubler1,r2;doubleq();printf("inputr1,r2:");scanf("%lf,%lf",&r1,&r2);printf("s=%f\n",q(r1,r2));}doubleq(*,y)double*,y;{doubles;s=3.1415926*(***+y*y);return(s);}但C语言规定,在以下几种情况下可以不在调用函数中对被调用函数作类型说明:①被调用函数为整型或字符型,自动按整型处理。②被调用函数的定义出现在调用函数之前。③在调用函数之前已经由别的函数(它可能也要调用该被调用函数)对被调用函数作了类型说明。(4)C语言虽不允许嵌套定义函数,但可以嵌套调用函数。形参与实参的结合方式1.地址结合所谓地址结合,是指在一个模块调用另一个模块时,并不是将调用模块中的实参值直接传送给被调用模块中的形参,而只是将存放实参的地址传送给形参。2.数值结合所谓数值结合,是指调用模块中的实参地址与被调用模块中的形参地址是互相独立的,在一个模块调用另一个模块时,直接将实参值传送给形参被存放在形参地址中。例5.3分析下列C程序:voidswap(*,y)int*,y;{intt;t=*;*=y;y=t;return;}*include"stdio.h"main(){int*,y;scanf("*=%d,y=%d",&*,&y);swap(*,y);printf("*=%d,y=%d\n",*,y);}在这个程序中共有两个函数。在主函数中分别为整型变量*与y输入数据,然后调用函数swap(*,y)。而函数swap(*,y)的功能是实现变量*值与y值的交换。但在实际运行该程序时,如果从键盘输入*=6,y=8则输出的结果为*=6,y=8即没有达到交换的目的。这是因为在主函数中调用函数swap()时,只是将实参*和y的值分别传递给了swap()函数中的形参*和y,但由于主函数中的实参*和y与函数swap()中的形参*和y在计算机中的存储地址是不同的,因此,在函数swap()中虽然交换了形参*与y的值,但实参*与y的值实际上没有改变,即它们没有被交换。由此可以看出,在形参与实参为数值结合的情况下,实参与形参在计算机存中的存储地址不是同一个,因此,即使在被调用函数中改变了形参值,调用函数中的实参值也是不会被改变的。局部变量与全局变量1.局部变量在函数部定义的变量称为局部变量。函数部定义的变量只在该函数围有效,因此,不同函数中的局部变量可以重名,互不混淆。2.全局变量在函数外定义的变量称为全局变量除非十分必要,一般不提倡使用全局变量,其原因有以下几点:①由于全局变量属于程序中的所有函数,因此,在程序的执行过程中,全局变量都需要占用存储空间,即使实际正在执行的函数中根本用不着这些全局变量,它们也要占用存储空间。②在函数中使用全局变量后,要求在所有调用该函数的调用程序中都要使用这些全局变量,从而会降低函数的通用性。③在函数中使用全局变量后,使各函数模块之间的互相影响比较大,从而使函数模块的“聚性”差,而与其他模块的“耦合性”强。④在函数中使用全局变量后,会降低程序的清晰性,可读性差。动态存储变量与静态存储变量1.用户程序的存储分配一般来说,用户程序在计算机中的存储分配如图5.1所示。其中:程序区用于存放程序;静态存储区是在程序开始执行时就分配的固定存储单元,如全局变量;动态存储区是在函数调用过程中进行动态分配的存储单元,如函数形参、自动变量、函数调用时的现场保护和返回地址等。2.变量的存储类型①数据类型:如整型(int)、实型(float)、字符型(char)、双精度型(double)等。②数据的存储类型:分为自动类型(auto)、静态类型(static)、寄存器类型(register)、外部类型(e*tern)。例5.4计算并输出1~5的阶乘值。其C程序如下:intfac(n)intn;{staticintf=1;f=f*n;return(f);}*include"stdio.h"main(){inti;for(i=1;i<=5;i=i+1)printf("%d!=%d\n",i,fac(i));}下面对静态存储变量作几点说明:①形参不能定义成静态类型。②对局部静态变量赋初值是在编译时进行的,在调用时不再赋初值;而对自动变量赋初值是在调用时进行的,每次调用将重新赋初值。③定义局部静态变量时若不赋初值,则在编译时将自动赋初值0;但在定义自动变量时若不赋初值,则其初值为随机值。④若无多大必要,尽量不用局部静态变量。3.外部变量全局变量如果在文件开头定义,则在整个文件围的所有函数都可以使用该变量。一般来说,全局变量有以下几种用法:①在同一文件中,为了使全局变量定义点之前的函数中也能使用该全局变量,则应在函数中用e*tern加以说明。②使一个文件中的函数也能用另一个文件中的全局变量。③利用静态外部变量,使全局变量只能被本文件中的函数引用。部函数与外部函数在C语言中,函数可以分为部函数与外部函数。只能被本文件中其他函数调用的函数称为部函数,部函数又称为静态函数。定义部函数的形式如下:static类型标识符函数名(形参表)定义外部函数的形式如下:[e*tern]类型标识符函数名(形参表)人们在解决一些复杂问题时,为了降低问题的复杂程度(如问题的规模等),一般总是将问题逐层分解,最后归结为一些最简单的问题。例5.5编写一个C函数,对于输入的参数n,依次打印输出自然数1到n。这是一个很简单的问题,实际上不用递归就能解决,其C函数如下:*include"stdio.h"wrt(intn){intk;for(k=1;k<=n;k++)printf("%d\n",k);return;}解决这个问题还可以用以下的递归函数来实现:*include"stdio.h"wrt1(intn){if(n!=0){wrt1(n-1);printf("%d\n",n);}return;}功能:对于输入的参数n,依次打印输出自然数1到n自己调用自己的过程称为递归调用过程。在C语言中,自己调用自己的函数称为递归函数。递归分为直接递归与间接递归两种。所谓直接递归,是指直接调用函数本身。例5.6编写一个函数,其功能是判断给定的正整数是否是素数,若是素数则返回函数值1,否则返回函数值0。其C函数如下:*include"math.h"sushu(intn){intk,i,flag;k=sqrt((double)n);i=2;flag=0;while((i<=k)&&(flag==0)){if(n%i==0)flag=1;i=i+1;}return(!flag);}例5.8Hanoi塔问题。相传古代印度有一座Bramah庙,庙中有三根插在黄铜板上的宝石柱,在其中的一根柱子上放了64个金盘子,大盘在下,小盘在上,称为Hanoi塔。有一天,庙里的和尚们想把这些盘子从一根柱子上移到另一根柱子上,规定每次只允许移动一个盘子,并且,在移动过程中都不允许出现大盘子压在小盘子上面的现象,但在移动盘子的过程中可以利用三根柱子中的任何一根。为了使问题具有普遍性,假设圆盘数为n,按直径从小到大依次编号为1,2,…,n;三根柱子的名称分别为*,Y,Z。开始时,n个圆盘按从大到小的顺序(即下面放大圆盘,上面放小圆盘)放在*柱子上,现在要将*柱子上的n个圆盘移到Z柱子上,其移动的原则如上所述。这个问题称为n阶Hanoi塔问题。可以写出C程序如下:*include"stdio.h"main(){intn;char*='*',y='Y',z='Z';voidhanoi();printf("inputn=");scanf("%d",&n);hanoi(n,*,y,z);}voidhanoi(n,*,y,z)intn;char*,y,z;{voidmove();if(n==1)move(*,n,z);else{hanoi(n-1,*,z,y);move(*,n,z);hanoi(n-1,y,*,z);}return;}voidmove(*,n,z)intn;char*,z;{printf("%c(%d)---->%c\n",*,n,z);}编译预处理功能是C语言的一个重要特点。所谓编译预处理,是指C语言编译系统首先对程序模块中的编译预处理命令进行处理。C语言提供的编译预处理命令主要有以下3种:(1)宏定义;(2)文件包含命令;(3)条件编译命令。编译预处理命令一般是在函数体的外面。正确使用编译预处理命令,可以编写出易于调试、易于移植的程序模块。文件包含命令文件包含是指一个源文件可以将另一个指定的源文件包括进来。文件包含命令的一般形式为*include〈文件名〉或*include"文件名"其功能是将指定文件中的全部容读到该命令所在的位置后一起被编译。在使用文件包含命令时,要注意以下几个问题:(1)当*include命令指定的文件中的容改变时,包含这个文件的所有源文件都应该重新进行编译处理;(2)一个*include命令只能指定一个被包含文件,如果需要包含多个文件,则要用多个*include命令实现;(3)被包含的文件应该是源文件,不能是经编译后的目标文件;(4)文件包含可以嵌套使用,即被包含的文件中还可以使用*include命令;(5)由*include命令所指定的文件中可以有任何语言成分,因此,通常可以将经常使用的、具有公用性质的符号常量、带参数的宏定义以及外部变量等集中起来放在这种文件中,以尽量避免一些重复操作。6.1一维数组一维数组的定义与引用定义一维数组的一般形式如下:类型说明符数组名[常量表达式];其中类型说明符是定义数组中各元素的数据类型,常量表达式是说明数组的大小(即数组中元素的个数。数组的说明与变量的说明一样,其作用是为数组分配存储空间。关于数组的说明要注意以下几个问题:(1)数组名的命名规则与变量名相同。(2)说明数组大小的常量表达式必须为整型,并且用方括号括起来(不能用圆括号)。(3)说明数组大小的常量表达式中可以包含符号常量,但不能是变量。例6.1下面的程序说明了如何对数组定义和引用数组元素:*include"stdio.h"*defineN5main(){inti,a[N];for(i=0;i<N;i=i+1)a[i]=i;for(i=0;i<N;i=i+1)printf("%5d",a[i]);printf("\n");}在这个程序中,首先定义了一个长度为5的整型一维数组a,然后利用for循环对其中的每一个元素(a[0]~a[4])进行赋值,最后利用for循环输出这5个元素值。在C语言中,凡是一般简单变量可以使用的地方都可以使用数组元素。一维数组的初始化在C语言中,给数组元素提供数据的方法有以下3种。(1)利用赋值语句逐个对数组中的元素进行赋值。(2)利用输入函数逐个输入数组中的各个元素。例如,*include"stdio.h"main(){inti,a[5];for(i=0;i<5;i=i+1)scanf("%d",&a[i]);}其中&a[i]表示取数组元素a[i]的地址。(3)初始化。下面对静态一维数组的初始化作三点说明:(1)可以只给数组的前若干个元素赋初值,此时后面的元素均将自动赋以初值0。(2)在对全部元素赋初值时,说明语句中可以不指定数组长度,其长度默认为与初值表中数据的个数相同。(3)虽然标准C语言规定只能对“静态存储”的数组进行初始化,即除了可以对外部(全局)数组进行初始化外,还可以对用static说明的局部数组进行初始化。例6.3分析下列程序的输出结果:*include"stdio.h"main(){intk,*[5];staticinty[5];intz[5]={0,0,0};for(k=0;k<5;k++){printf("%5d%5d%5d",*[k],y[k],z[k]);printf("\n");}}6.2二维数组二维数组的定义与引用定义二维数组的一般形式如下:类型说明符数组名[常量表达式1][常量表达式2];二维数组的初始化与一维数组一样,也可以对静态存储的二维数组进行初始化。在对二维数组进行初始化时要注意以下几点。(1)在分行给二维数组赋初值时,对于每一行都可以只对前几个元素赋初值,后面未赋初值的元素系统将自动赋初值0;并且,还可以只对前几行元素赋初值。(2)在给全部元素赋初值时,说明语句中可以省略第一维的长度说明。(3)在分行赋初值时,也可以省略第一维的长度说明6.3字符数组与字符串字符数组的定义与初始化定义字符数组的一般形式如下:char数组名[常量表达式];一维字符数组char数组名[常量表达式1][常量表达式2];二维字符数组(1)当对字符数组中所有元素赋初值时,数组的长度说明可以省略。(2)可以只对前若干元素赋初值。(3)虽然标准C语言规定只能对“静态存储”的字符数组进行初始化,即除了可以对外部(全局)字符数组进行初始化外,还可以对用static说明的局部字符数组进行初始化。字符串C语言规定,字符串常量(简称字符串)要用一对双撇号括起来。在一个字符串常量中,最后还包括一个结束符‘\0’。C语言允许用字符串常量对字符数组进行初始化。字符数组与字符串的输入与输出1.输入输出一个字符(格式说明符为%c)在用于输入时,输入项为数组元素地址。在具体输入时,各字符之间不要分隔,字符也不要用单撇号括起来。在用于输出时,输出项为数组元素。2.输入输出一个字符串(格式说明符为%s)在用格式说明符%s进行输入输出时,其输入输出项均为数组名。但在输入时,相邻两个字符串之间要用空格分隔,系统将自动地在字符串最后加结束符'\0'。字符串处理函数下面简单介绍一些常用的字符串处理函数。(1)puts(字符数组名)功能:输出一个字符串到终端。(2)gets(字符数组名)功能:从终端输入一个字符串到字符数组,并返回字符数组的地址。(3)strcat(字符数组1,字符串2)功能:将字符串2连接到字符串1的后面,并返回字符串1的地址。(4)strcpy(字符数组1,字符串2)功能:字符串2拷贝到字符数组1中。(5)strcmp(字符串1,字符串2)功能:比较字符串。这个函数的返回值如下:若字符串1=字符串2,则返回值为0;若字符串1>字符串2,则返回值为正整数;若字符串1<字符串2,则返回值为负整数。(6)strlen(字符串)功能:测试字符串长度。(7)大小写转换函数大小写转换函数有以下两个:strlwr(字符串)将字符串写字母转换成小写字母。strupr(字符串)将字符串中小写字母转换成大写字母。6.4数组作为函数参数形参数组与实参数组的结合例6.8用选择法对无序序列进行排序。C程序如下:/*select.c*/select(b,n)intn,b[];{inti,j,k,d;for(i=0;i<=n-2;i=i+1){k=i;for(j=i+1;j<=n-1;j=j+1)if(b[j]<b[k])k=j;if(k!=i){d=b[i];b[i]=b[k];b[k]=d;}}}/*e*.c*/*include"stdio.h"*include"select.c"main(){intk;static

温馨提示

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

评论

0/150

提交评论