LInux基础35-C语言篇之函数Ⅰ【入门级】

函数

函数的概述

  • 函数:实现一定功能的,独立的代码模块。我们的函数一定是先定义,后使用

  • 使用函数的优势:

    ①我们可以通过函数提供功能给别人使用。当然我们也可以使用别人提供的函数,减少代码量。

    ②借助函数可以减少重复性代码。

    ③实现结构化(模块化)程序设计思想。

关于结构化设计思想:将大型的任务功能划分为相互独立的小型任务任务模块来设计。

  • 函数是C语言程序的基本组成单元:

    C语言程序是由一个(必然是main函数)或多个函数组成。

函数的分类

  • 从函数实现的角度:
    • 库函数:C语言标准库实现的并提供使用的函数,比如常见的有scanf(),printf(),strlen()…
    • 自定义函数:需要程序员自行实现,开发中大部分函数都是自定义的。
  • 从函数形式的角度:
    • 无参函数:函数调用时,无需传递,可有可无返回值,举例:test1();
    • 有参函数:函数调用时,需要参数传递数据,需要经常配套返回值来使用,举例:printf(“%d”,12);

相关概念:

主调函数与被调函数:

  • 主调函数:主动取调用其他函数的函数。

  • 被调函数:被其他函数调用的函数。

    举例:

    //这里的main就是主调函数
    int main()
    {
        //这里的printf就是被调函数
        printf("Hello world");
    }
    

    很多时候,尤其是对于自定义函数来说,一个函数有可能既是主调函数,又是被调函数。

    int fun_b()
    {
        printf("函数B\n");
    }
    
    int fun_a()
    {
        printf("函数A\n");
        fun_b();
    }
    
    int main()
    {
        fun_a();
    }
    

    以上案例中,fun_a()对于fun_b()来说是主调函数,对于main函数来说是被调函数。

函数的定义

定义

语法:

[返回类型]函数名([形参列表])   ---函数头|函数首部
{
    函数体语句;			    ---函数体,整个()包裹的内容包括返回值都属于函数体
}

函数头:

  • 返回类型:函数返回值的类型
  • 函数名:函数的名称,遵循标识符命名(不能以数字开头,只能包含字母、数字、下划线,建议:小写+下划线命名法,举例:set_count())
  • 形参列表:用于接收主调函数传递的数据,如果有多个参数,使用,分隔,且每一个形参都需要指明类型。

说明:

  • 函数的返回类型,就是返回值类型,两个类型可以不同,但是必须能够进行转换。举例:

    double fun_a()//返回类型:double
    {
        return 12;//返回值类型:int
    }
    //相当于将int类型的12赋值给了double类型的匿名变量,此时转换属于自动类型转换
    double res = fun_a();
    
  • 在C语言中还可以定义无类型(即void类型)的函数,这种函数不返回函数值(没有返回值),只是完成某种功能,举例:

    void test()
    {
        printf("hello\n");
    }
    
  • C语言中,函数的返回值类型标识符是可以省略的,默认返回int,举例:

    // 写法1:main的返回类型是int类型,默认的返回值类型是0
    main()
    {
        
    }
    // 写法2:等价于写法1,返回值类型是int类型,返回值是0
    int main()
    {
        return 0;// 如果返回类型是int,这里return 0 不写,也是返回0
    }
    
  • 函数中返回语句的形式为return(表达式)或者return表达式,其作用是将表达式的值作为函数值返回给主调函数,其中表达式的类型应该与函数类型一致(也就是说函数类型和返回值类型之间是支持隐式转换或者显示转换)

    //写法一
    int main()
    {
        return(0);
    }
    
    //写法二
    int main()
    {
        return 0;//推荐
    }
    
  • 如果说参数列表中有多个形式参数,则它们之间要用,分隔,举例:

    int avg(int x,int y,int z)
    {
        ...
    }
    
  • 如果形参列表中有多个形参,即使它们类型相同,在形参列表中只能逐个进行说明。

    int avg(int x,y,z)//错误写法
        
    int avg(int x,int y,int z)//正确
    
  • 如果形参列表中没有参数,可以不写,或者用void来表示,举例:

    int main()
    {
        ...
    }
    
    int main(void)
    {
        ...
    }
    
  • 一个完整的C语言程序中的所有函数可以放在同一个文件中,也可以放在多个文件中

    • 同一个文件

      demo.c

    #include 
    void show()
    {
        printf("hello\n");
    }
    int main()
    {
        show();
    }
    
    • 不同文件中:

    a.h

    void show();//头文件中只放函数的声明,也就是说只有函数头
    

    a.c

    #include "a.h"//引入库函数,使用<>,引入自定义函数,用""
    
    void show()
    {
        printf("hello\n");
    }
    

    b.c

    #include "a.h"
     int main()
     {
        show();
     }
    
案例

案例1:

  • 需求:计算1~n之间的自然数

  • 代码:

     #include 
     /**
     * 求1~n的阶乘值
     * 建议:我们设计的函数,尽量让被调函数改动较小,由主调函数去影响
     */
     long fun_1(int n)
     {
       int i; // 循环变量
       long s = 1; // 阶乘值
       for (i = 1; i <= n; i++)
       {
          s *= i;
       }
       return s;// 返回结果给主调函数
    }
     int main(int argc,char *argv[])
     {
        printf("1~5的阶乘结果是:%ld\n",fun_1(5));
        printf("1~10的阶乘结果是:%ld\n",fun_1(10));
         return 0;
     }
    

    案例2:

    • 需求:计算一个圆台两个面的面积之和

    • 代码:

       #include 
       // 定义一个符号常量 PI
       #define PI 3.1415926
       /**
       * 定义一个函数,根据半径计算面积
       * @param r:半径
       * @return 面积
       */ 
      double circle_area(double r)
       {
          
          return PI * r * r;
       }
       int main(int argc,char *argv[])
       {
          // 定义两个半径,两个面积
          double r1,r2,area1,area2;
          printf("请输入两个圆的半径:\n");
          scanf("%lf,%lf",&r1,&r2);// double r = r1;
          // 调用函数计算圆的面积
          area1 = circle_area(r1);
          area2 = circle_area(r2);
          printf("一个圆台两个面的面积之和是%.2lf\n",area1 + area2);
           return 0;
       }
      

你可能感兴趣的:(linux,c语言,网络)