第七章 C语言函数
7.1什么是函数?概念
我们将常用的代码以固定的格式封装(包装)成一个独立的模块,只要知道这个模块的名字就可以重复使用它,这个模块就叫做函数(Function)。
用比较字符串大小的函数讲解函数的封装以及一些注意事项。
库函数和自定义函数
C语言自带的函数称为库函数(Library Function)。库(Library)是编程中的一个基本概念,可以简单地认为它是一系列函数的集合,在磁盘上往往是一个文件夹。C语言自带的库称为标准库(Standard Library),其他公司或个人开发的库称为第三方库(Third-Party Library)。
除了库函数,我们还可以编写自己的函数,拓展程序的功能。自己编写的函数称为自定义函数。自定义函数和库函数在编写和使用方式上完全相同,只是由不同的机构来编写。
参数
参数是函数需要处理的数据,函数名后括号中包含的数据或变量
例如:
strlen(str1)用来计算字符串的长度,str1就是参数。
形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。
形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用 。(函数外部???)
函数调用中发生的数据传递是单向的,只能把实参的值传递给形参,而不能把形参的值反向地传递给实参;换句话说,一旦完成数据的传递,实参和形参就再也没有瓜葛了,所以,在函数调用过程中,形参的值发生改变并不会影响实参。
形参和实参虽然可以同名,但它们之间是相互独立的,互不影响,因为实参在函数外部有效,而形参在函数内部有效。
#include <stdio.h>
//计算从m加到n的值
int sum(int m, int n) {
int i;
for (i = m + 1; i <= n; ++i) {
m += i;
}
return m;
}
int main() {
int m, n, total;
printf("Input two numbers: ");
scanf("%d %d", &m, &n);
total = sum(m, n);
printf("m=%d, n=%d\n", m, n);
printf("total=%d\n", total);
return 0;
}
运行结果:
Input two numbers: 1 100
m=1, n=100
total=5050
返回值
返回值就是函数的执行结果
例如:
char str1[ ] = “C Language”;
int len = strlen(str1);
strlen() 的处理结果是字符串 str1 的长度,是一个整数,我们通过 len 变量来接收。
函数返回值有固定的数据类型(int、char、float等),用来接收返回值的变量类型要一致。
return 语句可以有多个,可以出现在函数体的任意位置,但是每次调用函数只能有一个 return 语句被执行,所以只有一个返回值
//返回两个整数中较大的一个
int max(int a, int b){
if(a > b){
return a;
}else{
return b;
}
}
判断是否为素数
#include <stdio.h>
int prime(int n){
int is_prime = 1, i;
//n一旦小于0就不符合条件,就没必要执行后面的代码了,所以提前结束函数
if(n < 0){ return -1; }
for(i=2; i<n; i++) //注意i的取值范围
{
if(n % i == 0)
{
is_prime = 0;//满足上面条件的不是素数
break; //提前终止循环
}
}
return is_prime;
}
int main(){
int num, is_prime;
scanf("%d", &num);
is_prime = prime(num);
if(is_prime < 0){
printf("%d is a illegal number.\n", num);
}else if(is_prime > 0){
printf("%d is a prime number.\n", num);
}else{
printf("%d is not a prime number.\n", num);
}
return 0;
}
函数一旦遇到 return 语句就立即返回,后面的所有语句都不会被执行到了。从这个角度看,return 语句还有强制结束函数执行的作用。
更改上面的代码,使得 return 后面不跟任何数据:
#include <stdio.h>
void prime(int n){
int is_prime = 1, i;
if(n < 0){
printf("%d is a illegal number.\n", n);
return; //return后面不带任何数据
}
for(i=2; i<n; i++){
if(n % i == 0){
is_prime = 0;
break;
}
}
if(is_prime > 0){
printf("%d is a prime number.\n", n);
}else{
printf("%d is not a prime number.\n", n);
}
}
int main(){
int num;
scanf("%d", &num);
prime(num);
return 0;
}
7.2函数定义
将代码段封装成函数的过程叫做函数定义。
C语言无参函数的定义
如果函数不接收用户传递的数据,那么定义时可以不带参数。(也就是没有输入时)
例如,定义一个函数,计算从 1 加到 100 的结果:
int sum(){
int i, sum=0;
for(i=1; i<=100; i++){
sum+=i;
}
return sum;
}
return是C语言中的一个关键字,只能用在函数中,用来返回处理结果。
将上面代码补充完整:
#include <stdio.h>
int sum(){
int i, sum=0;
for(i=1; i<=100; i++){
sum+=i;
}
return sum;
}
int main(){
int a = sum();
printf("The sum is %d\n", a);
return 0;
}
函数不能嵌套定义,main 也是一个函数定义,所以要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 要放在 main 前面。
main 是函数定义,不是函数调用。
无返回值函数
有的函数不需要返回值,或者返回值类型不确定(很少见),那么可以用 void 表示,例如:
void hello(){
printf ("Hello,world \n");
//没有返回值就不需要 return 语句
}
void在C语言中表示**“空类型”或“无类型”**,绝大部分情况下也就意味着没有 return 语句。
C语言有参函数的定义
参数本质上也是变量,定义时要指明类型和名称。
数据通过参数传递到函数内部进行处理,处理完成以后再通过返回值告知函数外部。
函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(也就是传递的数据)称为实际参数,简称实参。
函数调用时,将实参的值传递给形参,相当于一次赋值操作。
原则上讲,实参的类型和数目要与形参保持一致。
#include <stdio.h>
int sum(int m, int n){
int i, sum=0;
for(i=m; i<=n; i++){
sum+=i;
}
return sum;
}
int main(){
int begin = 5, end = 86;
int result = sum(begin, end);
printf("The sum from %d to %d is %d\n", begin, end, result);
return 0;
}
函数不能嵌套定义
不能在一个函数中定义另外一个函数
#include <stdio.h>
void func2(){
printf("C语言小白变怪兽");
}
void func1(){
printf("http://c.biancheng.net");
func2();
}
int main(){
func1();
return 0;
}
func1()、func2()、main() 三个函数是平行的,谁也不能位于谁的内部,要想达到「调用 func1() 时也调用 func2()」的目的,必须将 func2() 定义在 func1() 外面,并在 func1() 内部调用 func2()。
例题
函数的嵌套调用
题目描述:
利用阶乘函数计算组合数
本题要求实现2个自定义函数:求组合数函数和求阶乘函数。
函数接口定义:
int comb(int m,int n);
int fac(int x);
裁判测试程序样例:
样例输入:
6 3
样例输出:
20
int fac(int x)
{
int i,s=1;
for(i=0;i<x;i++)
{
s=s*i;
}
return s;
}
int comb(int m,int n)
{
int c;
c=fac(m)/(fac(n)*fac(m-n));
return c;
}
#include<stdio.h>
int fac(int x);
int comb(int m,int n);
int main(void)
{
int a,b;
while(scanf("%d %d",&a,&b)!=EOF)
printf("%d\n",comb(a,b));
}
错误的代码,明天改正
【示例】计算sum = 1! + 2! + 3! + … + (n-1)! + n!
#include<stdio.h>
int f(int n)
{
int i,m=1;
for(i=1;i<=n;i++)
{
m=m*i;
}
return m;
}
int S(int n)
{
int i,s=0;
for(i=1;i<=n;i++)
{
s=s+f(i);
}
return s;
}
int main()
{
int n;
scanf("%d",&n);
printf("%d",S(n));
}