1
上次作业中的问题
数据类型声明 (定义 )不正确
float a,b,h,s;
sum?
scanf()语句格式不正确
scanf(“%f%f%f”,&a,&b,&h);
输入数据时一定要按照上面的格式输入数据
scanf(“%f,%f,%f”,&a,&b,&h);
缺少符号或多了符号或者符号写得有错误。
第 3讲
简单 C程序设计之二
多函数程序设计
3
编写求梯形面积的程序
#include <stdio.h>
void main()
{
int a,b,h;
float s;
printf(" please input a,b,h,");
scanf("%d%d%d",&a,&b,&h);
s= (a+b)*h/2;
printf(" s=%f\n",s);
}
若 a,b,h分别是 1,2,3,结果会怎样?
s=4.000000
为什么?
因为右边的数据都是整型数,
所以计算结果也是整型了。
要想得到正确结果就需要将所有数据改为 float类型。
若全部数据类型都是 float,
s=1/2*(a+b)*h的结果又会怎样?
s=0.000000
因为 1/2中的两个常数都是整数,结果仍是整数,为 0,
再继续进行运算,结果仍为
0。
要想得到正确结果,要
s=(float)1/2*(a+b)*h(强行将 1转换 成 float类型)或
s=1.0/2*(a+b)*h(因为第一个数据是实数类型,其他的运算结果一律 自动转换 成
double类型 )
4
涉及到的语法知识
-数据类型的 自动转换 和 强制转换
当表达式中的数据类型不一致时
数据类型的 自动转换
方向,char?int?float?double
数据类型的 强制转换
在表达式前加 (数据类型 )
例,s=(float)1/2*(a+b)*h
s=(float)(1/2)*(a+b)*h的结果呢?
赋值时也存在类型转换的问题
例,upper=lower-32; int a=4.5;
值得注意的是:
不要让这种转换导致计算上的错误!
5
再例:把从键盘上输入的小写字母换成大写字母并输出。
如何转换?
将小写字母的 ASCII码减 32即得大写字母的 ASCII码。
算法:
输入小写字母 lower
计算其对应的大写字母 upper
输出 upper.
源代码如下:
#include <stdio.h>
void main()
{
char lower,upper;
printf(“please input an lowercase:”);
scanf(“%c”,&lower);
upper=lower-32; /* char与 int数据间可进行算术运算 */
printf(“lower:%c?upper:%c\n",lower,upper);
}
printf(“lo er:%d %d
6
三例:求两个整数的商与余数
算法:
输入两个整数 a,b
计算整数的 quotient,remains
输出结果 quotient,remains
#include <stdio.h>
void main()
{
int a,b; /* 定义两个整型变量 */
int quotient,remains; /* 定义两个变量存放结果 */
printf(“please input two integer:”);
scanf(“%d%d”,&a,&b);
quotient=a/b;remains=a%b; /*求模运算符 */
printf(“%d/%d=%d… %d\n",a,b,
quotient,remains); /* 显示运算结果 */
}
7
数据类型与内存空间
不同的编译器可能有不同的结果
用 sizeof()求得,不要靠经验。
#include <stdio.h>
main()
{
printf("Data type Number of bytes\n");
printf("------------ ---------------------\n");
printf("char %d\n",sizeof(char));
printf("int %d\n",sizeof(int));
printf("short int %d\n",sizeof(short));
printf("long int %d\n",sizeof(long));
printf("float %d\n",sizeof(float));
printf("double %d\n",sizeof(double));
}
sizeof(3)和 sizeof(3.0)的结果又是什么呢?
分别是 int和 double类型的所占内存的字节数,在 VC上是
4和 8,
8
涉及到的语法知识
- 运算符的 优先级 和 结合性
我们学过的运算符有:
() & sizeof() * / % + - =
单目 运算符 双目 运算符
优先级,出现多种运算符时谁先运算
()高于 & sizeof(),然后是 * / %,+ -次之,最后是 =
结合性,出现多个同级运算符时从哪边开始运算
一般从左向右 (例如:算术运算符 ),也有一些从右向左
(例如:赋值运算符 a=b=3;)。还有一些运算符,用到时再讲。
9
复杂的数学计算如何实现?
直接调用 C语言的库函数即可。
别忘了加 #include <math.h>
请记住几个常用的函数:
函数名 功 能 函数名 功 能
sqrt(x) 计算 x的平方根,x应大于等于 0 exp(x) 计算 ex的值
fabs(x) 计算 x的绝对值 pow(x,y) 计算 xy的值
log(x) 计算 lnx的值 sin(x) 计算 sinx的值,x为弧度值
log10(x) 计算 lgx的值 cos(x) 计算 cosx的值,x为弧度值
10
改装以前的程序
问题仍是:计算梯形的面积
将该问题放在一个 函数 里解决,即编写一个函数 s(a,b,h).
有几个 参数,数据类型是什么?
(float a,float b,float h)
结果又是什么类型?
float s(float a,float b,float h)
11
函数定义
/*函数功能:求梯形面积函数参数,float a表示上底,float b表示下底,float h表示高函数返回值:梯形面积 */
float s(float a,float b,float h)
{
return (a+b)*h/2;
}
三个 形式参数返回值 类型函数名称返回语句函数体
void s(float a,float b,float h)
{
printf(“area=%f”,(a+b)*h/2);
}
函数定义相当于建立一个 s(a,b,h)=(a+b)*h/2这样一个函数的形式化表示,此时没有具体的数值
12
在 main函数中怎样 调用 呢?
#include<stdio.h>
float s(float,float,float);/*函数声明 */
float s(float a,float b,float h)
{
return (a+b)*h/2;
}
void main()
{ float a,b,h,area;
printf(" please input a,b,h,");
scanf(“%d%d%d”,&a,&b,&h);/*假设输入的数据是 1,2,3*/
area= s(a,b,h); /*函数调用,相当于数学函数的代入,a,b,h
有确切的数值,因此称为 实参,函数的返回值赋值给 area,相当于计算 area=s(1,2,3)*/
printf(" area=%f\n",area);
}
13
运行过程
#include<stdio.h>
float s(float,float,float);/*函数声明 */
float s(float a,float b,float h)
{
return (a+b)*h/2;
}
void main()
{ float a,b,h,area;
printf(" please input a,b,h,");
scanf("%d%d%d",&a,&b,&h);
area= s(a,b,h); /*实参向形参单向传递数值 */
printf(" area=%f\n",area);
}
14
涉及的语法
- 函数定义 格式
/* 函数功能:实现 ×××× 功能函数参数:参数 1,表示 ×××××
参数 2,表示 ×××××
...
函数返回值,×××××
*/
返回值类型 函数名 (参数表 )
{
函数体
}
养成注释的好习惯:
15
涉及的语法
- 函数调用 ( call)
调用即使用已经定义好的函数。
调用函数时,必须提供所有的参数
printf和 scanf是采用变长变量表定义的函数,
所以变量的个数不固定。
提供的参数 个数、类型、顺序 应与定义时相同
单向 值传递
16
涉及的语法
-函数调用格式
函数调用的一般形式:
函数名(实参列表)
具体调用格式:
有返回值时
放到一个数值表达式中,如 area = s(a,b,h);
作为另一个函数调用的参数,如
printf(“area=%f\n",s(a,b,h));
无返回值时
函数调用表达式,如 printf(“hello!”);
注意,main()函数可以调用其它函数,但它不可以被其它函数调用。即:它只能作为 主调函数,不能作为 被调函数
17
涉及的语法
- 函数原型 或 函数声明
调用一个函数之前,先要对其返回值类型、
函数名和参数进行声明( declare)
不对函数进行声明是非常危险的
声明时不要省略参数以及返回值的类型
一般都写在编译预处理命令之后。
18
函数的分类
从使用角度:
库函数,直接使用 (调用 )
自定义函数:用户需要自己先定义,然后使用。
根据返回值:
有返回值:需要返回计算结果
无返回值:不需要返回计算 (处理 )结果
根据参数:
无参函数,clrscr()
有参函数,pow(x,y)
19
练习:编写函数,将 小写字母转换成大写字母#include <stdio.h>
char atoA(char);/*函数声明 */
char atoA(char lower) /* 函数定义:将小写字母转换成大写字母 */
{
return (lower-32);
}
void main()
{
char lower,upper;
printf(" please input an lowercase,");
scanf("%c",&lower);
upper= atoA(lower);
printf(" lower:%c->upper:%c\n",lower,upper);
}
printf(" lower:%c->upper:%c\n",lower,atoA(lower));
20
本讲小结
要求
能够编写 多函数 程序
理解函数的调用过程和程序的执行顺序
应掌握的语法内容
数据类型的自动转换和强制转换
几种运算符以及它们的优先级和结合性
掌握常用的几个数学函数的用法
函数的定义、调用、声明格式 (重点中的重点)
21
作业
定义两个函数分别实现求圆的面积和周长,并在主函数中调用这两个函数。
习题 2.4
习题 2.5(读程序要求为每条语句加注释和写明最终输出结果 )