第六章 函数
6.1 多国货币兑换
例1:英国预算1万英镑,美国2万美元,欧洲3万欧元,需要多少人名币
#include <stdio.h>
//函数:英镑到人民币
double PoundToRmb (double pound,double rate)
{
double rmb;
rmb=pound*rate;
return rmb;
}
int main(void)
{
double pound = 10000;//会自动转换类型的
double poundRate=8.7462;
printf("%f",PoundToRmb(pound,poundRate));
return 0;//表示程序正常退出
}
6.2 模块化程序设计
为了降低开发大规模软件的复杂度,可以将大型任务分解为若干小问题,小问题可以继续分割为更小的问题,这种分而治之的策略称为模块化程序设计
1 函数是什么
简单来说,函数是完成特定功能的代码块,可以把函数看成一个黑盒
2 函数的分类
库函数
标准库函数stdio.h,还有其他第三方开发的库函数,比如math.h
用户自定义函数
①程序开发中,仅使用系统库函数难以满足需要,这是就需要自己动手编写函数来实现特定功能
②函数又可以分为有参函数和无参函数(rand函数)
③也可以分为有返回值函数(有return语句)和无返回值函数
6.3 必备知识
1 函数定义和调用
定义的一般形式:
返回值类型 函数名(形式参数列表)
{
函数体;
}
return语句结束当前函数的执行,将控制权交还给调用者,有返回值的函数必须有return语句
函数一般调用形式:
函数名(实参列表)
当函数无返回值时,可以在函数调用格式化后加上分号后进行函数调用
printMenu();
例2:输入两个实数,调用add函数求和
#include <stdio.h>
double add(double a,double b)
{
double sum;
sum=a+b;
return sum;
}
int main(void)
{
double m,n;
double sum;
m=12.1;
n=11.2;
sum=add(m,n);
printf("%lf",sum);
return 0;
}
函数形参和实参的特点
①形参变量只有在被调用时才分配内存单元,在调用结束时,即释放所分配的内存单元,因此形参只在函数内部有效
②实参可以是常量、变量、表达式、函数等,在进行函数调用时,实参必须有确定的值,以便把这些值传递给形参
③实参和形参在个数、类型和顺序上应严格一致,否则会发生类型不匹配错误
例3:无返回值函数的定义和调用,printMenu完成固定菜单打印
#include <stdio.h>
void printMenu(void)
{
printf("请选择:\n");
printf(" A 功能A\n");
printf(" B 功能B\n");
printf(" C 功能C\n");
printf(" D 功能D\n");
return ;
}
int main(void)
{
printMenu();
return 0;
}
2 函数原型说明
①c语言变量使用的一个基本原则是”先定义,后调用“,所以必须把自己定义的函数放在main函数前面,但是这样不容易理解,人们更希望将main函数放在前面,怎么办?
②可以使用函数原型说明,指出函数的返回值类型和形式参数列表,但是不包括处理语句
double add(double a,double b);//函数原型说明
int main(void)
{
sum=add(1,2);//主函数内调用
}
double add(double a,double b)//具体进行说明
{
return a+b;
}
3 函数参数传递方式
函数的参数传递方式为值传递,在值传递时,实参的值被复制到被调用函数的形参中,被调用函数使用形参进行计算,当形参改变时,不会影响到实参的值
例4:函数参数的值传递
#include<stdio.h>
void swap(int x,int y)
{
int t=x;
x=y;
y=t;
}
int main(void)
{
int a=10,b=20;
printf("a=%d,b=%d",a,b);
swap(a,b);
printf("a=%d,b=%d",a,b);
return 0;
}
例5:求x的n次幂
#include <stdio.h>
double power(double x,int n)
{
double result=1.0;
int i;
for(i=1;i<=n;i++)
{
result*=x;
}
return result;
}
int main(void)
{
double a;
int num;
a=3.7;
num=5;
printf("%.2f",power(a,num));
return 0;
}
例6:输入正整数n,*打印等腰三角形
#include <stdio.h>
void star(char ch,int n)
{
while(n-- > 0)
{
putchar(ch);
}
}
int main(void)
{
int i,n;
n=10;
for(i=1;i<=n;i++)
{
star(' ',n-i);
star('*',2*i-1);
putchar('\n');
}
return 0;
}
4 函数的嵌套调用
c语言匀速在一个函数的定义中出现对另一个函数的调用,也就是被调用的函数可以继续调用其他函数,这称为函数的嵌套调用
例7:求排列组合问题C 8 3
#include <stdio.h>
long fac(int n);
int cmn(int,int);
int main(void)
{
printf("C(8,3)=%d",cmn(8,3));
}
int cmn(int m,int n)
{
return fac(m)/(fac(n)*fac(m-n));
}
long fac(int n)
{
long s=1;
int i;
for(i=2;i<=n;i++)
{
s*=i;
}
return s;
}
5 递归函数【重要 会用递归求阶乘】
我 调用 我自己
例9:用递归函数求n的阶乘
#include <stdio.h>
long fact(int n);
int main()
{
int n;
long result;
n=5;
if(n>=0)
{
result=fact(n);
printf("%d",result);
}
return 0;
}
long fact(int n)
{
if(0==n || 1==n)
{
return 1;
}
else
{
return n*fact(n-1);
}
}
6 变量的作用域【重要】
局部变量
在一个函数内部定义的变量或在一个语句块中定义的变量,就称为局部变量,只在局部变量只在局部作用域内有效
函数的形参的作用域在函数内,也是局部变量
全局变量
在函数外部定义的变量,称为全局变量,也称外部变量,作用域为文件作用域,有效作用范围从变量定义出开始,到源程序文件结尾处结束。
7 变量的存储类型【不是很重要】
auto变量
auto int a;
用关键字auto说明的局部变量都是自动存储类型变量,属于动态存储方式,局部变量默认就是auto
注意事项
①auto变量属于动态存储类型,在执行到变量作用域是,系统动态的为变量分配存储空间,执行到变量作用域结束时,系统立刻回收变量所占用的存储空间
②没有初始化的自动型变量在赋值之前的值是不确定的
static变量
static int b;
用关键字static说明的变量称为静态存储类变量
注意事项
①静态变量是静态存储类型,程序开始运行时系统就分配存储空间, 并且在程序的执行过程中一直占用空间直到程序运行结束
②静态变量的初始化是在编译的时候完成的,且只初始化一次,如果没有指定初值默认为0
③静态变量可以是全局变量,也可以局部变量
register变量
register int i;
关键字register说明的局部变量称为寄存储器存储类型变量
注意事项
①寄存器行变量属于动态存储类型,只能是局部变量
②现在的编译器一般都可以进行最优化处理,自动判断那些变量保存在寄存器会更好,使用register声明变量的重要性已经降低了,一般不使用
extern变量
extern a;
外部变量是在函数的外部定义的,他的作用域从变量定义处开始,到本程序文件的末尾