《C程序设计课件第4节》由会员分享,可在线阅读,更多相关《C程序设计课件第4节(54页珍藏版)》请在金锄头文库上搜索。
1、C C程序程序设计课件第件第4 4节带子程序的带子程序的C程序程序n n编程计算编程计算编程计算编程计算 其中其中其中其中void main() float y,f,p0,p2,p5,x; printf ( please input x: ); scanf(%f,&x); f=(x+x)+(x*0.3)/(7*(x*0.3); p0=(f+x/2)/(2*x); f=(x+(x+2)+(x+2)*0.3)/(7*(x+2)*0.3); p2=(f+(x+2)/2)/(2*x); f=(x+(x+5)+(x+5)*0.3)/(7*(x+5)*0.3); p5=(f+(x+5)/2)/(2*x);
2、 y=(p0*p0+5*x)/(p5-sqrt(x)*p2; printf (y(x)=%8.4fn,y);float x,y ;float x,y ; /* 3 */ /* 3 */float f(float v,float w )float f(float v,float w ) /* 4 */ /* 4 */return (w+v)/(7*v);return (w+v)/(7*v); /* 5 */ /* 5 */ /* 6 */ /* 6 */float p(float u)float p(float u) /* 7 */ /* 7 */return ( f(u*0.3,x+u)+(u
3、/2)/(2*x) );return ( f(u*0.3,x+u)+(u/2)/(2*x) ); /* 8 */ /* 8 */ /* 9 */ /* 9 */void main()void main() /* 10 */ /* 10 */printf (please input x: );printf (please input x: ); /* 11 */ /* 11 */scanf(%f,&x);scanf(%f,&x); /* 12 */ /* 12 */y=(p(x)*p(x)+(5*x)/(p(x+5)-sqrt(x)*p(x+2); /* 13 */y=(p(x)*p(x)+(5
4、*x)/(p(x+5)-sqrt(x)*p(x+2); /* 13 */ printf (y(x)=%8.4fn,y) printf (y(x)=%8.4fn,y) /* 14 */ /* 14 */ P(x)称为函数调用函数定义说明符,小括号()为形式参数表内为函数p的函数体,具体规定p的操作和计算Return:表达式的值作为函数值返回定义函数f执行顺序:1112 13 (分别以x,x+5,x+2为实参调用函数p )14定义函数pn n程序执行的主要步骤程序执行的主要步骤从键盘读入从键盘读入从键盘读入从键盘读入x x的值的值的值的值printf (please input x: );prin
5、tf (please input x: ); scanf(%f,&x);scanf(%f,&x);依次计算以依次计算以依次计算以依次计算以x, x+5, x+2x, x+5, x+2作为实参的函数作为实参的函数作为实参的函数作为实参的函数p p的值的值的值的值y=(p(x)*p(x)+(5*x)/(p(x+5)-sqrt(x)*p(x+2)y=(p(x)*p(x)+(5*x)/(p(x+5)-sqrt(x)*p(x+2)输入出函数输入出函数输入出函数输入出函数y y的值的值的值的值printf (y(x)=%8.4fn,y)printf (y(x)=%8.4fn,y)n n计算计算计算计算p(
6、x+5)p(x+5)过程过程过程过程 计算计算计算计算 x+5 x+5 得得得得 6.0 6.0 ; 将将将将 6.0 6.0 送入送入送入送入 p p 的形参的形参的形参的形参 u u 中,这时中,这时中,这时中,这时 u u 的值为的值为的值为的值为 6.0 6.0 ; 进入函数进入函数进入函数进入函数p p ,执行,执行,执行,执行 p p 的操作部分的操作部分的操作部分的操作部分( (第第第第8 8行行行行), ),即返回语句即返回语句即返回语句即返回语句“return “return . ;”. ;”,先计算返回语句中表达式的值,先计算返回语句中表达式的值,先计算返回语句中表达式的值
7、,先计算返回语句中表达式的值。 以以以以 u*0.3 u*0.3 和和和和 u+x u+x 为实参调用函数为实参调用函数为实参调用函数为实参调用函数 f f 顺序计算顺序计算顺序计算顺序计算 u*0.3 u*0.3 、u+x u+x 得得得得1.8 1.8 、7.0 7.0 ; 将将将将1.81.8、7.07.0顺序送入顺序送入顺序送入顺序送入 f f 的形参的形参的形参的形参v v、ww中,中,中,中,v=1.8v=1.8、w=7.0w=7.0; 进入函数进入函数进入函数进入函数 f f 执行执行执行执行 f f 的操作部分的操作部分的操作部分的操作部分( (第第第第5 5行行行行) ),执
8、行返回语句,执行返回语句,执行返回语句,执行返回语句 计算出表达式的值为计算出表达式的值为计算出表达式的值为计算出表达式的值为 0.698413 0.698413 带着函数值带着函数值带着函数值带着函数值 0.698413 0.698413 返回调用处,返回调用处,返回调用处,返回调用处,p p 中的返回语句内中的返回语句内中的返回语句内中的返回语句内( (第第第第8 8行行行行) ) 计算出返回语句中表达式的值为计算出返回语句中表达式的值为计算出返回语句中表达式的值为计算出返回语句中表达式的值为 1.84921 1.84921 即即即即 p p的值。的值。的值。的值。 带着函数值带着函数值带
9、着函数值带着函数值1.84921 1.84921 返回调用处:主程序第返回调用处:主程序第返回调用处:主程序第返回调用处:主程序第1313行的表达式语行的表达式语行的表达式语行的表达式语句内。句内。句内。句内。主程序主程序调用函数调用函数返回返回结束结束函数函数n n使用子程序技术分离了使用子程序技术分离了“做什么做什么”与与“怎么做怎么做” 程序逻辑结构清晰,易写,易读,易懂。程序逻辑结构清晰,易写,易读,易懂。程序逻辑结构清晰,易写,易读,易懂。程序逻辑结构清晰,易写,易读,易懂。程序的设计,调试,维护变得容易。程序的设计,调试,维护变得容易。程序的设计,调试,维护变得容易。程序的设计,调
10、试,维护变得容易。函数函数n n数学中函数数学中函数 n n函数概念的组成函数概念的组成函数定义函数定义函数定义函数定义函数调用函数调用函数调用函数调用n n使用函数注意事项使用函数注意事项先定义该函数(标准库函数除外)先定义该函数(标准库函数除外)先定义该函数(标准库函数除外)先定义该函数(标准库函数除外)类似于数学中的函数定义。类似于数学中的函数定义。类似于数学中的函数定义。类似于数学中的函数定义。再在表达式中调用该函数再在表达式中调用该函数再在表达式中调用该函数再在表达式中调用该函数数学中计算某函数的一个特定值。数学中计算某函数的一个特定值。数学中计算某函数的一个特定值。数学中计算某函数
11、的一个特定值。函数调用函数调用(function-designator)n n调用过程调用过程形参实参结合形参实参结合形参实参结合形参实参结合进入函数执行复合语句进入函数执行复合语句进入函数执行复合语句进入函数执行复合语句n n一般形式一般形式 F (e, e, , e)F (e, e, , e) F ( )F ( )n n例子例子 p (x+5) p (x+5) f (u*0.3,x+u)f (u*0.3,x+u)函数定义函数定义(function-declaration)n n除标准库函数外除标准库函数外除标准库函数外除标准库函数外, , 程序中使用函数必须程序中使用函数必须程序中使用函数
12、必须程序中使用函数必须先定义先定义先定义先定义,然后,然后,然后,然后再用再用再用再用“ “函数调用函数调用函数调用函数调用” ”调用它。调用它。调用它。调用它。n n标准函数是系统已经定义好的函数,不必定义即可直标准函数是系统已经定义好的函数,不必定义即可直标准函数是系统已经定义好的函数,不必定义即可直标准函数是系统已经定义好的函数,不必定义即可直接调用。接调用。接调用。接调用。n n在程序在程序在程序在程序example401Aexample401A中:中:中:中: float f(float v,float w ) float f(float v,float w ) /* 4 */ /*
13、 4 */ return (w+v)/(7*v); return (w+v)/(7*v); /* 5 */ /* 5 */ /* 6 */ /* 6 */ float p(float u) float p(float u) /* 7 */ /* 7 */ return ( f(u*0.3,x+u)+(u/2)/(2*x) ); return ( f(u*0.3,x+u)+(u/2)/(2*x) ); /* 8 */ /* 8 */ /* 9 */ /* 9 */n n由上述语法可知,一个函数定义的形式是由上述语法可知,一个函数定义的形式是由上述语法可知,一个函数定义的形式是由上述语法可知,一个
14、函数定义的形式是: : 类型说明符类型说明符类型说明符类型说明符 标识符标识符标识符标识符 ( ( ( ( 参数列表参数列表参数列表参数列表 ) ) ) ) 复合语句复合语句复合语句复合语句float f (float u) float f (float u) return (f(u*0.3,x+u)+(u/2)/(2*x);return (f(u*0.3,x+u)+(u/2)/(2*x); 函数类函数类型型函数名字函数名字形参列表形参列表复合语句复合语句函数体函数体函数定义说明符函数定义说明符n n 函数定义说明符函数定义说明符函数定义说明符函数定义说明符 上述形式的第一行称上述形式的第一行
15、称上述形式的第一行称上述形式的第一行称“ “函数定义说明符函数定义说明符函数定义说明符函数定义说明符” ”,形式如下,形式如下,形式如下,形式如下 TT F ( TT F ( 参数列表参数列表参数列表参数列表) )具体指明以下点:具体指明以下点:具体指明以下点:具体指明以下点:l函数的结果类型函数的结果类型函数的结果类型函数的结果类型 由由由由“ “类型说明符类型说明符类型说明符类型说明符” ”( TT )( TT )标明;标明;标明;标明;l函数的名字函数的名字函数的名字函数的名字 由类型说明符后的由类型说明符后的由类型说明符后的由类型说明符后的“ “标识符标识符标识符标识符” ” ( F
16、)( F )标明;标明;标明;标明;l函数的形式参数个数和每个形式参数的特性函数的形式参数个数和每个形式参数的特性函数的形式参数个数和每个形式参数的特性函数的形式参数个数和每个形式参数的特性 由由由由“ “参数列表参数列表参数列表参数列表” ”标明。标明。标明。标明。n n函数类型(返回值的类型)函数类型(返回值的类型)不能是数组或函数不能是数组或函数没有返回值的函数类型是没有返回值的函数类型是voidn n函数返回函数返回返回方式:返回方式:return ;return 表达式;表达式;函数运行到复合语句末尾(最后那个闭花函数运行到复合语句末尾(最后那个闭花括号括号“”)后。)后。int f
17、 (int x)return x*x;int y=9;void f (int x)if (x=y) if (x=y) return x; return x; else else return y; return y; n n无返回类型的函数无返回类型的函数无返回类型的函数无返回类型的函数 void void g( int w) g( int w) if (w=1) if (w=1) return; return; else else x=3; x=3; n n有返回类型函数的函数值有返回类型函数的函数值使用使用使用使用 return e; return e; 向调用函数的主程序传递函数值向调用
18、函数的主程序传递函数值向调用函数的主程序传递函数值向调用函数的主程序传递函数值return e ; return e ; 的执行过程是:的执行过程是:的执行过程是:的执行过程是:计算表达式计算表达式计算表达式计算表达式e e的值的值的值的值把表达式值按赋值转换规则,转换成函数的结把表达式值按赋值转换规则,转换成函数的结把表达式值按赋值转换规则,转换成函数的结把表达式值按赋值转换规则,转换成函数的结果类型;果类型;果类型;果类型;返回语句中表达式的类型与函数的结果类型必返回语句中表达式的类型与函数的结果类型必返回语句中表达式的类型与函数的结果类型必返回语句中表达式的类型与函数的结果类型必须赋值兼
19、容。须赋值兼容。须赋值兼容。须赋值兼容。用类型转换后的值作为函数值,并带着它返回用类型转换后的值作为函数值,并带着它返回用类型转换后的值作为函数值,并带着它返回用类型转换后的值作为函数值,并带着它返回到调用该函数处到调用该函数处到调用该函数处到调用该函数处n n无返回类型函数的函数值无返回类型函数的函数值void void g( int w) g( int w) if (w=1) if (w=1) return; return; else else x=3; x=3; n n在函数调用处,所调函数无值可以带回。在函数调用处,所调函数无值可以带回。对于对于对于对于无类型无类型无类型无类型函数,在
20、函数调用处不需要函数值,函数,在函数调用处不需要函数值,函数,在函数调用处不需要函数值,函数,在函数调用处不需要函数值,这种返回是正常的;这种返回是正常的;这种返回是正常的;这种返回是正常的;对于对于对于对于有类型有类型有类型有类型函数,在函数调用处极可能需要函数函数,在函数调用处极可能需要函数函数,在函数调用处极可能需要函数函数,在函数调用处极可能需要函数值参加下一步运算,这将值参加下一步运算,这将值参加下一步运算,这将值参加下一步运算,这将带来不可预料的结果带来不可预料的结果带来不可预料的结果带来不可预料的结果n n函数原型函数原型为什么使用函数原型为什么使用函数原型任何标识符都必须声明,
21、而且必须先声明任何标识符都必须声明,而且必须先声明后使用后使用在声明定义函数时必须保证函数声明位置在声明定义函数时必须保证函数声明位置在使用前出现在使用前出现从程序行文顺序上控制从程序行文顺序上控制从程序行文顺序上控制从程序行文顺序上控制 一般比较难实现一般比较难实现一般比较难实现一般比较难实现函数原型函数原型函数原型函数原型 方便灵活方便灵活方便灵活方便灵活n n一般形式一般形式TT F ( T TT F ( T ,T T ,. . ,T );T );TT F ( T id TT F ( T id ,T id T id ,. . ,T id );T id );n n例子例子 float f
22、( int, float, int, char ) ; float f ( int, float, int, char ) ; float f ( int z, float u, int v, char w ) ; float f ( int z, float u, int v, char w ) ; 一一对应一一对应一一对应一一对应n n函数原型的功能函数原型的功能满足了满足了C标识符先定义后使用的要求标识符先定义后使用的要求并向编译系统提供所调用函数的信息并向编译系统提供所调用函数的信息函数返回类型函数返回类型函数的参数个数函数的参数个数函数参数特性等信息函数参数特性等信息程序设计风格程序
23、设计风格最好把所有函数原型集中,放在主函数最好把所有函数原型集中,放在主函数之前之前float x,y ; float f(float ,float );float p(float ); void main() printf (please input x: );scanf(%f,&x); y=(p(x)*p(x)+(5*x)/(p(x+5)-sqrt(x)*p(x+2); printf (y(x)=%8.4fn,y) float f(float v,float w )return (w+v)/(7*v);float p(float u)return ( f(u*0.3,x+u)+(u/2)/
24、(2*x) );例例4-3 生成伪随机数生成伪随机数n n生成伪随机数公式生成伪随机数公式生成伪随机数公式生成伪随机数公式 r rk k = ( multiplier * r= ( multiplier * rk-1k-1 + increment ) % modulus + increment ) % modulus 如下给定三个常数值如下给定三个常数值如下给定三个常数值如下给定三个常数值, , 产生产生产生产生 65536 65536个随机数个随机数个随机数个随机数multiplier = 25173multiplier = 25173increment = 13849increment =
25、 13849modulus = 2modulus = 21616 = 65536 = 65536 随机数序列随机数序列随机数序列随机数序列的的的的k-1k-1项项项项#define multiplier 25173#define increment 13849 #define modulus 65536 int seed=0 ;int random ( void ) seed = ( multiplier * seed + increment ) % modulus ; return seed ;seedseedseedseed是外部变量,在第一次调用该函是外部变量,在第一次调用该函是外部变量
26、,在第一次调用该函是外部变量,在第一次调用该函数前必须给数前必须给数前必须给数前必须给seedseedseedseed赋予初始值赋予初始值赋予初始值赋予初始值n n模拟掷骰子,函数修改成模拟掷骰子,函数修改成模拟掷骰子,函数修改成模拟掷骰子,函数修改成: :int random ( void ) int random ( void ) seed seed = ( multiplier * seed + increment ) % modulus ;= ( multiplier * seed + increment ) % modulus ; return seed % 6 +1 ; retur
27、n seed % 6 +1 ; n n产生产生产生产生 0 0 与与与与 1 1 之间的实数型随机数序列,函数修改成之间的实数型随机数序列,函数修改成之间的实数型随机数序列,函数修改成之间的实数型随机数序列,函数修改成: :float random ( void ) float random ( void ) seed seed = ( multiplier * seed + increment ) % modulus ;= ( multiplier * seed + increment ) % modulus ; return (float)seed / modulus; return (f
28、loat)seed / modulus; 例例4-4 验证验证 Pascal 定理定理n n圆内接六边形三双对边延线的交点在一条直线上圆内接六边形三双对边延线的交点在一条直线上圆内接六边形三双对边延线的交点在一条直线上圆内接六边形三双对边延线的交点在一条直线上ABCDEFB1B2B3读入六个极角的值读入六个极角的值求六个顶点求六个顶点A, B, C, D, E, F 在直角坐标系中的坐标在直角坐标系中的坐标求三双对边交点求三双对边交点B1, B2, B3 坐标坐标验证验证B1, B2, B3 是否在一条直线上是否在一条直线上开始开始结束结束n n将将将将6 6个点的极坐标个点的极坐标个点的极坐
29、标个点的极坐标转换成直角坐标转换成直角坐标转换成直角坐标转换成直角坐标n n已知极角已知极角已知极角已知极角theta,theta,矢径矢径矢径矢径r, r,求求求求一点的直角坐标一点的直角坐标一点的直角坐标一点的直角坐标(px, py)(px, py)coordinatepx=r*cos(theta);py=r*sin(theta);returntrans_abcdef 转换转换a xa , ya转换转换b xb , yb转换转换d xd , yd 转换转换f xf , yf转换转换e xe , ye转换转换c xc , ycreturnn n求交点求交点求交点求交点B1,B2,B3B1,B
30、2,B3的坐标的坐标的坐标的坐标n n已知四点已知四点已知四点已知四点r, s, t, ur, s, t, u求两条直线交点求两条直线交点求两条直线交点求两条直线交点B Bthree_inter求求AB 、DE交点交点B1求求BC 、EF交点交点B2求求CD 、FA交点交点B3returnintersection 求求r, s ; t, u直线方程直线方程l1, l2求求l1、l2交点交点Breturnn n已知四点已知四点已知四点已知四点r, s, t, ur, s, t, u求两条直线求两条直线求两条直线求两条直线l1,l2l1,l2的方程的方程的方程的方程n n已知两点坐标已知两点坐标已
31、知两点坐标已知两点坐标px, py, qx, px, py, qx, qy, qy, 求直线的斜率求直线的斜率求直线的斜率求直线的斜率a a和截距和截距和截距和截距b bequtionreturn求求r,s直线方程直线方程l1求求t,u直线方程直线方程l2straightline b=(py*qx-qy*px)/(qx-px)return a=(py-qy)/(px-qx)n n已知两条直线方程斜率已知两条直线方程斜率已知两条直线方程斜率已知两条直线方程斜率分别为分别为分别为分别为ma, na; ma, na; 截距截距截距截距mb, mb, nb;nb;求直线交点求直线交点求直线交点求直线交
32、点(wx, wy)(wx, wy)n n验证验证验证验证B1, B2, B3B1, B2, B3是否在一条直线上是否在一条直线上是否在一条直线上是否在一条直线上interwx=(nb-mb)/(ma-na); wy=ma*px+mb; returntestreturn 求过求过B1, B2直线方程直线方程L判断判断B3是否在直线是否在直线L上上/*PROGRAM Pascal theorem*/#include math.h#include stdio.h#define PI 3.1415927#define eps 1e-5float radius; /* 圆的半径圆的半径 */float
33、theta1, theta2, theta3, theta4, theta5, theta6; / * 六个极角的度数六个极角的度数 */float xa, ya, xb, yb, xc, yc, xd, yd, xe, ye, xf, yf; /* 六个顶点的直角坐标六个顶点的直角坐标 */float b1_x, b1_y, b2_x, b2_y, b3_x, b3_y; /* 三个交点的直角坐标三个交点的直角坐标 */ float b12_a, b12_b; /*B1和和B2构成直线的斜率和截距构成直线的斜率和截距*/*主程序之前这段为主程序之前这段为“函数原型函数原型”以及各个函数返回结
34、果所用变量以及各个函数返回结果所用变量*/void trans_abcdef();float px, py; /* 用来保存用来保存coordinate()转换的直角坐标转换的直角坐标 */void coordinate (float, float);void three_inter();void intersection (float, float, float, float, float, float, float, float);float l1_a, l1_b, l2_a, l2_b; /* 两条直线的斜率和截距两条直线的斜率和截距 */void equation (float, fl
35、oat, float, float, float, float, float, float);float a, b; /* 直线方程的斜率和截距直线方程的斜率和截距 */void straightline(float, float, float, float);float wx, wy; /* 直线交点的直角坐标直线交点的直角坐标 */void inter (float, float, float, float);bool test (float, float, float, float, float, float);/*主函数主函数*/void main() /*读入圆形的半径读入圆形的半径
36、*/ printf(please input the radius of the circle:); scanf(%f, &radius); /*读入六个角读入六个角*/ printf(please input six angle:); scanf(%f %f %f %f %f %f, &theta1, &theta3, &theta3, &theta4, &theta5, &theta6); trans_abcdef(); /*计算六个定点坐标计算六个定点坐标*/ three_inter(); /*求三个交点求三个交点*/ if( test(b1_x, b1_y, b2_x, b2_y, b
37、3_x, b3_y) ) /*验证验证*/ printf(ok); else printf(There is an error when:n); printf(theta1=%d theta2=%dn, theta1, theta2); printf(theta3=%d theta4=%dn, theta3, theta4); printf(theta5=%d theta6=%dn, theta5, theta6); /*计算六个顶点坐标计算六个顶点坐标*/void trans_abcdef() coordinate(radius, theta1); xa=px; ya=py; coordin
38、ate(radius, theta2); xb=px; yb=py; coordinate(radius, theta3); xc=px; yc=py; coordinate(radius, theta4); xd=px; yd=py; coordinate(radius, theta5); xe=px; ye=py; coordinate(radius, theta6); xf=px; yf=py;/*计算一个顶点坐标计算一个顶点坐标*/void coordinate(float r, float theta) /* 先把先把“角度角度”转换成转换成“弧度弧度”,再转换成直角坐标,再转换成直
39、角坐标 */ px=r*cos(PI*theta/180); py=r*sin(PI*theta/180);/*求三个交点求三个交点*/void three_inter() intersection(xa, ya, xb, yb, xd, yd, xe, ye); b1_x=wx; b1_y=wy; intersection(xb, yb, xc, yc, xe, ye, xf, yf); b2_x=wx; b2_y=wy; intersection(xc, yc, xd, yd, xf, yf, xa, ya); b3_x=wx; b3_y=wy;/*已知四点,求两条直线交点已知四点,求两条
40、直线交点*/void intersection(float rx, float ry, float sx, float sy, float tx, float ty, float ux, float uy) equation (rx, ry, sx, sy, tx, ty, ux, uy); inter (l1_a, l1_b, l2_a, l2_b);/*已知四点,求两条直线方程已知四点,求两条直线方程*/void equation ( float rx, float ry, float sx, float sy, float tx, float ty, float ux, float uy
41、) straightline(rx, ry, sx, sy); l1_a=a; l1_b=b; straightline(tx, ty, ux, uy); l2_a=a; l2_b=b;/*计算由两点确定直线方程的斜率(计算由两点确定直线方程的斜率(a)和截距()和截距(b)*/void straightline(float ex, float ey, float fx, float fy) a=(fy-ey)/(fx-ex); /* 斜率斜率 */ b=ey-a*ex; /* 截距截距 */*已知两个直线方程的斜率和截距,求它们交点已知两个直线方程的斜率和截距,求它们交点*/void int
42、er ( float ma, float mb, float na, float nb) wx=(nb-mb)/(ma-na); wy=ma*wx+mb;/* 检验检验 */bool test ( float b1_x, float b1_y, float b2_x, float b2_y, float b3_x, float b3_y) straightline(b1_x, b1_y, b2_x, b2_y); if(fabs(b3_y-(a*b3_x+b)eps) return true; else return false;本章小结本章小结n n函数的定义函数的定义n n函数的调用函数的调用函数的程序设计思想函数的程序设计思想作业作业4.14.84.12结束结束