1、机电系统控制电路设计,张志安,南京理工大学,机电系统控制电路设计,2,2019/10/11,1 C语言基础 2 数据类型、运算符和表达式 3 程序控制语句 4 函数及其调用 5 编译预处理 6 数组及指针,AVR单片机C语言编程基础,机电系统控制电路设计,3,2019/10/11,1 C语言基础,例子 1,机电系统控制电路设计,4,2019/10/11,例子 2,1 C语言基础,机电系统控制电路设计,5,2019/10/11,1 C语言基础,例子 3,机电系统控制电路设计,6,2019/10/11,1 C语言基础,/*给定半径,求圆的面积*/ #define PI 3.14159 /*编译预处
2、理宏替换*/ #include /*编译预处理文件包含*/ #include /*编译预处理文件包含*/ main( ) /*主函数*/ float r,s; /*定义变量r、s类型为单精度实型*/r =1.0; /*变量r赋初值*/s=PI * pow(r,2); /*计算圆面积s*/printf (“半径R=%f 时,面积S=%f n“,r,s); /*输出结果*/ ,例 4 求圆面积程序 area.c,机电系统控制电路设计,7,2019/10/11,关于编译预处理(宏定义),1 C语言基础,#define PI 3.14159 -不带参数 #define S(a,b) a*b-带参数 #
3、define 宏定义命令PI 符号常量(宏名,最好用大写,以区别一般变量)3.14159 宏体(可以是一个表达式,如3+4) 作用:用简单符号代表宏体部份内容(编译时会先自动替换) 意义:直观/多次使用/便于修改 注意: #define 可出现在程序的任一位置(作用范围:由此行到程序末尾) 宏定义不是C语句,不必在行未加分号,否则会连分号一起置换。,机电系统控制电路设计,8,2019/10/11,1 C语言基础,#include stdio.h“头文件”(标准前导文件) C语言是一种“装配式”语言,许多常规的工作如输入、输出、数学函数等,往往事先由人做成各种“程序模块”(库函数),存放在各种所
4、谓“头文件”(.h)中。使用时只需进行以下处理#include “头文件名” 或 #include 在程序的执行部分调用该库函数:函数名(参数) 文件包含的作用,就是根据需要把相应的某个“头文件”的内容在编译时先整体嵌入所编的程序中。 用户也可以将自己设计的程序模块等做成“头文件”,供其他程序“包含”。,关于编译预处理(文件包含),机电系统控制电路设计,9,2019/10/11,1 C语言基础,标识符被#define 命令定义过 #ifdef 标识符程序段1 #else程序段2 #endif,关于编译预处理(条件编译),标识符未被#define 命令定义过 #ifndef 标识符程序段1 #e
5、lse程序段2 #endif,#if 表达式-表达式真执行程序段1,假执行程序段2程序段1 #else程序段2 #endif,机电系统控制电路设计,10,2019/10/11,1 C语言基础,关于主函数 main( ) ,C语言是一种函数式语言,它的一个函数实际上就是一个功能模块C程序的基本组成是函数。 一个C程序是由一个固定名称为main的主函数和若干个其他函数(可没有)组成。 一个C程序必须有一个、也只能有一个主函数。 主函数在程序中的位置可以任意,但程序执行时总是从主函数开始,在主函数内结束。 主函数可以调用其他各种函数(包括用户自己编写的),但其他函数不能调用主函数。,机电系统控制电路
6、设计,11,2019/10/11,主函数的一般形式:,main( ) 说明部分程序段(定义数据类型)执行部分程序段(给出操作指令),说明部分(简单程序可能没有此部分):float r,s; /*定义变量r、s类型为单精度实型*/int a,b; /*定义变量a、b类型为整型*/ 执行部份:输入、赋值、计算、控制、输出等:r=1.0; /*变量r赋初值*/s=PI*pow(r,2); /*计算圆面积s*/printf(“半径R=%f 时,面积S=%f n“,r,s); /*输出结果*/,1 C语言基础,机电系统控制电路设计,12,2019/10/11,其他函数,标准库函数只能调用 。使用方法:
7、先“包含”,即将该函数所在头文件包含在程序中。后调用。调用方式:函数名(参数),例: #include #include main( ) s=PI*pow(r,2); printf(“半径R=%f 时,面积S=%fn”,r,s); 说明:pow(x,y) 求xy (math.h中的标准数学函数) printf(); (stdio.h中的标准输出函数),1 C语言基础,机电系统控制电路设计,13,2019/10/11,其他函数,自编(定义)函数: 先定义(规定函数类型、函数名和函数功能) 后调用(使用所定义的函数实现其功能)定义函数: 函数类型 函数名(形式参数) (函数体)调用函数:函数名(参
8、数),求三个数的平均值 float average ( float x, float y, float z) /*定义函数average( )*/ float aver;aver=(x+y+z)/3;return(aver); main( ) /*主函数*/ float a,b,c,ave;a=3.5;b =4.6;c =7.9;ave=average(a,b,c); /*调用自定义函数average( )*/ printf(“average=%f “,ave); ,1 C语言基础,机电系统控制电路设计,14,2019/10/11,关于语句: 数据类型定义语句,语句形式 变量类型关键字 变量名
9、;float r,s; 定义r、s为单精度实型变量 int r,s; 定义r、s为整型变量 【注意】在C语言程序中,所有变量都要先定义后使用,否则就会出现编译错误提示,如:Error: Undefined symbol a in function mainLets try,变量类型关键字字符型(描述文字性的数据) char数值型: 整型(在机内是准确表示的) int实型(在机内一般是近似表示的)float (有效数字6位)double(有效数字16位),变量名 C语言标识符(变量名、符号常量名、函数名等)命名:组成:字母、数字、下划线开头:字母、下划线长度:32字符 【注意】大小写为不同字符(
10、变量名一般小写,符号常 量 名一般大写),还要注意不得与关键字同名。,1 C语言基础,机电系统控制电路设计,15,2019/10/11,关于语句: 赋值语句,作用:使变量获得具体的运算值。 语句形式变量名=表达式(常量、变量、函数、算式及其混合);r =1.0; /*变量r赋初值*/s=PI*pow(r,2); /*计算圆面积s*/ 变量赋初值亦可在数据类型定义时进行:float r =1.0, s;把变量声明语句与赋值结合在一起的语句,术语上称为 “初始化语句”。,1 C语言基础,机电系统控制电路设计,16,2019/10/11,关于语句: 输出语句,作用:将运算结果送到显示器屏幕显示出来
11、语句形式 printf ( ) ;printf (“半径R=%f 时,面积S=%fn“,r,s);printf (“Hello,everyone!”); 【注意】C语言本身没有输入、输出语句,其功能要借用有关函数来实现。%f 格式字符串n 控制字符(转义字符) n表示回车换行 引号中的其他部分照原样输出,1 C语言基础,机电系统控制电路设计,17,2019/10/11,关于格式字符串,表示该处将用printf语句引号外对应表达式的值替换后输出例:若 r =1,s=3.14printf (“半径R=%f 时,面积S=%fn”,r,s);输出结果:半径R=1 时,面积S=3.140000 常用格式
12、字符串:字符型:%c 单字符%s 字符串数值型:%d 整数(十进制)%f 实数(小数形式,默认为6位小数),例一int x = 5;f loat y =3;printf (“a=%d,b=%f,c=%s“,x,y, “abcdefg“);,输出结果:a=5,b=3.000000,c=abcdefg,例二int x = 5;f loat y =3;printf (“a=%d,b=%f,c=%s“,x+2,y*3, “123defg“);,输出结果:a=7,b=9.000000,c=123defg,1 C语言基础,机电系统控制电路设计,18,2019/10/11,C语言程序的基本结构,一个C程序是
13、由一个固定名称为main的主函数和若干个其他函数(可缺省)组成。其基本结构一般形式如右图所示。,1 C语言基础,返回,机电系统控制电路设计,19,2019/10/11,2 数据类型、运算符和表达式,机电系统控制电路设计,20,2019/10/11,2 数据类型、运算符和表达式,机电系统控制电路设计,21,2019/10/11,2 数据类型、运算符和表达式,可知对不同数据类型占用的存储空间:charshort=intlong =floatdouble,如求某一类型数据所占存储字节数,可用运算符:,sizeof(类型关键字),Example: main( ) printf(“char:%d字节n”
14、,sizeof(char);printf(“float:%d字节n”,sizeof(float); ,结果显示: char:1字节 float:4字节,机电系统控制电路设计,22,2019/10/11,2 数据类型、运算符和表达式,常量,整型常量 十进制数 12 -123八进制数 012 -012十六进制数 0x12 -0x12 实型常量 十进制形式 123.45 2.0 123. ( 必有小数点)指数形式 2.45e-4 1.13E3 (e或E前为数,后为整数)实型常量本身无单或双精度,其机内精度取决于赋给那类变量 字符常量/字符串常量,机电系统控制电路设计,23,2019/10/11,2
15、数据类型、运算符和表达式,变量,注意: 变量必须先定义后使用 变量名必须符合标识符命名规则,例: b=(a=3+5) a=b=c=d=3+5 (结果均为8)例:int a=b=c=d=3+5 (语法错误,除非b,c,d定义过)正确:int a, b=a=3+5;例: c=3+(a=5)*6 结果:c=33,a=5(一个语句可以有几个赋值运算),机电系统控制电路设计,24,2019/10/11,2 数据类型、运算符和表达式,运算符,算术运算符 + * / %(取余数模) + + ,+(自加运算符)-(自减运算符) 用法: +1 -1 运算 a、前缀形式int i=5; x = + i ; y=
16、i ; (x=6, i =6, y=6)int i =5; + i ; y= i ; ( i =6, y=6) b、后缀形式int i =5; x = i +; y= i ; (x=5, i =6, y=6)int i =5; i +; y= i ; ( i =6, y=6),机电系统控制电路设计,25,2019/10/11,2 数据类型、运算符和表达式,运算符,自反算术赋值运算符(复合的赋值运算符) += -= *= /=,解法: 将b*=看作b=b*(),其余类推例: c=b*=a+3 相当于(1)a+3 (2)b=b*(a+3) (3)c=b 例:若 i 、j 的初值分别为3和4,则执行
17、 j+=i- =1 后i 、j 的值为多少?,解题步骤:i=i-1=3-1=2j=j+i=4+2=6 结果:i=2, j=6,机电系统控制电路设计,26,2019/10/11,2 数据类型、运算符和表达式,运算符,关系运算(比较运算) = = = !=关系表达式: 含有关系运算符的表达式特别注意 aXb 之类算式的正确写法 :a=x & x=b(错误写法:a=X=b),【例一】 main( ) int m=5;if (m+5)printf(“m5”);else printf(“m=%d”,m-);printf(“m=%d”,m-); ,运算结果: m=6,m=5,【例二】 main( ) in
18、t m=5;if (+m5)printf(“m5”);else printf(“m=%d”,m-);printf(“m=%d”,m-); ,运算结果: m5,机电系统控制电路设计,27,2019/10/11,2 数据类型、运算符和表达式,运算符,逻辑运算 &(与运算符) 运算符两边均为真时,结果为真 | (或运算符) 运算符两边均为假时,结果为假!(非运算符) 将运算符右边真假倒置逻辑运算符的任一端如果为非0数,则视为“真”,为0则视为假。【例】 printf(“%d”, !3+5) 结果为5printf(“%d”, !0+5) 结果为6 注意:! 优先于关系运算符,与+、-同级。,【例一】m
19、ain( ) int a=1,b=2,m=2,n=2; (m=ab),运行结果:n=2,【例二】main( ) int a=1,b=2,m=2,n=2; (m=ba),运行结果:n=3,原因:在&和|的左边如果能判断出结果,则右边不再作运算。 结论:在逻辑表达式的求解中,并不是所有的逻辑运算符都会被执行。只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。,机电系统控制电路设计,28,2019/10/11,2 数据类型、运算符和表达式,运算符,条件运算 ? : (三元运算符,即需连接三个运算量) 一般形式: e1?e2:e3 (e1为条件表达式,e2,e3为任意类型表达式) 功
20、能:如果e10(为真),运算结果为e2的值。如果e1=0(为假),则取e3的值。,【例】分别令x=3,x=0,x= -5,求运行结果。 main( ) int x,y;printf(“Input x=”);scanf(“%d”, ,结果: x=3,y=1 x=0,y=0 x=-5,y=-1,机电系统控制电路设计,29,2019/10/11,2 数据类型、运算符和表达式,运算符,位操作运算符 &(与AND) |(或OR) (异或XOR) (非NOT)(右移),机电系统控制电路设计,30,2019/10/11,2 数据类型、运算符和表达式,运算符的优先级,返回,机电系统控制电路设计,31,2019
21、/10/11,3 程序控制语句,条件控制语句,if语句,1、简单if语句 if(表达式) 程序段 下面程序的功能是: 如果输入的数据大于等于60,则输出 You are passed!: scanf(“%d”, ,机电系统控制电路设计,32,2019/10/11,3 程序控制语句,条件控制语句,2、if-else语句 if(表达式) 程序段 else 程序段 ,如果输入的数据大于等于60,则输出You are passed! 否则输出You failed! scanf(“%d”,if语句,机电系统控制电路设计,33,2019/10/11,3 程序控制语句,条件控制语句,#include mai
22、n() int x,y=100,z=0;x=180;if(xy) /交换x和yz=x;x=y;y=z;rintf(“x=%d,y=%dn“,x,y); ,#include main() int x,y=100,z=0;x=180;if(xy)z=x;x=y;y=z;rintf(“x=%d,y=%dn“,x,y);,运行结果:x=180,y=100,运行结果:x=100,y=0,if语句,机电系统控制电路设计,34,2019/10/11,3 程序控制语句,条件控制语句,第3种if语句 if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式n) 语句n; else
23、 语句n+1; ,if(x0,if语句,机电系统控制电路设计,35,2019/10/11,3 程序控制语句,条件控制语句,switch语句,switch(变量或表达式P) case 常量表达式C1:程序段S1break;case 常量表达式C2:程序段S2break;.case 常量表达式Cn:程序段Snbreak;default: 程序段Sn+1break;,机电系统控制电路设计,36,2019/10/11,#include main() char ch; printf(“input the mark(A,B,C,D,E or F)“);scanf(“%c“, ,3 程序控制语句,条件控制语
24、句,switch语句,运行结果: input the mark(A,B,C,D,E or F)D70,机电系统控制电路设计,37,2019/10/11,break子句可以省略,但是否省略break子句,要根据算法的逻辑而定。因为没有了break语句,switch语句会被执行到语句结束。,3 程序控制语句,条件控制语句,switch语句,char ch=N; switch(ch)case Y:printf(“Yesn“);break;case N:printf(“Non“);break;case A:printf(“Alln“);break; ,char ch=N; switch(ch)case
25、 Y:printf(“Yesn“);break;case N:printf(“Non“);case A:printf(“Alln“);break; ,输出:No,输出:NoAll,机电系统控制电路设计,38,2019/10/11,3 程序控制语句,循环控制语句,while语句,while语句的形式: while(表达式P) 程序段S,int a; long sum;/sum should be long type sum=0; a=1; while(a=100) sum+=a; a+; printf(“1+2+.+%d=%ldn“,100,sum);,while语句的例子:计算1+2+3+10
26、0的值,通常情况下,程序中会利用 一个变量来控制while语句的表 达式P的值,这个变量被称为循 环控制变量。在执行while语句 之前,循环控制变量必须初始化,否则执行的结果将是不可预知的。 上面的程序重新编写,其运行结果将是不可预知的,因为a未初始化:,int a; long sum;/sum should be long type sum=0; /a should be initialized here while(a=100) sum+=a; a+; printf(“1+2+.+%d=%ldn“,100,sum);,机电系统控制电路设计,39,2019/10/11,3 程序控制语句,循
27、环控制语句,while语句,有关while语句的几点说明,1、要在while语句的某处(表达式P或循环体内)改变循环控制变量的值,否则极易构成死循环。下面的while语句便是死循环:,x=2; while(x10) / 死循环,因为x的值没有变化,永远小于10sum+=x; printf(“%ld”,sum);,机电系统控制电路设计,40,2019/10/11,3 程序控制语句,循环控制语句,while语句,有关while语句的几点说明,2、如果在执行循环体过程中,遇到了break子句,则跳出while循环。比如,上面求1+2+100的程序可以这样设计:,a=1; sum=0; while(1
28、) if(a100)break;sum+=a;a+;,机电系统控制电路设计,41,2019/10/11,3 程序控制语句,循环控制语句,while语句,有关while语句的几点说明,3、如果在执行循环体过程中,遇到了continue语句,则循环体中continue语句后面的其他语句将被跳过,而直接进入下一轮循环。,a=1; while(a=10) printf(“%d“,a);a+;if(a%5=1)continue;printf(“*“);,运行结果: 12*3*4*5*67*8*9*10,机电系统控制电路设计,42,2019/10/11,3 程序控制语句,循环控制语句,do-while语句
29、,do-while语句的形式: do 程序段S while(表达式P);,do-while语句的例子:计算1+2+3+100的值,int a; long sum; sum=0; a=1; do sum+=a; a+; while(a=100); printf(“1+2+.+%d=%ldn“,100,sum);,do-while语句与while语句大体相同,但要特别注意,while( )后面的分号不要漏掉。此外,while语句的循环体可能永远不被执行,但do-while语句的循环体至少被执行一次。,机电系统控制电路设计,43,2019/10/11,3 程序控制语句,循环控制语句,for语句,fo
30、r语句的形式: 必须是分号 必须是分号 for(表达式1 ; 表达式2 ; 表达式3) 程序段S,机电系统控制电路设计,44,2019/10/11,3 程序控制语句,循环控制语句,for语句,int a; long sum; sum=0; for(a=1;a=100;a+) sum+=a; printf(“1+2+.+%d=%ldn“,100,sum);,for语句的例子:用for语句实现1+2+100求和,机电系统控制电路设计,45,2019/10/11,3 程序控制语句,三种循环控制语句的比较,在使用while和do-while语句时,循环控制变量的变化必须放在循环体内。而for语句却可以
31、利用表达式3来改变循环控制变量的值。 在使用while和do-while语句时,必须在while或do-while语句前初始化循环控制变量。但for语句却可以利用表达式1来初始化循环控制变量。 do-while语句的循环体至少被执行一次,但while语句和for语句的循环体可能一次也执行不到。 while语句和do-while语句中不能省略循环条件(即表达式P),但for语句却可以省略循环条件(即表达式2)。 break语句和continue语句在这3种循环语句中的作用是相同的。 凡是用while语句能实现的循环,必然能用for语句实现,反过来也一样。,机电系统控制电路设计,46,2019/1
32、0/11,3 程序控制语句,三种循环控制语句的选用及循环嵌套,返回,机电系统控制电路设计,47,2019/10/11,4 函数及其调用,C语言的函数是子程序的总称,包括函数和过程。(有返回值、无返回值,有参函数,无参函数)。 C语言函数可以分为库函数、用户自定义函数。库函数由系统提供,程序员只需要使用(调用),用户自定义函数需要程序员自己编制。 C语言的程序由函数组成,函数是C语言程序的基本单位。,机电系统控制电路设计,48,2019/10/11,4 函数及其调用,C语言程序的结构如图所示。在每个程序中,主函数main是必须的,它是所有程序的执行起点,main函数只调用其它函数,不能为其它函数
33、调用。其它函数没有主从关系,可以相互调用。所有函数都可以调用库函数。程序的总体功能通过函数的调用来实现。,机电系统控制电路设计,49,2019/10/11,4 函数及其调用,函数应当先定义,后调用 函数定义的一般形式 函数返回值的数据类型 函数名(类型名 变量名1,类型名 变量名2,) 声明部分/定义本函数所使用的变量和进行有关声明(如函数声明) 处理语句 /程序段,由若干条语句组成(可以在其中调用其它函数) 【注意】无形参表的即无参函数。无函数体的为“空函数”。如果函数返回值的数据类型为int,可以省略之。如果不返回值,定义为void类型。,机电系统控制电路设计,50,2019/10/11,
34、4 函数及其调用,函数定义举例: main() int n1,n2,n3,nmax;scanf(“%d%d%d”, ,输入三个整数,求三个整数中的最大值 不使用函数(除main外),int max(int,int,int); main() int n1,n2,n3,nmax;scanf(“%d%d%d”, ,输入三个整数,求三个整数中的最大值 使用函数,子函数定义,机电系统控制电路设计,51,2019/10/11,形式参数与实际参数 1、形式参数(形参):函数定义时设定的参数。前例中,函数头int max(int x,int y,int z)中x,y,z就是形参它们的类型都是整型。 2、实际参
35、数(实参):调用函数时所使用的实际的参数。前例中,主函数中调用max函数的语句是:nmax=max(n1,n2,n3); 其中n1,n2,n3就是实参,它们的类型都是整型。 关于形参和实参的说明: a、形参只有当调用时才临时分配存储单元。 b、实参一定要有确定的值,可以是表达式。 c、实参和形参的类型应相同或赋值相容。,4 函数及其调用,机电系统控制电路设计,52,2019/10/11,4 函数及其调用,形式参数与实际参数,机电系统控制电路设计,53,2019/10/11,4 函数及其调用,函数的返回值,C语言可以从函数(被调用函数)返回值给调用函数(这与数学函数相当类似)。在函数内是通过re
36、turn语句返回值的。函数可以使用一个或者多个return语句返回值也可以不返回值(此时函数类型是void)。 return语句的格式:return 表达式;或 return (表达式); 说明:函数的类型就是返回值的类型,return语句中表达式的类型应该与函数类型一致。如果不一致,以函数类型为准(赋值转化)。,机电系统控制电路设计,54,2019/10/11,4 函数及其调用,局部变量概念:是指在一定范围内有效的变量。C语言中,在以下各位置定义的变量均属于局部变量。在函数体内定义的变量:在本函数范围内有效,作用域局限于函数体内。在复合语句内定义的变量:在本复合语句范围内有效,作用域局限于复
37、合语句内。有参函数的形式参数也是局部变量:只在其所在的函数范围内有效。,机电系统控制电路设计,55,2019/10/11,4 函数及其调用,全局变量全局变量:在函数之外定义的变量。(所有函数前,各个函数之间,所有函数后)全局变量作用域:从定义全局变量的位置起到本源程序结束为止。在引用全局变量时如果使用“extern”声明全局变量,可以扩大全局变量的作用域。例如,扩大到整个源文件(模块),对于多源文件(模块)可以扩大到其它源文件(模块)。全局变量和局部变量同名的“屏蔽”。,机电系统控制电路设计,56,2019/10/11,4 函数及其调用,全局变量和局部变量的应用,局部变量,输出结果 。 cou
38、nt is 100,机电系统控制电路设计,57,2019/10/11,4 函数及其调用,变量(局部/全局)两大属性: 数据类型 存储类别,1、数据类型(复习)通过变量说明(定义)来规定其数据类型:格式 数据类型关键字 变量名如 char a;int b,c ;float x,y;为什么使用变量前要先对其数据类型进行“说明”好比看电影前先买票订座预留存储空间(如char型为1个字节,int型为2个字节)确定存储方式(如char型存放ASCII值,int型存放补码值),机电系统控制电路设计,58,2019/10/11,变量(局部/全局)两大属性: 数据类型 存储类别,4 函数及其调用,2、存储类别
39、 规定了变量在计算机内部的存放位置决定变量的“寿命”(何时“生”,何时“灭”)一个完整的变量说明格式如下:存储类别 数据类型 变量名如 static int x , y ; C程序的存储类别有: register型(寄存器型) auto型(自动变量型) static型(静态变量型) extern型(外部变量型),机电系统控制电路设计,59,2019/10/11,C程序的变量存储位置,4 函数及其调用,变量的生存期静态存储区中的变量:与程序“共存亡”动态存储区中的变量:与函数“共存亡”寄存器中的变量:同静态存储区,机电系统控制电路设计,60,2019/10/11,4 函数及其调用,C程序的变量存
40、储类别, register型(寄存器型)变量值存放在运算器的寄存器中存取速度快,一般只允许存23个变量,且限于char型和int型,通常用于循环变量。 auto型(自动变量型)变量值存放在主存储器的动态存储区(堆栈方式); 优点同一内存区可被不同变量反复使用。以上两种变量均属于“动态存储型”,即调用函数时才为这些变量分配单元,函数调用结束其值自动消失。,机电系统控制电路设计,61,2019/10/11,4 函数及其调用,C程序的变量存储类别, static型(静态变量型) 变量值存放在主存储器的静态存储区 程序执行开始至结束,始终占用该存储空间 extern型(外部变量型) 同上,其值可供其他
41、源文件使用 以上两种均属于“静态存储”性质,即从变量定义处开始,在整个程序执行期间其值都存在(都可用!),机电系统控制电路设计,62,2019/10/11,4 函数及其调用,auto(默认) 所在函数调用结束时,其值自动消失 局部变量 register 如不赋初值,取不确定值为初值static 所有函数调用结束,其值仍保留如不赋初值,取初值为0(数值型)或空字符0(字符型),extern(默认)允许本源文件中其他函数及其他 全局变量 源文件使用 static 只限本源文件中使用,机电系统控制电路设计,63,2019/10/11,4 函数及其调用,求程序运行结果,main() int a=2,i
42、;clrscr( );/清楚屏幕,内部函数for (i=0;i3;i+)printf(“%4d“,f(a); f(int a) int b=0;static int c=3;b+;c+;return a+b+c; ,变量跟踪main( ) f函数a i b c f(a)2 0 01 4 71 01 5 82 01 6 9【结果】 7 8 9,如果去掉static呢?,【结果】 7 7 7,机电系统控制电路设计,64,2019/10/11,4 函数及其调用,求程序运行结果,main() int k=4,m=1,p;clrscr();p=func(k,m); printf(“%d,“,p);p=f
43、unc(k,m); printf(“%d“,p); func(int a,int b) static int m=0,i=2;i+=m+1;m=i+a+b;return m; ,变量跟踪main( ) func函数k m a b m i4 1 4 1 08 234 1 4 1 817 312【结果】 8, 17,如果去掉static呢?,【结果】 8, 8,机电系统控制电路设计,65,2019/10/11,4 函数及其调用,求程序运行结果,#include main() int a=3, b=2, c=1; /注意应用范围int b=5, c=12;/注意应用范围c-=b*2;printf(“
44、a=%d,b=%d,c=%dn“, a, b, c);a+=c;printf(“a=%d,b=%d,c=%dn“, a, b, c); ,【结果】 a=3,b=5,c=2 a=5,b=2,c=1,机电系统控制电路设计,66,2019/10/11,4 函数及其调用,int a=3,b=5; max(int a,int b) int c;c=ab?a:b;return c;main() int a=8;printf(“%dn“,max(a,b);,求程序运行结果,【结果】 8,如果主函数中没有int a=8, 结果?,【结果】 5,如果让主函数中int a=4 或a=-1,结果?,【结果】 均为
45、5,机电系统控制电路设计,67,2019/10/11,4 函数及其调用,求程序运行结果,void num() extern int x,y;int a=15,b=10;x=a-b;y=a+b; int x,y; main() int a=7,b=5;x=a+b;y=a-b;num();printf(“%d,%dn“,x,y); ,【结果】 5,25,如果第二行不加上extern呢?,【结果】 12,2,机电系统控制电路设计,68,2019/10/11,4 函数及其调用,求程序运行结果,int a=0;fun(int i) a+=2*i;return a; main() int a=10;clr
46、scr( );printf(“%d,%dn“,fun(a),a); ,【结果】 20,10,返回,机电系统控制电路设计,69,2019/10/11,5 编译预处理,预处理 在编译之前对源程序进行“预处理” 预处理命令不是C语句,末尾没有分号 预处理命令不在可执行文件中执行 预处理命令都以#开始 包括宏定义、文件包含、条件编译等 举例 #define MAX 1000 #include ,机电系统控制电路设计,70,2019/10/11,宏(Macro)定义,5 编译预处理,无参数的宏定义带参数的宏定义,机电系统控制电路设计,71,2019/10/11,5 编译预处理,无参数的宏定义,一般形式
47、#define 标识符 字符串 说明 把源程序中相应标识符予以替换 仅是简单的字符串替换,没有任何语法正确性检查 有效范围从定义处开始,到文件结束,或者由#undef命令终止作用域 行末没有分号,如有分号将会被一起替换,#define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define begin #define end #define forever for(;) int main() begin /* */printf(“L=%f“, L); #undef PI /* 取消对PI的宏定义 */forever; /* for(;); 无限循环 */ end /* */,