首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

3.2  库函数

3.2.1  预定义函数和代码复用

软件工程的基本目标是编写无差错代码。代码复用是实现该目标的一种方法,也就是随时重复使用已经存在并测试过的程序片段。简而言之就是“为什么要重打锣另开张?”

C语言通过提供许多预定义函数来鼓励复用,这些函数可以完成数学计算。C语言的标准数学库定义了一个sqrt函数,用于完成平方根的计算。在赋值语句中的函数调用

 

y= sqrt(x);

function

name

 

argument

 
 

激活函数sqrt的代码,并传递参数x到函数中。通过函数调用可以激活该函数,而在函数执行后,函数返回结果就会取代函数调用。如果x是16.0,那么上面的赋值语句会进行下面的求值运算:

(1) x是16.0,函数sqrt计算,得到4.0。

(2) 函数返回结果4.0被赋值给y。

函数sqrt

 
可以将函数看成是一个“黑盒子”,它接受一个或多个传递的输入值,而自动返回一个输出值。图3-6给出了函数sqrt的调用。x的值(16.0)是函数的输入,函数的结果(或者说输出)是(最终结果是4.0)。

图3-6  函数sqrt作为一个“黑盒子”

如果w是9.0,赋值语句

z = 5.7 + sqrt(w);

将按照下面步骤求值:

(1) w是9.0,函数sqrt计算9.0的平方根,得到3.0。

(2) 将5.7和3.0两个值相加。

(3) z中存储相加值8.7。

例3-1        图3-7中的程序给出了输入的两个数(first和second)的平方根,以及这两个数和的平方根。因此,该程序必须调用C函数sqrt三次:

      first_sqrt=sqrt(first);

      second_sqrt=sqrt(second);

      sum_sqrt=sqrt(first+second);

前两个函数调用中的参数是变量(first和second),而第三个调用说明函数的参数还可以是表达式(first+second)。这三个调用函数sqrt的结果都赋给一个变量。因为标准sqrt函数的定义在标准数学库中,因此程序开头要加上一条#include指令。

109.   /*

110.    * Performs three square root computations

111.    */

112.    

113.   #include <stdio.h> /* definitions of printf, scanf */

114.   #include <math.h>  /* definition of sqrt */

115.    

116.   int

117.   main(void)

118. {

119.         double first, second,    /* input - two data values         */

120.                  first_sqrt,      /* output - square root of first   */

121.                  second_sqrt,     /* output - square root of second  */

122.                  sum_sqrt;        /* output - square root of sum     */

123.  

124.         /* Get first number and display its square root.  */

125.         printf("Enter the first number> ");

126.         scanf("%lf", &first);

127.         first_sqrt = sqrt(first);

128.         printf("The square root of the first number is %.2f\n", first_sqrt);

129.          /* Get second number and display its square root. */

130.         printf("Enter the second number> ");

131.         scanf("%lf", &second);

132.         second_sqrt = sqrt(second);

133.         printf("The square root of the second number is %.2f\n", second_sqrt);

134.   

135.         /* Display the square root of the sum of the two numbers. */

136.         sum_sqrt = sqrt(first + second);

137.         printf("The square root of the sum of the two numbers is %.2f\n",

138.                  sum_sqrt);

139.  

140.         return (0);

141. }

  Enter the first number> 9.0

  The square root of the first number is 3.00

  Enter the second number> 16.0

  The square root of the second number is 4.00

  The square root of the sum of the two numbers is 5.00

图3-7  平方根程序

仔细观察图3-7中的程序,会发现每一条语句都包含对库函数的调用(printf、scanf、sqrt)——这里在编写新程序时已经使用了C的预定义函数作为程序的组成部分。

3.2.2  使用灰色区分新结构

在图3-7中,将新结构所在的程序行用灰色标出,这样容易区分。在后面包含程序的图中仍会采用这样的方法。

3.2.3  C库函数

表3-1列出了一些最常用的函数及其说明,以及使用每个函数所需要的包含在#include中的标准头文件名。完整的标准库函数在附录B中列出。

表3-1  部分数学库函数

函    数

标准头文件

说明:示例

参    数

返回结果

abs(x)

<stdlib.h>

返回整数参数的绝对值:若x=-5,abs(x)=5

int

int

ceil(x)

<math.h>

返回不小于x的最小整数值:若x=45.23,ceil(x)=46.0

double

double

cos(x)

<math.h>

返回角x的余弦值:若x=0.0,cos(x)=1.0

double

(弧度)

double

exp(x)

<math.h>

返回ex,其中e=2.71828…:若x=1.0,exp(x)= 2.71828

double

double

fabs(x)

<math.h>

返回double型参数的绝对值:若x=-8.432,fabs(x)=8.432

double

double

floor(x)

<math.h>

返回不大于x的最大整数:若x=45.23,floor(x)=45.0

double

double

log(x)

<math.h>

返回x的自然对数(x>0.0):若x=2.71828,log(x)=1.0

double

double

log10(x)

<math.h>

返回x以10为底的对数(x>0.0):若x=100.0,log10(x)=2.0

double

double

pow(x,y)

<math.h>

返回xy,若x是负数,y必须是整数:若x=0.16,y=0.5,pow(x,y)=0.4

double,

double

double

sin(x)

<math.h>

返回角x的正弦值:若x=1.5708,sin (x)=1.0

double

(弧度)

double

sqrt(x)

<math.h>

返回x的非负平方根(x≥0.0):若x=2.25,sqrt(x)=1.5

double

double

tan(x)

<math.h>

返回角x的正切值:若x=0.0,tan(x)=0.0

double

(弧度)

double

如果表3-1中的某个函数被调用时的数值参数并不是参数表中列出的类型,那么该参数在使用前必须转换为要求的类型。int型的值转换为double型没有问题,但是double型的值要转换为int型就会将小数部分丢失,就如同混合类型赋值一样。例如,若以double型值-3.47调用函数abs,那么函数返回结果为int型值3。因此,对double型参数要使用库中的另一个绝对值函数(fabs)。

表3-1中的大部分函数是数学运算函数。函数log和log10的参数必须为正,而函数sqrt的参数必须为非负。函数sin、cos和tan的参数应以弧度表示,而不能以角度表示。

例3-2   利用C函数pow和sqrt计算如下的x的二次方程式的根:

当判别式(b2-4ac)大于0时,方程的两个根定义为

假设判别式大于0,那么可以用下面的赋值语句给root_1和root_2赋值。

/* Compute two roots,root_1 and root_2,for disc>0.0 */

disc=pow(b,2)-4*a*c;

root_1=(-b+sqrt(disc))/(2*a);

root_2=(-b-sqrt(disc))/(2*a);

例3-3   已知一个三角形的两条边bc,以及它们之间的夹角α,利用下面的公式计算第三条边a(见图3-8):

要使用数学库中的余弦函数(cos),必须将参数角表示为弧度,而不是角度。为此,只要给角度乘以π/180就可以将其转换为弧度。如果用PI表示常数π,那么下面的赋值语句将计算第三边的边长:

a=sqrt(pow(b,2)+pow(c,2)

-2*b*c*cos(a*PI/180.0));

图3-8  具有未知边a的三角形

3.2.4  本节目标

C语言中还可以编写自己的函数。假设我们已经编写过函数find_area和find_circum:

函数find_area(r)返回半径为r的圆的面积。

函数find_circum(r)返回半径为r的圆的周长。

在本章前面的两个程序(见图3-3和图3-5)中可以复用这两个函数。图3-3中的程序计算圆面积和周长。语句

area=find_area(radius);

circum=find_circum(radius);

可以求出数值。每个赋值语句的表达式部分都是一个带参数radius(圆半径)的函数调用。每个函数调用后的返回值都存储在程序的输出变量中(area或circum)。

在平垫圈程序中(图3-5),可以使用语句

rim_area=find_area(edge_radius)-find_area(hole_radius);

计算垫圈的环形面积。这条语句比原来的程序语句(39~40行)更清晰一些。

练习

自测

1. 用C函数编写下列数学表达式。

a.                       b.     loge(xy)

c.                        d.      |xy-w/z|

2. 求出下面表达式的值:

a.   floor(15.8)

b.   floor(15.8+0.5)

c.   ceil(-7.2)*pow(4.0,2.0)

d.   sqrt(floor(fabs(-16.8)))

e.   log10(1000.0)

编程

1. 编写语句,要求实现计算并显示两个double型变量xy(|x-y|)的绝对差。

2. 编写完整的C程序,提示用户输入两个点(x1, y1)和 (x2, y2)的直角坐标,利用下面的公式计算它们之间的距离并显示:

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论