已阅读5页,还剩178页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言总复习,一、C语言的数据表示,1. 1 常量和变量 1. 2 表达式 1. 3 数据类型 简单类型、结构类型、指针类型 1.4 输入、输出,1.1 常量和变量,1.常量 常量是在程序执行中,值不发生改变的数据。其值预先决定,之后不变。有不同的数据类型。,(1)常数 例如的: 整数:+5 、-3、017(八进制)、0x1f(16进制) 实数(浮点数):3.14 、-1.2E-3 、1E10 单个字符: A,占一个字节 ,转义字符 非法 77 (八进制ASCII码63,?),78非法 x3f (十六进制ASCII码63,?) x3g非法 字符串: “A” 后面有0,占两个字节,在程序中 int a = 0x6d,是把一个十六进制的数赋给变量a 注意这里的0x必须存在。 在程序中 int a = 06d, 是一个八进制的形式。 在转义字符中,x6d 才是合法的,0不能写,并且x是小写。 141 是合法的, 0是不能写的。 108是非法的,因为不可以出现8。 ,转义字符 非法 ” 77 (八进制ASCII码63,?),78非法 x3f (十六进制ASCII码63,?) x3g非法 转义字符占1个字节。,(2)符号常量 给常量起标识符名字。 C语言的符号常量(用宏定义): #define PI 3.14159265 好处:提高程序易读性;方便修改常量的值; 注意: 1.一般用大写字母。 2, #define M 3 不是C语句,后面没有“;”。 3.可以做M+1,不能做M+.,(3)地址常量 当数组在定义时,其变量名为其首地址,是地址常量。 int a10;可以做a+1,不能做a+.,1.1 常量和变量,2 变量 用各种操作来改变值数据。 从“名”和“值”两个角度认识变量,(1)变量名 每个变量,要在使用前定义变量的名字,遵循标识符命名规则。 只能用字母、数字和下划线组成。 不能以数字开头。 不能用保留字(int, main)。 关键字不可以作为用户标识符号。main define scanf printf 都不是关键字。迷惑你的地方If是可以做为用户标识符。因为If中的第一个字母大写了,所以不是关键字。,变量定义就是申请数据的存储空间,登记数据的各种存储特性。 例如: int m ;2个字节 -215215-1(-3276832767) long n; 4个字节 -231231-1 char ch; 1 个字节 0255 float x; 4个字节 3.4 (10-38 1038) double y; 8个字节 1.7(10-308 10308) 可以用sizeof获得字长 sizeof(char)=1 sizeof(int)=2 sizeof(double)=8,(2)变量的值 变量值就是由变量名所指定空间上的存储数据内容。即变量的当前值。 数据内容用语言的操作语句来改变。 赋值语句;键盘输入语句; char chx; int m; /* 变量的定义 */ chx=A; m=12*3; /* 赋值语句 */ scanf(“%d”, /* 键盘输入语句 */ 在程序运行时,将数据存入制定内存空间。,变量初始化:定义变量时同时确定变量初值。 例如: char chy=a; int weight=2;,1.2 C语言的表达式,1、算术表达式 2、关系表达式 3、逻辑表达式 4、赋值表达式 5、逗号表达式 6、条件表达式 7、其他表达式,C语言的表达式: 使用规定的运算符, 将常量、变量、函数(调用)连结的一个有意义的式子。,1、算术表达式,用算术运算符来表示对数据的算术运算求值过程。 算术运算符: + - * / % 2/3结果是0,2%3结果是2,2.0%3错,注意不同类型运算问题:,强制类型转换: 一定是 (int)a 不是 int(a),注意类型上一定有括号的。 注意(int)(a+b)和(int)a+b 的区别。 前是把a+b转型,后是把a转型再加b。,2、关系表达式,关系运算符: = 0 , sin(x)=0.5, (a+b)=(c*d) 注意语法合理与数学逻辑错误问题: 分析:10=a=15 a=9,10=a=15,10=a 假 0,0=15 真,所以要写成10=a&a=15,a=bc等价于a=(bc),3、逻辑表达式,用逻辑表达式来表示对数据的逻辑关系判断,运算结果是逻辑值“真”1或者“假”0。 C逻辑运算符包括: ! ,a,c均按非0(即真)处理,逻辑运算规律,在&(与)表达式中,若&的左端为假, 则不再计算另一端,该表达式值肯定为 0(假)。 在|(或)表达式中,若|的左端为真,则不再计算另一端,表达式的值必定为 1(真)。,int a=5,b=1 k=a0 k?b?,假,后面不算了,k=0,b=1,判断闰年的条件是:能被4整除但不能被100整除,或能被400整除。,(x4= =0&x100!=0|x%400=0),水仙花数是指一个三位正整数,其各位数字的立方和等于该数本身,(k*100+m*10+n= =k*k*k+m*m*m+n*n*n),三角形的基本条件,(a+b)c)&(c+b)a)&(c+a)b),4、赋值表达式=,+=,-=,*=,/=, +(单目),- (单目) 级别仅高于逗号表达式,右结合 变量=表达式,int a=3,c=2,b a=b=c;,n*=m+2 相当于 n=n*(m+2) k=i+; 先k=i,再i=i+1 k=+i; 先i=i+1,再k=i,c赋值给b,b=2 b赋值给a,a=2,5、条件表达式 e1?e2:e3 若e1为真,表达式的值为e2,否则为e3. (- -a=b+)? -a : b +,5-1=4 T a=4,-a a=3 表达式的值为3,a=5,b=4,4-1=5 F b=6,b + b=7 表达式的值为6,a=4,b=5,条件表达式的值的类型为e2,e3二者中类型较高者。 如果y=5; y3?-1.0:2 其值为2.0,6、逗号表达式 表达式的值等于最后一个表达式的值,运算等级最低! a=5,b=2,c=3 a=7+b+c, a+ a=(7+b+c, a+),a=12,a=5,7、强制类型转换表达式(单目) int m; sqrt(float) m);,并没有改变m的类型和数值,三种取整丢小数的情况:,、int a =1.6; 、(int)a; 、函数返回值,位运算,总的处理方法:几乎所有的位运算的题目都要按这个流程来处理(先把十进制变成二进制再变成十进制)。 例1: char a = 6, b; b = a2; 这种题目的计算是先要把a的十进制6化成二进制,再做位运算。,理解记忆运算符表,右结合 单目运算符 赋值运算符 条件运算符,例 假设x =10,y = 20,计算38 + 5 x + y & 38 % 5 = y的值,在容易出错或不确定的地方按照自己的本意给表达式加括号,38 + 5 x + y & 38 % 5 = y 43 30, ,表达式的求值过程, 3,0,1,运算符的优先级和结合性,0,1.3 数据类型,数据类型:在高级语言的数据表示机制中,数据类型(data tyPe )是个核心概念。,简单类型,构造类型,指针类型,整型,实型,字符型,数组,结构体,共用体,数值型,枚举型,空类型,1. 3 数据类型,(1)整型(输入、输出格式 “%d”) 类型名 字节数 数值范围 int 2 -32768 32767 short 2 -32768 32767 long 4 -2147483648 2147483647 还有无符号整型(输入、输出格式 “%u”) Unsigned int 2 0 65535 Unsigned short 2 0 65535 Unsigned long 4 0 4294967295,1.简单类型,(2) 实型(输入、输出格式 “%f”) 实型(float )数据的值集是实数集的一个有限子集. -3.4e38, -3.4e-39, 3.4E-38, 3.4E38,1.简单类型,类型名 字节数 输入、输出格式 有效数字位 float 4 %f 7 doubule 8 %lf 16 long doubule 16 %lf 19,不要以为是长整型,E38 非法,(3) 字符型(输入、输出格式 “%c”) ASCII码,一个字符占1字节; char ca; ca=#; 注意转义字符 的使用。,(4)字符串(输入、输出格式 “%s”) 所谓“字符串”是指若干有效字符的序列。语言字符串可以包括字母、数字、专用字符、转义字符等。 字符串常量:使用双引号 “China“ “BASIC“ “a+b=c“ “Li-Li“ “39.4“ “%dn“ “解放军“ 字符型的一维数组(相当于字符串变量) char st8, str10; strcpy(st,“12345“); strcpy(str,st); 不能st=“12345”; str=st;,2. 结构类型 “结构”一般可以称为数据元素,在不同的结构类型中,数据元素会有特定的名称。 结构类型的数据由更加基本的成分组成。 这些成分称为“数据项”,结构的子成员。,1. 3 数据类型,(1) 数组 A0 A1 A2 A3 A4 A5 A6 A7 10 20 30 40 50 60 70 80 一个数组(array )是由相同类型的若干数组元素构成的有限序列。 C 语言的数定义 : int B8 , A8 ; char C10;,2. 结构类型,例 日期类型的定义,(2) 结构体,C语言中实现: struct Date int month ; /*月*/ int day; /*日*/ int year; /*年*/ ; struct Date myd=12,16, 1978; 系统分配给它的内存是各成员所需内存量的总和。本例是6.,(1)指针:变量名在内存中的存储地址。 (2)指针变量 int i=12, *p; P= 把存放变量i 的地址的变量p 称作指针变量。 指针变量的存放内容是数据的地址。,3. 指针类型,(3)指针引用变量 指针变量可以指向各种不同的数据类型,因此指针变量也要有不同的指针类型。如: int m, *p; float x,*q; int a,*r m=12; p=,注意:是否用&,1.4 输入、输出,输出: printf(“.”, .) %d, %6d, %ld %c, %s %f , %10.2f , %lf, %20.8lf,n=3; printf(“n %d,%d,%d”, n,+n,n+); 计算从右到左,输出从左到右。,%s是输出以指定首地址到第一个0或空格之间的字符串。 char a=“abcd efg”,*p=a; printf(“%s”,*+p);,bcd,5,5,3,1.4 输入、输出,输入: scanf(“.”, .) %d, %ld 对应int long %c, %s 对应char char str %f , %lf 对应flaot double Scanf(“%d%d%*d%d”, 跳过输入的第三个数据。,常见错误 int a,b;char d,e20; scanf(“%d,%fn”,格式化输入函数scanf,输入/输出,输入/输出,说明:(1)负号“-”表示该输出项以左对齐方式输出,缺省表示以右对齐方式输出; (2)m称字段宽度,表示该输出项所占字符个数; (3)n表示小数部分占用的字符个数; (4)如果输出项的实际位数小于m,则用空格补足,如果大于m,则按实际的位数输出。,输入/输出,(1)表达式语句 (2)流程控制语句 (3)复合语句,C语言语句, 指令语句 非指令语句,数据定义语句 float x; int m; 编译预处理 宏定义 #define PI 3.14159 文件包含处理 #include ,二、C语言的程序结构与相关语句,表达式语句,1. 表达式语句的组成: 由一个表达式后接一个分号组成的。 i=i+1 (是表达式,没有构成语句) i=i+1; (是语句) x+y; (是合法语句,但没有实际意义) 表达式语句的分类: 赋值语句: i=1; c=getchar(); 函数调用语句: printf(n Hello,world !“); 空语句。其形式为: ; 逗号表达式语句: +a,-b; 复合语句:t=a;a=b;b=t;,完成一定的控制功能。9种控制语句: 判断语句 条件判断语句 if()else 多分支选择语句 switch()case 循环语句 循环次数控制语句 for() 先判断后执行循环控制语句while() 先执行后判断循环控制语句dowhile() 转移控制语句 直接转移语句 goto 终止语句 break(用在循环结构、swicth) 跳转语句 continue (仅用在循环结构) 返回语句 return,流程控制语句,复合语句,一组语句括在一对花括号之中,称复合语句。 c=getchar(); putchar(c); 注意,一个复合语句的后花括号之后不应再写分号。 在语法上是一个整体,相当于一个语句。 凡是能够使用简单语句的地方,都可以使用复合语句。一个复合语句中又可以包含另一个或多个复合语句。,二、C语言的程序结构与相关语句,程序的三种基本结构: 顺序结构 选择结构 if()else switch()case 循环结构 for(); while(); do ; while(),选择结构,单分支结构 if(a=b)printf(“yes”); 双分支结构 if(a=b) printf(“yes”); else printf(“no”); else 是与最接近的if且没有配对else的相组合的。 多分支结构 switch_case,表达式类型任意,switch (表达式) case 常量表达式1 : 语句1 break ; case 常量表达式2 : 语句2 break ; case 常量表达式n : 语句n break ; default : 语句n+1 break; ,算术表达式(int char),相当于语句标号,没有分号,多分支选择语句,switch(表达式) case 常量表达式1: 语句序列1; break; case 常量表达式2: 语句序列2; break; case 常量表达式n: 语句序列n; break; default:语句序列n+1; ,根据“表达式”的值从上至下去寻找与表达式的值相匹配的“case常量表达式”,执行一个分支后,再执行下一个分支,直到break结束,然后执行switch结构后面的程序。 找不到匹配的入口标号时,执行“语句序列n+1”,然后结束。顺序向下执行程序。,一定要注意 有break 和没有break的差别,没有break时候,只要有一个case匹配了,剩下的都要执行,有break则是直接跳出了swiche语句。,main() int a=1,b=1; switch (a) case 1: switch (b) case 0:printf(“$”);break; case 1:printf(“#”);break; case 2:printf(“*”); case 2:printf(“”); case 3:printf(“”); break; case 4:printf(“ ,a=1 case 1:swtch(1) b=1 printf #, break 跳出switch(b)结构 进入switch(a)结构 case 2:printf case 2:printf break 跳出switch(a)结构,#,for,while,do-while三种结构,循环变量初始化,继续循环条件,改变循环变量是不可缺少的三个环节。 for常用于循环次数已知的问题中。括号中的两个“;”不可省。 do-while()循环的最后一个while();的分号一定不能够丢。 while与do-while常用于循环次数未知的问题中。 写程序的时候一定要注意,循环一定要有结束的条件,否则成了死循环。,注意,在for和while语句之后一般没有分号 有分号表示循环体就是分号之前的内容(空循环体) while (i 100); i+; for (i = 0; i 100; i+); printf(“%d“, i); if,swtich,while,for后面的语句只能是一句,因此,多句时别忘了。 do-while()循环的最后一个while();的分号一定不能够丢。,在while( e )和for( ;e ;)中的e是循环继续的条件,不能写其它条件!如果缺省,就是死循环!,在if(e),while( e )和for( ;e ;)中e的值是逻辑值(0或非0)e一般是关系表达式,逻辑表达式或变量。,if(x=1),if(x=1),main() int i=1; doi-;while(i+); printf(“%d”,i-); A) -1 B) 0 C) 1 D)陷入死循环,break,coutinue,break只能用于switch和循环语句中,作用提前终止本层次switch和循环。 coutinue是跳过循环体内尚未执行的语句,接着执行下次循环。,常用的循环算法,求素数、水仙花数、最小公倍数、最大公约数、分解多位数的数字,累加,累乘,分解质因数等。 各种有规律的图案。,while( m) k = m%10 ; /*求最低位的数字*/ m=m/10; /*除去最低位的数字*/ ,分解多位数的数字,判断素数,main() int i,x,flag=1; scanf(“%d”, ,求阶乘x!,long facto (int x ) long y; for ( y=1; x0; -x ) y *= x; return(y);,main() long y; for ( y=1; x0; -x ) y *= x; printf(“%ld”,y);,main( ) int m, n; long cmn, facto( ); scanf (“%d%d“, ,求C(m,n) = m!/(n!*(m-n)!),嵌套循环,就是有循环里面还有循环,这种比较复杂,要一层一层一步一步耐心的计算,一般记住两层是处理二维数组的。,while(c=getchar())!=n) 和 while(c=getchar() !=n) 的差别,先看a = 3 != 2 和(a=3)!=2 的区别: (!=号的级别高于=号 所以第一个先计算 3!=2) 第一个a的数值是得到的1;第二个a的数值是3。,三 数组,数组要素: 1. 数组名:数组的起始地址 2. 基类型:数组元素的数据类型 3. 数组长度:数组元素的个数 4.数组的存储:连续的存储单元。二维数组按行存放,数组的定义 类型标识符 数组名数组长度,错误的定义是: 或 int n; int n=10; scanf(“%d“,定义int a5时, a0,a1=?,随机数!,只有int a5=3后,后面几项自动赋0,常量表达式,数组的初始化,合法: int a=1,2,3,4,5; int i 3=1,2,3,4,5,6; int a5=1,2,3; int b34=1,3; char a4=“boy” char a3=b,o,y,不合法: int a5=,2, ,4,5; int i2 =1,2,3,4,5,6; int a5= ; char a4=boy,数组的初始化,一维和二维的,一维可以不写,二维第二个一定要写 int a=1,2 合法。 int a4=2,3,4合法。 但int a4=2,3,4非法。,一维数组元素的引用 引用数组元素使用数组名和该元素在数组中的下标。,数组下标的取值范围是0, 数组长度1,二维数组元素的引用与一维数组类似,分别用三种方法(数组元素下标法、数组名地址法、指针变量法)访问数组元素。,#include void main() int a5=1,3,5,7,9, i, *p; for(i=0;i5;i+)printf(“%d “, ai ); /*下标法*/ printf(“n“); for(i=0;i5;i+)printf(“%d “, *(a+i) ); /*地址法*/ printf(“n“); for(p=a;pa+5;p+)printf(“%d “, *p ); /*指针变量*/ ,对a10这个数组的讨论。,、a表示数组名,是第一个元素的地址,也就是元素a0的地址。 、a是地址常量,所以只要出现a+,或者是a=a+2赋值的都是错误的。 、a是一维数组名,所以它是列指针,也就是说a+1是跳一列。,1.输入与输出,例如:对一维数组有 int a10; 定义后, 输入格式为: for(i = 0; i 10; i+) scanf(“%d”, ,对二维数组有 int a32; 定义后, 输入格式为: for(i = 0; i 3; i+) for(j=0; j2; j+) scanf(“%d”,2.数组遍历,遍历:下标 i+ 指针 p+ 结束条件: in 字符串 ai!=0,对a33的讨论,、a表示数组名,是第一个元素的地址,也就是元素a0的地址。 、a是地址常量,所以只要出现a+,或者是a=a+2赋值的都是错误的。 、a是二维数组名,所以它是行指针,也就是说a+1是跳一行。 、a0、a1、a2也都是地址常量,不可以对它进行赋值操作,同时它们都是列指针,a0+1,a1+1,a2+1都是跳一列。 、注意a和a0 、a1、a2是不同的,它们的基类型是不同的。前者是一行元素,后三者是一列元素。,二维数组做题目的技巧:,如果有a33=1,2,3,4,5,6,7,8,9这样的题目。 步骤一:把他们写成: 第一列 第二列 第三列 a0 1 2 3 第一行 a1 4 5 6 第二行 a2 7 8 9 第三行,步骤二:这样作题目时很简单: *(a0+1)我们就知道是第一行的第一个元素往后面跳一列,那么这里就是a01元素,所以是。 *(a1+2)我们就知道是第二行的第一个元素往后面跳二列。那么这里就是a12元素,所以是6。 一定记住:只要是二维数组的题目,一定是写成如上的格式,再去做题目,这样会比较简单。,二维数组中的行指针,int a12; 其中a现在就是一个行指针,a+1跳一行数组元素。 搭配(*)p2指针 a0,a1现在就是一个列指针。a0+1 跳一个数组元素。搭配*p2指针数组使用 还有记住脱衣服法则: a2 变成 *(a+2) a23变成 *(a+2)3再可以变成 *(*(a+2)+3)这个思想很重要!,数组的操作往往用循环结构.,数值数组 #define M 10 int aM; for(i=0;iM;i+),字符数组 #define M 10 char aM; for(i=0;ai!=0;i+),数值数组倒序 #define M 10 main() int i,j,aM; for(i=0;iM;i+) scanf(“%d”,ai); for(i=0,j=M;ij;i+,i-) 交换ai,aj,字符数组倒序 main() int i,j;char a50; gets(a); for(i=0,j=strlen(a);ij;i+,i-) 交换ai,aj,用函数实现倒序,数值数组 void inv(int x,int n); #define M 10 main() int i,j,aM; for(i=0;iM;i+) scanf(“%d”,ai); inv(a,M); for(i=0;iM;i+) printf(“%d”,ai); ,字符数组 void inv(char x) main() int i,j;char a50; gets(a); inv(a); puts(a); ,多一个参数,表示元素个数,可以整体输入,输出,必须单个输入,输出,数值数组 void inv(int x,int m) int i,j,k; j=m; for(i=0;ij;i+,i-) k=xi; xi=xj; xj=k; ,字符数组 void inv(int x ) int i,j,k; j=strlen(x); for(i=0;ij;i+,i-) k=xi; xi=xj; xj=k; ,顺序查找,下面程序在a数组中查找与x值相同的元素所在位置,数据从a1元素开始存放。 #include void main( ) int a11, i, x ; printf( “输入10个整数:”); for(i=1; i=10; i+) scanf( “%d “, ,费伯那契(Fibonacci)数列各项为1,1,2,3,5,8,13,21,.,求其前40项之和。,矩阵,基本知识:主对角线 i=j 副对角线 i+j=n-1 上三角形 i=j,编一个程序,求一个33矩阵对角线元素之和。 main( ) int i,j,s=0,a33; for ( i=0; i3; i+ ) for ( j=0; j3; j+ ) scanf(“%d“, ,主对角线 i=j 副对角线 i+j=2,累加(积),# define M 10 main() int i,aM,s=0; for (i=0;iM;i+) scanf(“%d”, ,# define M 10 main() int i,aM,s=1; for (i=0;iM;i+) scanf(“%d”, ,求最大(小)值,#define M 30 main() int i,k,k_i,aM; for(i=0;iM;i+) scanf(“%d”, ,最小值 if(kai),最大值,字符数组,char str50;int i; for (i=0;stri!=0,i+) 构造新的字符数组(删除,插入,复制,连接,倒序)。 1.用和不用字符串函数实现上述功能。 2.用指针实现。 3.必须注意最后一项一定是: stri =0;或 *p=0;,编一个程序,输入一个字符串,将组成字符串的所有非英文字母的字符删除后输出。例如:输入“abc123+xyz.5“,应输出“abcxyz“。 #include #include void main() char str256; int i,j,k=0,n; gets(str); n=strlen(str); for(i=0;i=a ,4个函数,编制程序,输出字符串的有效长度,并输出该字符串。 #include void main( ) int i=0,len; char str80 = “Happy”; for(i=0;stri!=0;i+) ; len=i; printf(“len=%dn”,len); for(i=0;stri!=0;i+) putchar(stri); ,将字符数组s2中的全部字符拷贝到字符数组s1中。 #include “stdio.h“ void main( ) char s120,s2 =“Good morning!“;int i=0; while(s1i+=s2i)!=0); printf(“%sn“,s1); ,将两个字符串连接起来。,#include void main( ) char a40, b40, c80; int i, j; printf( “分二行输入两个字符串: n”); gets(a); gets(b); for(i=0;ai!=0;i+) ci=ai; for(j=0;bj!=0;j+) ci+j=bj; cj=0; puts(c); ,实现两个字符串的比较,即自左至右逐个字符按ASCII码大小相比较 。 如果字符串1 = = 字符串2,结果为 0。 如果字符串1 字符串2,结果为一正整数。 如果字符串1 void main() char s180,s240; int i=0,j=0; printf(“nInput the first string:“); scanf(“%s“,s1); printf(“nInput the second string:“); scanf(“%s“,s2); for(i=0;s1i!= 0;i+) if(s1i!=s2i) break; printf(“%d”s1i-s2i);,双重循环,2个排序,二维字符数组,二维数组在内存中的排列顺序是“按行优先存放” 二维数组amn可以视为由n个一维数组am组成的。 二维字符数组中m由其中最长的字符串决定。,char stu56= “Tom“,“Anne“,“Mary“,“Peter“; 其中stu0= “Tom“ stu1=“Anne“,字符串函数,要用#include 字符串拷贝函数strcpy 字符串连接函数strcat 字符串比较函数strcmp 测字符串长度函数strlen 函数strlen的值为0之前的全部字符个数.它与数组长度不是一个概念.,char s6=H,o,w,0,o,k,strlen (s) =3,字符串函数的应用,字符串赋值 字符串比较,s1=s2,strcpy(s1,s2),s1=s2,strcmp(s1,s2)=0,s1s2,strcmp(s1,s2)0,s1s2,strcmp(s1,s2)0,一 函数定义的形式:,存储类型 数据类型 函数名(形式参数表) 变量数据定义语句序列; 可执行语句序列; ,int fun(int x,int y) int z; z=x+y; return z; ,函数体,四 函数,类型标识符 函数名(形参表) 语句 ,返回值类型,函数首部(函数头),函数体,可以为空,但花括号不能省略,没有分号,形参表可以为空,但括号不能省略,函数要先定义后使用(调用)。 【语法】函数定义的一般形式为:,【语义】定义一个函数,编译程序并不为函数定义分配存储空间,在函数调用时才分配存储空间,然后再运行这个函数。,函数定义,1. 有返回值函数 有返回值函数在函数执行结束后向调用者返回一个执行结果,称为函数的返回值。 【语法】有返回值return语句的一般形式如下: return (表达式) ; 括号可以省略 【语义】计算表达式的值,结束函数的执行并将表达式的值作为返回值返回给调用者。,函数定义,2. 无返回值函数 无返回值函数只完成某种特定的处理,函数执行后不向调用者返回函数值。函数首部必须将返回值的类型说明为空类型(void),函数体中的return语句只结束函数的执行。 【语法】无返回值return语句的一般形式如下: return ; 【语义】结束函数的执行。,函数调用,函数定义只是按照程序逻辑将相关语句组织在一起,要想执行这些语句,就需要执行函数,即函数调用。 【语法】函数调用的一般形式如下:,函数名(实参表);,与形参表相对应,实参可以是常量、变量,还可以是表达式,如果实参中存在变量,则在函数调用时,变量应该是“值有定义的”;,【语义】为函数分配存储空间,执行函数。,括号不能省略,函数的嵌套调用,函数可以嵌套调用,程序中的函数通过互相调用体现其逻辑关系。,但函数不能嵌套定义。,函数声明,【语义】对函数原型进行声明,说明函数的参数和返回值类型等情况。,C 语言规定:函数必须先定义后调用,因此,程序中要确保函数调用之前已经完成函数定义,否则编译器没有关于函数的任何信息,不能正确地完成翻译工作。 为了避免函数在定义前调用,在调用前声明这个函数的原型。,【语法】函数声明的一般形式如下:,1.基本知识: (1)调用格式:主调函数 函数名(实参表列) 被调函数 返回类型 函数名(形参说明 形参表列) (2)地址传递 主调函数 函数名(地址表列) 被调函数 返回类型 函数名(形参说明 地址表列) (3)一维数组 主调函数 函数名(a,n) 被调函数 返回类型 函数名(int *b,int n) 函数名(int b,int n) (4)二维数组 主调函数 函数名(a,3,4) 被调函数 返回类型 函数名(int *b,int m,int n),非void型 int fun(int x,int y); main() int a,b; scanf(“%d,%d”, ,void型 void fun(int x,int y); main() int a,b; scanf(“%d,%d”, ,填main(),char fun(int x,int y) int z; z=x+y; return z; ,main() ,int a,b; 函数实参,char c; 函数返回值,scanf(“%d,%d”, a,b); 实参赋值,c=fun(a,b); 调用函数,printf(“%c”, c); 输出结果,注意变量数据类型的对应 int %d long %ld float %f double %lf char %c或%s,递归调用的概念 在语言中,一个函数直接或间接地调用自身,便构成了函数的递归调用。 前者为直接递归调用,后者称间接递归调用。,计算n!的函数fac() long fac(int n) long p; if (n=0 |n=1) p=1; else p= n*fac(n-1); /*自己调自己*/ return p; void main() printf(“%ld”, fac(5); ,记住递归调用的框架,一定要注意参数之间的传递,实参和形参之间 传数值,和传地址的差别。 传数值的话,形参的变化不会改变实参的变化。 传地址的话,形参的变化就会有可能改变实参的变化。,数组名作函数实参,void fun(int a ,int n); main() int arr10,i; for(i=0;i10;i+) scanf(“%d”, ,变量的作用域,局部变量,局部变量是在函数内部、复合语句或语句块的内部定义的变量,其作用域仅限于函数、复合语句或语句块,离开作用域后再引用局部变量是非法的。 1. 函数级局部变量,局部变量,#include int Fun(int x) ; int main( ) int a = 10, b; b = Fun(a); printf(“%d“, x); /编译错误,变量x只能在函数Fun中引用 return 0; int Fun(int x) int y ; y = x * x + 2 * x + 1 ; printf(“%d“, a); /编译错误,变量a只能在函数main中引用 return y ; ,局部变量 a和b 的作用域,局部变量 x和y 的作用域,局部变量,同名变量,占用不同的内存单元, 属于不同的作用域,互不干扰,局部变量,局部变量,2. 复合语句级局部变量,在复合语句中定义的变量属于复合语句级局部变量,其作用域仅限于花括号括起的复合语句。,#include int main( ) int a = 5, b = 10 ; int temp ; temp = a ; a = b ; b = temp ; printf(“%d“, temp) ; /编译错误,对变量temp的访问超出其作用域 return 0 ; ,局部变量temp的作用域,全局变量,全局变量(也称全程变量)是定义在所有函数(包括main函数)之外的变量,其作用域从变量定义开始到程序结束。全局变量不属于哪一个函数,可以被作用域内的所有函数引用。,#include int Sum = 0 ; void Accumulate( ) ; int main( ) Accumulate( ) ; printf(“调用1次累加和:%dn“, Sum) ; /Sum的值为10 Accumulate( ) ; printf(“调用2次累加和:%dn“, Sum) ; /Sum的值为20 return 0 ; void Accumulate( ) for (int i = 1; i = 10; i+) Sum+ ; ,全局变量Sum 的作用域,变量的生存期,变量从生成到撤销(释放)的这段时间称为变量的生存期。,C程序在运行时将具有生存期的变量保存在数据区中,数据区一般分为静态存储区和动态存储区两种,全局变量和静态变量存储在静态存储区中,局部变量和自动变量存储在动态存储区中,如图所示。,动态存储区:局部变量、自动变量,所谓自动的含义是在生成变量时系统自动为变量分配内存空间,在撤销变量时系统自动收回变量占用的内存空间,因此,此类变量称为自动变量。局部变量都属于自动变量,静态变量(static),如果希望在函数调用结束后仍保留局部变量的值,即不释放该变量占用的存储单元,则必须将该变量定义为静态变量。 静态变量一经分配内存空间,在程序的运行过程中就始终占有该内存空间,但静态变量的作用域不变,因此,仍然只能在其作用域范围内引用。静态变量的初始化只在第一次调用函数时执行一次,以后执行函数时不再进行初始化操作。,自动变量(auto或省略),静态局部变量,可以保留上次运行的结果 函数f定义如下,执行语句“sum=f(5)+f(3);”后,sum的值应为 。 int f(int m) static int i=0; int s=0; for(; i=m; i+) s+=i; return s; A、21 B、16 C、15 D、8,静态局部变量,#include int Accumulate( ) ; main( ) int num; num = Accumulate( ) ; printf(“调用1次累加和:%dn“, num) ; /num的值为10 num = Accumulate( ) ; printf(“调用2次累加和:%dn“, num) ; /num的值为20 printf(“%d“, sum); /编译错误,对变量sum的引用超出其作用域 return 0 ; int Accumulate( ) static int sum = 0; /初始化操作只执行一次 for (int i = 1; i = 10; i+) sum+ ; return sum; ,静态变量sum的作用域,main( ) int i,a=2; for(i=1;i=5;i+) f( i ); printf( “%dn”,a); f( int j ) static int a=100; auto k=1; +k; printf( “%d+%d+%d=%dn”,a,k,j,a+k+j); a+=10; ,函数调用,函数定义,函数内定义,值不保留。,运行结果: 100+2+1=103 110+2+2=114 120+2+3=125 130+2+4=136 140+2+5=147 2,两个函数变量同名,互不影响。,静态变量,变量作用域,写出下列程序段的输出结果。 #include int x=1,y=5; /全局变量 void main() int x; /函数内局部变量 x=y+; printf(“%d,%dn”,x,y); if(x4) int x; /复合语句内局部变量 x=+y; printf(“%d,%dn”,x,y); x+=y-; printf(“%d,%dn”,x,y); ,五 指针 (1)指针: 某变量的地址值称为该变量的指针。 (2)指针变量: 指针变量是存放普通变量地址的变量。 指针变量指向这个普通变量。,11 12,a b,地址 1010 1012,指针变量 整型变量,指针变量的本质是用来放地址,而一般的变量是放数值的。 int *p 中 *p和p的差别: *p可以当做变量来用;*的作用是取后面地址p里面的数值 p是当作地址
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024新版《药品管理法》培训课件
- 心脏手术的抗凝治疗与并发症防控
- 治疗阿尔茨海默病药
- 脑震荡的中医护理方案
- 吉林省2024七年级数学上册第2章整式及其加减阶段综合训练范围2.1~2.3课件新版华东师大版
- 分销管理模式
- 脚病调理培训课件
- 化学反应方向说课稿
- 红黄蓝说课稿
- 好玩的洞洞说课稿
- 乱扔垃圾的课件
- 2024-2030年中国安全校车市场发展分析及市场趋势与投资方向研究报告
- 数字孪生水利项目建设可行性研究报告
- 北京市房山区2023-2024学年高二上学期期中地理试题 含解析
- 人教版六年级上册数学课本课后习题答案
- 期刊编辑的学术期刊版权教育与培训考核试卷
- SolidWorks-2020项目教程全套课件配套课件完整版电子教案
- 高等教育自学考试《13683管理学原理(中级)》考前模拟试卷一
- 2024政务服务综合窗口人员能力与服务规范考试试题
- 鼎和财险机器人产品质量责任保险条款
- 第4章 代数式 单元测试卷 2024-2025学年浙教版七年级数学上册
评论
0/150
提交评论