<一>return语句
深入学习return语句,在有返回值的函数中,return语句的作用是提供整个函数的返回值,并结束当前函数返回到调用它的地方。在没有返回值的函数中也可以使用return语句。例如:当检查到一个错误时提前结束当前函数的执行并返回:
对数的概念log,英语名词:logarithms。如果a^b=n,那么log(a)(n)=b。其中,a叫做“底数”,n叫做“真数”,b叫做“以a为底的n的对数”。 log(a)(n)函数叫做对数函数。对数函数中n的定义域是n>0,零和负数没有对数;a的定义域是a>0且a≠1。现在底数为a=10,对数为1,则真是为0。
print_logarithm()函数调用判断时,如果x小于0.0,则输出Positive numbers only, please.然后返回函数值,结束当前函数调用,返回到调用它的主函数,继续执行下一条语句,现在在print_logarithm()函数的if语句return后面加多一条多余的代码,如果不是在执行return语句后中断,则会在打印多一个Positive numbers only, please.语句。为什么要用math.h头文件,因为使用到数学函数loga(n)=b
#include <stdio.h>
#include <math.h>
void print_logarithm(double x)
{
if (x <= 0.0) {
printf("Positive numbers only, please.\n");
return;
printf("Positive numbers only, please.\n");
}
printf("The log of x is %f", log(x));
}
int main(void)
{
print_logarithm(-1.0);
print_logarithm(1.0);
return 0;
}
事实说明return返回函数值后中断,后面语句不再执行。加一行Dead Code,很容易引起bug.其实执行的语句可以换成布尔类型,如果为真返回1,否则返回0.
习题
1、编写一个布尔函数int is_leap_year(int year),判断参数year是不是闰年。如果某年份能被4整除,但不能被100整除,那么这一年就是闰年,此外,能被400整除的年份也是闰年。
2、编写一个函数double myround(double x),输入一个小数,将它四舍五入。例如myround(-3.51)的值是-4.0,myround(4.49)的值是4.0。可以调用math.h中的库函数ceil和floor实现这个函数。
#include <stdio.h>
int is_leap_year(int year)
{
if(year%4 == 0 && year%100 != 0)
{
return 1;
}
else
{
if(year%400 == 0)
{
return 1;
}
else
{
return 0;
}
}
}
int main()
{
int x;
printf("Please input year:\n");
scanf("%d",&x);
printf("%d\n",is_leap_year(x));
return 0;
}
希尔函数主要判断方便,如果为真返回1,如果为假返回0;
#include <stdio.h>
#include <math.h>
double myround(double x)
{
int a;
a=(int)x;
if(x > 0 )
{
if(x-a >= 0.5)
{
x=ceil(x);
return x;
}
else
{
x=floor(x);
return x;
}
}
else if(x < 0)
{
if(x-a <= -0.5)
{
x=floor(x);
return x;
}
else
{
x=ceil(x);
return x;
}
}
else
{
return x;
}
}
int main()
{
double x;
printf("Please input double x:\n");
scanf("%lf",&x);
printf("%lf\n",myround(x));
return 0;
}
ceil()和floor()函数是库函数,属于数学函数调用,因此头文件要添加math.h说明.编译时,gcc编译器不会连接math.h头文件,所以在编译时加上-lm参数。ceil()函数是向上舍入,floor()函数是向下舍入。如:ceil(-3.51)=-3.00,floor(-3.5.1)=-4.00,ceil(4.49)=5.00,floor(4.49)=4.00,该函数的缺点就是,不会自动帮你判断小数为的大小进行四舍五入。因此要自己取小数进行判断,然后对判断结果来执行不同的语句。
<二>增量式开发
增量式开发开发时初学者及开发人员检查程序bug的一种方式。很适合初学者。每做一步就测试一次,查看编写代码是否有bug。这样排除容易。
现在练习一个例子:
已知圆的半径的两个端点的坐标,圆心(x1,y1)和圆上任意一点(x2,y2).求圆的面积,开平方根用到sqrt数学函数。
1.用到的两点间的距离公式:
distance = √((x2-x1)2+(y2-y1)2)
2.求出圆半径,求圆公式:
area = π・radius2
#include <stdio.h>
#include <math.h>
double distance(double x1,double y1,double x2,double y2)
{
double dx = x2 - x1;
double dy = y2 - y1;
/*printf("dx is %f\ndy is %f\n",dx,dy);*/
double dsquared = dx * dx + dy * dy;
/*printf("dsquared is %f\n",dsquared);*/
double result = sqrt(dsquared);
return result;
/*return 0.0;*/
}
double area(double radius)
{
return 3.1416 * radius * radius;
}
int main()
{
printf("%f\n",distance(1.0,2.0,4.0,6.0));
printf("%f\n",area(distance(1.0,2.0,4.0,6.0)));
return 0;
}
通常测试可以很清楚的知道那步写错了,找bug方便容易。有很多高手都是一步到位的。return sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));为了维护方便,将所要重复用到的函数封装起来,尽可能复用(Reuse)以前写的代码,避免写重复的代码
<三>递归
经典的例子算阶乘,
#include <stdio.h>
int factorial(int n)
{
if (n == 0)
return 1;
else {
int recurse = factorial(n-1);
int result = n * recurse;
return result;
}
}
int main()
{
int x;
printf("Please input x:\n");
scanf("%d",&x);
printf("%d\n",factorial(x));
return 0;
}
用gdb检查一下:
由于需要使用GDB进行调试,需要在编译连接的时候加-g选项,生产的factorial即为带有调试信息的程序,调试信息是目标文件和可执行程序中加入了对源代码的引用,为保证调试信息可用,源代码必须存在,且路径不能改变。GDB的基本操作时使用GDB命令启动可执行程序。主要使用的命令式run(开始运行程序)、break(设置断点)、next(执行一行且不进入函数)、step(
进入函数)、contiune(继续程序运行)这个接下来会讲到。
今天到这里。。。。