Linux学习之路(番外--函数)

 函数概述:

函数(Function)是一段可以重复使用的代码,这是从整体上对函数的认识。

       C语言本身带了很多库函数,并分门别类地放在了不同的头文件中,使用时只要引入对应的头文件即可。

       除了C语言自带的函数,我们也可以编写自己的函数,称为自定义函数(User-Defined Function)。自定义函数和库函数没有本质的区别,表现形式和使用方法一样,只是开发者不同而已。

 

函数参数

       函数的一个明显特征就是使用时带括号( ),必要的话,括号中还要包含数据或变量,称为参数(Parameter)。     

       参数是函数需要处理的数据,例如:

strlen(str1)用来计算字符串的长度,str1就是参数。

puts("hello world")用来输出字符串,"hello world"就是参数。

 

返回值

       既然函数可以处理数据,那就有必要将处理结果告诉我们,所以很多函数都有返回值(Return Value)。所谓返回值,就是函数的执行结果。例如:

char str1[] = "C Language";

int len = strlen(str1);

strlen() 的处理结果是字符串 str1 的长度,是一个整数,我们通过 len 变量来接收。

函数返回值有固定的数据类型(int、char、float等),用来接收返回值的变量类型要一致。

 

自定义函数:

函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。

 

无参函数的定义

       如果函数不接收用户传递的数据,那么定义时可以不带参数。如下所示:

返回值类型  函数名()

{

    函数体

}

  注意:

  • 返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。
  • 函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
  • 函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。
  • 在函数体中使用return语句返回数据。

 例如,定义一个函数,计算1加到100的结果:

int sum()

{

        int i, sum=0;

        for(i=1; i<=100; i++)

        {

            sum+=i;

        }

        return sum;

}

       计算结果保存在变量sum中,通过return语句返回。sum为int型,所以返回值类型也必须为int,要一一对应。

       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;

}

运行结果:

The sum is 5050

       函数不能嵌套定义,main 也是一个函数定义,要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 只能在 main 前面。

   注意:

       main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。

 

无返回值函数

       有的函数不需要有返回值,或者返回值类型不确定(很少见),那么用void表示,例如:

void hello()

{

printf ("Hello,world \n");

//没有返回值就不需要 return 语句

}

       void是C语言中的一个关键字,表示空类型或无类型,绝大部分情况下也就意味着没有 return 语句。

 

有参函数的定义

       如果函数需要接收用户传递的数据,那么定义时就要带参数。如下所示:

返回值类型  函数名(参数列表)

{

    函数体

}

       用户数据通过“参数列表”传递给函数,供函数处理。例如,定义一个函数求两个数中的最大值:

int max(int a, int b)

{

        if (a>b)

        {

            return a;

        }

        else

        {

            return b;

        }

}

       参数(Parameter)本质上也是变量,定义时要指明参数类型和参数名称。参数列表中可以定义一个或多个参数,多个参数之间用逗号,分隔。参数列表中给出的参数可以在函数体中使用。

调用 max() 函数时可以直接传递整数:

int n = max(10, 20);

也可以传递变量:

int a = 10, b = 20;

int n = max(a, b);

也可以整数和变量一起传递:

int a = 10;

int n = max(a, 20);

变量 n 得到的值都是20

 

形参与实参

       函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。注意:实参和形参的类型、数目必须一致。

将上面的代码补充完整:

#include <stdio.h>

int max(int a, int b)

{

        if (a>b)

        {

            return a;

        }

        else

        {

            return b;

        }

}

int main()

{

        int num1, num2, maxVal;

        printf("Input two numbers: ");

        scanf("%d %d", &num1, &num2);

        maxVal = max(num1, num2);

        printf("The max number: %d\n", maxVal);

 

        return 0;

}

运行结果:

Input two numbers: 100 200

The max number: 200

       定义max时,变量a、b的值都是未知的;调用max时,分别将num1、num2的值传递给a、b,类似于:

a=num1;

b=num2;

       return 语句可以有多个,可以在函数体的任意位置。在max中,根据 if 的判断结果来执行不同的 return 语句。

      函数一旦遇到 return 语句就返回(停止执行),后面的所有语句都不会被执行到,例如:

int max(int a, int b)

{

        int n = (a>b) ? a : b;

        return n;

        printf("Function is performed\n");

}

      第5行代码是多余的,永远没有执行的机会。

 

形参和实参有以下几个特点:

  • 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。
  • 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

    函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。

     

    无参函数的定义

           如果函数不接收用户传递的数据,那么定义时可以不带参数。如下所示:

    返回值类型  函数名()

    {

        函数体

    }

      注意:

  • 返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。
  • 函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
  • 函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。
  • 在函数体中使用return语句返回数据。
  •  例如,定义一个函数,计算1加到100的结果:

    int sum()

    {

            int i, sum=0;

            for(i=1; i<=100; i++)

            {

                sum+=i;

            }

            return sum;

    }

           计算结果保存在变量sum中,通过return语句返回。sum为int型,所以返回值类型也必须为int,要一一对应。

           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;

    }

    运行结果:

    The sum is 5050

           函数不能嵌套定义,main 也是一个函数定义,要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 只能在 main 前面。

       注意:

           main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。

     

    无返回值函数

           有的函数不需要有返回值,或者返回值类型不确定(很少见),那么用void表示,例如:

    void hello()

    {

    printf ("Hello,world \n");

    //没有返回值就不需要 return 语句

    }

           void是C语言中的一个关键字,表示空类型或无类型,绝大部分情况下也就意味着没有 return 语句。

     

    有参函数的定义

           如果函数需要接收用户传递的数据,那么定义时就要带参数。如下所示:

    返回值类型  函数名(参数列表)

    {

        函数体

    }

           用户数据通过“参数列表”传递给函数,供函数处理。例如,定义一个函数求两个数中的最大值:

    int max(int a, int b)

    {

            if (a>b)

            {

                return a;

            }

            else

            {

                return b;

            }

    }

           参数(Parameter)本质上也是变量,定义时要指明参数类型和参数名称。参数列表中可以定义一个或多个参数,多个参数之间用逗号,分隔。参数列表中给出的参数可以在函数体中使用。

    调用 max() 函数时可以直接传递整数:

    int n = max(10, 20);

    也可以传递变量:

    int a = 10, b = 20;

    int n = max(a, b);

    也可以整数和变量一起传递:

    int a = 10;

    int n = max(a, 20);

    变量 n 得到的值都是20

     

    形参与实参

           函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。注意:实参和形参的类型、数目必须一致。

    将上面的代码补充完整:

    #include <stdio.h>

    int max(int a, int b)

    {

            if (a>b)

            {

                return a;

            }

            else

            {

                return b;

            }

    }

    int main()

    {

            int num1, num2, maxVal;

            printf("Input two numbers: ");

            scanf("%d %d", &num1, &num2);

            maxVal = max(num1, num2);

            printf("The max number: %d\n", maxVal);

     

            return 0;

    }

    运行结果:

    Input two numbers: 100 200

    The max number: 200

           定义max时,变量a、b的值都是未知的;调用max时,分别将num1、num2的值传递给a、b,类似于:

    a=num1;

    b=num2;

           return 语句可以有多个,可以在函数体的任意位置。在max中,根据 if 的判断结果来执行不同的 return 语句。

          函数一旦遇到 return 语句就返回(停止执行),后面的所有语句都不会被执行到,例如:

    int max(int a, int b)

    {

            int n = (a>b) ? a : b;

            return n;

            printf("Function is performed\n");

    }

          第5行代码是多余的,永远没有执行的机会。

     

    形参和实参有以下几个特点:

  • 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。
  • 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

    函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。

     

    无参函数的定义

           如果函数不接收用户传递的数据,那么定义时可以不带参数。如下所示:

    返回值类型  函数名()

    {

        函数体

    }

      注意:

  • 返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。
  • 函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
  • 函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。
  • 在函数体中使用return语句返回数据。
  •  例如,定义一个函数,计算1加到100的结果:

    int sum()

    {

            int i, sum=0;

            for(i=1; i<=100; i++)

            {

                sum+=i;

            }

            return sum;

    }

           计算结果保存在变量sum中,通过return语句返回。sum为int型,所以返回值类型也必须为int,要一一对应。

           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;

    }

    运行结果:

    The sum is 5050

           函数不能嵌套定义,main 也是一个函数定义,要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 只能在 main 前面。

       注意:

           main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。

     

    无返回值函数

           有的函数不需要有返回值,或者返回值类型不确定(很少见),那么用void表示,例如:

    void hello()

    {

    printf ("Hello,world \n");

    //没有返回值就不需要 return 语句

    }

           void是C语言中的一个关键字,表示空类型或无类型,绝大部分情况下也就意味着没有 return 语句。

     

    有参函数的定义

           如果函数需要接收用户传递的数据,那么定义时就要带参数。如下所示:

    返回值类型  函数名(参数列表)

    {

        函数体

    }

           用户数据通过“参数列表”传递给函数,供函数处理。例如,定义一个函数求两个数中的最大值:

    int max(int a, int b)

    {

            if (a>b)

            {

                return a;

            }

            else

            {

                return b;

            }

    }

           参数(Parameter)本质上也是变量,定义时要指明参数类型和参数名称。参数列表中可以定义一个或多个参数,多个参数之间用逗号,分隔。参数列表中给出的参数可以在函数体中使用。

    调用 max() 函数时可以直接传递整数:

    int n = max(10, 20);

    也可以传递变量:

    int a = 10, b = 20;

    int n = max(a, b);

    也可以整数和变量一起传递:

    int a = 10;

    int n = max(a, 20);

    变量 n 得到的值都是20

     

    形参与实参

           函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。注意:实参和形参的类型、数目必须一致。

    将上面的代码补充完整:

    #include <stdio.h>

    int max(int a, int b)

    {

            if (a>b)

            {

                return a;

            }

            else

            {

                return b;

            }

    }

    int main()

    {

            int num1, num2, maxVal;

            printf("Input two numbers: ");

            scanf("%d %d", &num1, &num2);

            maxVal = max(num1, num2);

            printf("The max number: %d\n", maxVal);

     

            return 0;

    }

    运行结果:

    Input two numbers: 100 200

    The max number: 200

           定义max时,变量a、b的值都是未知的;调用max时,分别将num1、num2的值传递给a、b,类似于:

    a=num1;

    b=num2;

           return 语句可以有多个,可以在函数体的任意位置。在max中,根据 if 的判断结果来执行不同的 return 语句。

          函数一旦遇到 return 语句就返回(停止执行),后面的所有语句都不会被执行到,例如:

    int max(int a, int b)

    {

            int n = (a>b) ? a : b;

            return n;

            printf("Function is performed\n");

    }

          第5行代码是多余的,永远没有执行的机会。

     

    形参和实参有以下几个特点:

  • 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。
  • 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

 

 

函数声明和函数原型:

C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错。但在实际开发中,经常会在函数定义之前使用它们,这个时候就需要提前声明。

       所谓声明(Declaration),就是告诉编译器我要使用这个函数,你现在没有找到它的定义不要紧,请不要报错,稍后我会把定义补上。

       函数声明的格式非常简单,相当于去掉函数定义中的函数体再加上分号;,如下所示:

返回值类型  函数名( 类型 形参, 类型 形参… );

       也可以不写形参,只写数据类型:

返回值类型  函数名( 类型, 类型…);

       函数声明给出了函数名、返回值类型、参数列表(参数类型)等与该函数有关的信息,称为函数原型(Function Prototype)。

       函数原型的作用是告诉编译器与该函数有关的信息,让编译器知道函数的存在,以及存在的形式,即使函数暂时没有定义,编译器也知道如何使用它。

       有了函数声明,函数定义就可以出现在任何地方了,甚至是其他文件、静态链接库、动态链接库等。

请看下面的代码:

#include <stdio.h>

 

// 函数声明

long factorial(int n);    //也可以写作 long factorial(int);

long sum(long n);       //也可以写作 long sum(long);

 

int main()

{

        printf("1!+2!+...+9!+10! = %ld\n", sum(10));

        return 0;

}

 

//求阶乘

long factorial(int n)

{

        int i;

        long result=1;

        for(i=1; i<=n; i++)

        {

            result *= i;

        }

        return result;

}

 

// 求累加的和

long sum(long n)

{

        int i;

        long result = 0;

        for(i=1; i<=n; i++)

        {

            //嵌套调用

            result += factorial(i);

        }

        return result;

}

运行结果:

1!+2!+...+9!+10! = 4037913

       我们知道,使用 printf()、puts()、scanf()、getchar() 等函数要引入 stdio.h 这个头文件,很多初学者认为 stdio.h 中包含了函数定义(也就是函数体),只要有了头文件程序就能运行。其实不然,头文件中包含的都是函数声明,而不是函数定义,函数定义都在系统库中,只有头文件没有系统库在链接时就会报错,程序根本不能运行。

       最后再补充一点,函数原型给出了使用该函数的所有细节,当我们不知道如何使用某个函数时,需要查找的是它的原型,而不是它的定义,我们往往不关心它的实现。

 

递归函数:

  一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数。执行递归函数将反复调用其自身,每调用一次就进入新的一层。

 

【示例】用递归计算 n!。阶乘 n! 的计算公式如下:

根据公式编程:

long factorial(int n)

{

        long result;

        if(n==0 || n==1)

        {

            result = 1;

        }

        else

        {

            result = factorial(n-1) * n;  // 递归调用

        }

        return result;

}

       这是一个典型的递归函数。调用factorial后即进入函数体,只有当 n==0 或 n==1 时函数才会执行结束,否则就一直调用它自身。

      由于每次调用的实参为 n-1,即把 n-1 的值赋给形参 n,所以每次递归实参的值都减 1,直到最后 n-1 的值为 1 时再作递归调用,形参 n 的值也为1,递归就终止了,会逐层退出。

      例如求 5!,即调用factorial(5)。当进入factorial函数体后,由于 n=5,不等于0或1,所以执行result = factorial(n-1) * n;,即result = factorial(5-1) * 5;,接下来也就是调用factorial(4)。这是第一次递归。

      进行四次递归调用后,实参的值为 1,也就是调用factorial(1)。这时递归就结束了,开始逐层返回。factorial(1) 的值为 1,factorial(2) 的值为 1*2=2,factorial(3) 的值为 2*3=6,factorial(4) 的值为 6*4=24,最后返回值 factorial(5) 为 24*5=120。

 

注意

  • 为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。
  • 递归调用不但难于理解,而且开销很大,如非必要,不推荐使用递归。很多递归调用可以用迭代(循环)来代替。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值