例5-1. 输入圆柱体的高和半径,求圆柱体的体积$volume=\pi\times r^2\times h$,要求定义和调用函数cylinder(r, h)计算圆柱体积
#include<stdio.h>
double cylinder(double r, double h); /* 函数声明 */
int main()
{
double height, radius, volumne;
printf("Enter radius and height: ");
scanf("%lf%lf", &radius, &height);
volume=cylinder(radius, height); /* 函数调用,将函数的返回值赋给volume */
printf("Volume=%.3f\n", volume);
return 0;
}
double cylinder(double r, double h) /* 定义函数求圆柱体的体积 */
{
double result;
result=3.1415926*r*r*h; /* 计算体积 */
return result; /* 返回结果 */
}
函数调用是如何运行的?
函数定义形式:
/* 函数首部 函数类型为返回值的类型,与return语句中表达式的类型一致 */
/* 函数类型 double, 函数名 cylinder, 参数列表 double r和double h */
double cylinder(double r, double h) /* 函数首部 */
{ /* 函数体,写在一对大括号内 */
double result; /* 函数内的局部变量 */
result=3.1415926*r*r*h; /* 计算圆柱体积 */
return result; /* 返回运算结果,类型与函数类型一致 */
}
double cylinder(double r, double h)
{
double result;
result=3.1415926*r*r*h;
return result;
}
函数的参数列表必须写成:
参数之间用
程序执行
如果遇到函数调用,
函数执行完毕后,
如果调用函数执行过程中遇到return,则直接返回主函数
见DevC++
#include<stdio.h>
double cylinder(double r, double h); /* 函数声明 */
int main()
{
double height, radius, volumne;
printf("Enter radius and height: ");
scanf("%lf%lf", &radius, &height);
volume=cylinder(radius, height); /* 函数调用 8-->12 */
printf("Volume=%.3f\n", volume);
return 0;
}
double cylinder(double r, double h) /* 参数列表赋值,实参->形参 */
{
double result; /* 执行函数中的语句 */
result=3.1415926*r*r*h;
return result; /* 返回结果到调用的地方,第8行 */
}
调用函数完成计算后,将运算结果返回给
return 表达式;
return可用于返回函数运算的结果,也可用于终止调用函数的运行。函数只能返回一个值,如需要返回多个值,需采用其它方法实现
函数声明,只写函数的首部,以分号结束,不包含函数体,即函数的实现部分
double volume(double r, double h);
void pyramid(int n);
例5-2. 计算五边形的面积
将一个五边形分割成3个三角形,输入这些三角形的7条边长,计算该五边形的面积。要求定义和调用函数area(x,y,z)计算边长为x,y,z的三角形面积
#include<stdio.h>
#include<math.h>
double area(double x, double y, double z);
int main()
{
double a1, a2, a3, a4, a5, a6, a7, s;
printf("Please input 7 side lengths in the order a1 to a7:");
scanf("%lf%lf%lf%lf%lf%lf%lf", &a1, &a2, &a3, &a4, &a5, &a6, &a7);
s=area(a1, a5, a6)+area(a4, a6, a7)+area(a2, a3, a7); /* 调用三次area函数计算面积 */
printf("The area of the pentagon is %.2f\n", s);
return 0;
}
/* 使用海伦-秦九韶公式计算三角形面积的函数 */
double area(double x, double y, double z)
{
double p=(x+y+z)/2;
return sqrt(p*(p-x)*(p-y)*(p-z));
}
练习. 判断奇偶数
定义一个判断奇偶数的函数even(n),当n为偶数时返回1,否则返回0。利用该函数计算1-500之间所有偶数的和
#include<stdio.h>
/* 判断奇偶性的函数 */
int even(int n)
{
if(n%2==0)
return 1;
else
return 0;
}
/* 求1-500之间所有偶数的和 */
int main()
{
int i, sum=0;
for(i=1; i<=500; i++)
{
if(even(i)==1)
sum=sum+i;
}
printf("%d", sum);
return 0;
}
例5-3. 判断完全平方数
定义一个判断完全平方数的函数isSquare(n),当n为完全平方数时返回1,否则返回0,不允许使用数学库函数
如果n是完全平方数,则可以找到正整数m使$n=m^2$成立。在
#include<stdio.h>
int isSquare(int n)
{
int i;
for(i=1; n>0; i=i+2)
{
n=n-i;
}
if(n==0)
return 1; /* 是完全平方数返回1 */
else
return 0; /* 不是完全平方数返回0 */
}
int main()
{
int n;
printf("Enter n:");
scanf("%d", &n);
if(isSquare(n)==1)
printf("%d is complete square number.\n", n);
else
printf("%d is not a complete square number.\n", n);
}
例5-4. 求最大公约数
定义函数gcd(int m, int n),计算m和n的最大公约数
辗转相除法(欧几里得算法)
1. temp=m%n
2. 若temp为0,返回n的值,否则转3.
3. m=n, n=temp, 转1继续
#include<stdio.h>
int gcd(int m, int n)
{
int r, temp;
if(m<n) /* 保证m比n大 */
{
temp=m;
m=n;
n=temp;
}
r=m%n;
while(r!=0){
m=n;
n=r;
r=m%n;
}
return n;
}
int main()
{
int m, n;
int g;
printf("Enter two numbers m, n(m>n):");
scanf("%d%d", &m, &n);
g=gcd(m, n);
printf("GCD of %d and %d is %d", m, n, g);
return 0;
}
例5-5. 使用函数判断素数
求100以内的全部素数,每行输出10个。素数是只能被1和自身整除的正整数,1不是素数,2是素数。
要求定义和调用函数prime(m)判断m是否为素数,当m为素数时返回1,否则返回0
#include<stdio.h>
#include<math.h>
int prime(int m)
{
int i, n, limit;
if(m<=1)
return 0;
else if(m==2)
return 1;
else{
limit=sqrt(m)+1;
for(i=2; i<=limit; i++){
if(m%i==0)
return 0;
}
}
return 1;
}
int main()
{
int count, m;
count=0;
for(m=2; m<=100; m++){
if(prime(m)!=0){
printf("%6d", m);
count++;
if(count%10==0)
printf("\n");
}
}
printf("\n");
return 0;
}
示例. 使用函数求$\pi$的近似值
输入精度e,使用格雷戈里公式求$\pi$的近似值,精确到最后一项的绝对值小于e
$$
\frac{\pi}{4}=\frac{!}-\frac{1}{3}+\frac{1}{5}-\frac{1}{7}+\cdots
$$
#include<stdio.h>
#include<math.h>
double funpi(double e)
{
int denominator, flag;
double item, sum;
flag=1;
denominator=1;
item=1.0;
sum=0;
while(fabs(item)>=e){
sum=sum+item;
flag=-flag;
denominator=denominator+2;
item=flag*1.0/denominator;
}
sum=sum+item;
return sum*4;
}
int main()
{
double e, pi;
printf("Enter e:");
scanf("%lf", &e);
pi=funpi(e);
printf("pi=%f\n", pi);
return 0;
}
例5-6. 数字金字塔
输入一个正整数,输出n行数字金字塔。如当n=5时,输出的金字塔如下图所示
#include<stdio.h>
void pyramid(int n) /* 函数定义 */
{
int i, j;
for(i=1; i<=n; i++){ /* 需要输出的行数 */
for(j=1; j<=n-i; j++){ /* 输出每行左边的空格 */
printf(" ");
}
for(j=1; j<=i; j++){ /* 输出每行的数字 */
printf("%d ", i); /* 注意每个数字后有空格 */
}
putchar('\n'); /* 换行 */
}
}
int main()
{
int n;
printf("Enter n:");
scanf("%d", &n);
pyramid(n);
return 0;
}
{
函数实现体
return;
}
函数定义中,
返回类型为void的函数一般用于输出
学生成绩统计程序经分解后得到树状结构,每个模块均设计为独立的函数,整个程序通过调用函数实现
例5-7. 计算两个复数的和与积
分别输入两个复数的实部与虚部,用函数实现计算两个复数的和与积
若两个复数分别为: c1=x1+y1
则有
c1+c2=(x1+x2)+(y1+y2)
c1*c2=(x1*x2-y1*y2)+(x1*y2+x2*y1)
#include<stdio.h>
double result_real, result_imag; /* 全局变量,用于存放函数结果 */
void complext_add(double real1, double imag1, double real2, double imag2)
{
result_real=real1+real2;
result_imag=imag1+imag2;
}
void complex_prod(double real1, double imag1, double real2, double imag2)
{
result_real=real2*imag1-real1*imag2;
result_imag=real1*imag2+real2*imag1;
}
int main()
{
double real1, real2, imag1, imag2; /* 两个复数的实部和虚部 */
printf("Enter 1st complex number(real and imaginary):");
scanf("%lf%lf", &real1, &imag1);
printf("Enter 2nd complex number(real and imaginary):");
scanf("%lf%lf", &real2, &imag2); /* 分别输入两个复数的实部和虚部 */
complex_add(real1, imag1, real2, imag2); /* 计算两个复数的和 */
printf("addition of complex is %f+%fi\n", result_real, result_imag);
complex_prod(real1, imag1, real2, imag2); /* 计算两个复数的积 */
printf("product of complex is %f+%fi\n", result_real, result_imag);
return 0;
}
#include<stdio.h>
int main()
{
int a;
a=1;
{ /* 复合语句开始 */
int b=2;
b=a+b;
a=a+b;
} /* 复合语句结束 */
printf("%d", a);
return 0;
}
上述代码的输出是什么?如果将11行改为
#include<stdio.h>
int x; /* 定义全局变量x */
int f()
{
int x=4; /* x是局部变量 */
return x;
}
int main()
{
int a=1;
x=a; /* 对全局变量x赋值 */
a=f(); /* a的值为4 */
{
int b=2;
b=a+b; /* b的值为6 */
x=x+b; /* 全局变量运算, x的值为7 */
}
printf("%d %d", a, x);
return 0;
}
若局部变量与全局变量同名,局部变量优先
int x=1;
void main()
{
int a=2;
//......
{
int b=3; /* x=? a=? b=? */
//......
}
f();
//...... /* b=? */
}
int t=4;
void f()
{
int x=5, b=6; /* x=? a=? b=? t=? */
//......
}
int a=7; /* a=? b=? t=? x=? */
例5-8. 用函数实现财务现金记账
先输入操作类型: 1. 收入,2. 支出,0. 结束。再输入操作金额,计算现金剩余额,经多次操作直到输入操作类型为0时结束。要求定义并调用函数,其中现金收与现金支出分别用不同函数实现
分析:设变量cash保存现金余额值,由于它被主函数、现金收入与现金支出函数共用,任意使用场合其意义与数值都是明确且唯一的,因此将其设为全局变量
#include<stdio.h>
double cash; /* 定义全局变量,保存现金余额 */
void income(double number) /* 定义现金收入函数 */
{
cash=cash+number; /* 改变全局变量cash的值 */
}
void expend(double number) /* 定义现金支出函数 */
{
cash=cash-number; /* 改变全局变量cash的值 */
}
int main()
{
int choice;
double value;
cash=0; /* 初始金额为0 */
printf("Enter operation choice(0-end, 1-income, 2-expend):");
scanf("%d", &choice);
while(choice!=0){ /* 若输入类型为0,结束循环 */
if(choice==1 || choice==2){
printf(“Enter cash value:"); /* 输入操作现金额 */
scanf("%f", &value);
if(choice==1)
income(value); /* 函数调用,计算现金收入 */
else
expend(value); /* 函数调用,计算现金支出 */
printf("Current cash: %.2f\n", cash);
}
printf("Enter operation choice(0-end, 1-income, 2-expend):");
scanf("%d", &choice);
}
return 0;
}
静态局部变量的作用范围是局部,但其生命周期是存在于全局
例5-9. 计算阶乘
输入正整数n,输出1!~n!的值。要求定义并调用含静态变量的函数fact_s(n)计算n!
#include<stdio.h>
double fact_s(int n)
{
static double f=1;
f=f*n;
return f;
}
int main()
{
int i, n;
printf("Enter n:");
scanf("%d", &n);
for(i=1; i<=n; i++)
printf("%3d!=%.0f\n", i, fact_s(i));
return 0;
}