当前位置: 首页 > news >正文

C语言基础:第10天笔记

内容提要

  • 函数

    • 函数的概述

    • 函数的分类

    • 函数的定义

    • 形参和实参

    • 函数的返回值

函数

函数的概述

  • 函数:实现一定功能的,独立的代码模块,函数是c程序的核心构成模块,可以说c程序就是由众多的函数组成,对于函数的使用,一定是先定义,后使用。

  • 使用函数的优势:

    ①可以通过函数提供给别人使用,也可以使用别人提供的函数,减少代码量。

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

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

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

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

    C语言程序是由一个或多个函数组成

函数的分类

  • 从函数实现的角度:

    • 库函数:C语言标准库实现的并提供使用的函数,比如:scanf() printf() fgets() fputs() strlen()

    • 自定义函数:需要程序员自行实现,开发中大部分函数都是自定义函数

  • 从函数形式的角度:

    • 无参函数:函数调用时,无需传递,可有可无返回值,举例: test1();

    • 有参函数:函数调用时,需要参数传递数据,经常需要配套返回值来使用,举例:printf("%d\n",12);

  • 从函数调用的角度:

    • 主调函数:主动去调用其他函数的函数。(main函数只能作为主调函数)

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

      举例:

       //主调函数
       int main()
       {
           //被调函数
           printf("hello world\n");
       }

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

       int fun_b()
       {
           printf("hello\n");
       }
       ​
       //主调函数
       int fun_a()
       {
           printf("world\n");
           //被调函数
           fun_b();
       }
       ​
       int main()
       {
           //被调函数
           fun_a();
       }

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

函数的定义

定义

语法:

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

函数头:

  • 返回类型:函数返回值的类型,(返回值是被调函数的主调函数)

  • 函数名:函数的名称,遵循标识符命名(不能以数字开头,只能包含字母、数字、下划线,建议:小写+下划线命名,举例:show_all())

  • 形参列表:用于接收主调函数传递的数据,如果有多个参数,使用“,”分隔,且每一个形参都需要指明类型。

小贴士:

形参列表(被调函数):主调函数给被调函数传递数据,主调函数 → 被调函数

返回类型(被调函数):被调函数给主调函数返回数据,被调函数 →主调函数

说明:

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

     double fun_a()   //函数的返回类型是double
     {
         return 12;   //函数返回值是int
     }

    以上代码可以理解为:将int类型的12赋值给一个double类型的匿名变量(int → double),此时属于隐式转换。

     int fun_a()   //函数的返回类型是double
     {
         return 12.5;   //函数返回值是int
     }

    案例:

     ​
  • 在C语言中还可以定义无类型(void类型)的函数,这种函数不返回函数值(没有函数值),只是完成某种功能,举例:

     void test()    //此时这个函数没有返回值,也就是它的返回值是,return;
     {
         printf("hello\n");
     }
     ​
     //下面等价于上面
     void test()
     {
         return;  //一般,这个return是省略不写的
     }
  • 在C语言中,函数的返回类型是可以省略的,如果省略,默认返回int,举例:

     //写法1  main的返回类型是int类型,默认的返回值是0,等价于写法2
     main()
     {
         ...
     }
     ​
     //写法2:main的返回类型是int类型,默认的返回值是0
     int main()
     {
         return 0;  // 0:逻辑真, -1:逻辑假   支持非0表示
     }
  • 函数中返回语句的形式为return(表达式)或者return 表达式

    //写法1
    int main()
    {
        return(0);
    }
    
    //写法2
    int main()
    {
        return 0;
    }
    
  • 如果参数列表中有多个形式参数,则它们之间要用","分隔;即使它们的类型相同,在形式参数中只能逐个进行说明,举例:

    //正确写法
    int avg(int x, int y, int z)
    {
        ...
    }
    
    //错误示例
    int avg(int x,y,z)
    {
        ...
    }
  • 如果形参列表中没有参数,我们可以不写,也可以用void标识,举例:

    //写法1
    int main()
    {
        ...
    }
    
    //写法2
    int main(void)
    {
    	...
    }
案例

案例1

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

  • 代码:

    注意:这里计算结果为0是因为数据太大,超过int存储范围,数据丢失

案例2

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

  • 方案1:自定义一个函数,直接计算两个圆的面积和

  • 方案2:自定义一个函数,只计算一个圆的面积

  • 代码:

    /*************************************************************************
      > File Name:    demo02.c
      > Author:       
      > Description:  
      > Created Time: 2025年03月14日 星期五 14时26分54秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <math.h>
    #define PI 3.1415926
    
    // 对库函数
    extern double pow(double x,double y);
    
    /**
     * 定义一个函数,根据半径计算面积
     * @param r :半径
     * @return 面积
     */
    double cicle_area(double r)
    {
        return PI * pow(r,2.0);//编译的时候,需要在gcc后面加-lm
    }
    
    int main(int argc,char *argv[])
    {
        // 定义两个圆半径和两个园面积
        double r1,r2,area1,area2;
    
        printf("请输入两个圆的半径\n");
        scanf("%lf,%lf",&r1,&r2);
    
        //计算面积
        area1 = cicle_area(r1);
        area2 = cicle_area(r2);
    
        //输出
        printf("一个园台两个面面积之和为:%.2f\n",area1 + area2);
        return 0;
    }
    

形参和实参

形参(形式参数)

函数定义时指定的参数,形参是用来接收数据的,函数定义时,系统不会为形参申请内存,只有当函数调用时,系统才会为形参申请内存,主要用于存储实际参数,并且当函数同时(执行return),系统会自动回收为形参申请的内存资源。

案例

  • 需求:判断奇偶数

  • 代码:

/**
* 方式1
*/
void fun(int n)
{
    if(n % 2 == 0)
    {
        printf("%d是偶数\n",n);
    }
    else
    {
    	printf("%d是奇数\n",n);
    }
}

/**
* 方式2 推荐
*/
void fun(int n)
{
    if(n % 2 == 0)
    {
        printf("%d是偶数\n",n);
        return;//return之后代码不执行
    }
    printf("%d是奇数\n",n);
}

/**
* 方式3 推荐
*/
int fun(int n)
{
    if(n % 2 == 0)
    {
        printf("%d是偶数\n",n);
        return -1;//return之后代码不执行
    }
    printf("%d是奇数\n",n);
    return 0;
}
实参(实际参数)
定义
  • 函数调用时主调函数传递的数据参数(字面量、符号常量、表达式...,是要是确定的值),实参就是传递的数据。

  • 实参和形参必须类型相同,如果不同时,按赋值规定进行类型转换,比如隐式转换。

  • 在C语言中,实参传递必须遵循单向传递(通过实参给形参赋值),实参只是将自身的值传递给了形参,而不是实参本身,形参的值的改变不会影响实参。

    int fun(int n)
    {
        printf("%d\n",n);
    }
    
    int main()
    {
        int a = 10; // a = 10
        fun(a); // a是实参,数据10,实参是变量
        a = 20; //a = 20
        
        fun(12);//字面量12就是实参
        
        fun(a + 12); //数据量是22 实参是表达式
    }
  • 实参与形参在内存中占据不同的内存空间。

    double fabs(double a)
    {
        return a < 0 ? -a : a;
    }
    
    int main()
    {
        int x = 12,y = -12;
        int x1 = (int)fabs(x);  //12
        int y1 = (int)fabs(y);  //12
    }
案例

案例1:

  • 需求:输入4个整数,要求用一个函数求出最大数

  • 代码:

    /*************************************************************************
      > File Name:    demo03.c
      > Author:       
      > Description:  
      > Created Time: 2025年03月14日 星期五 15时25分32秒
     ************************************************************************/
    
    #include <stdio.h>
    
    /**
     * 定义一个函数,求两个数最大数
     * @param x,y
     * @return 最大数
     */
    int max(int x, int y)
    {
        return x > y ? x : y;
    }
    
    int main(int argc,char *argv[])
    {
        int a,b,c,d,max1,max2,max3;
        printf("输入4个数\n");
        scanf("%d%d%d%d",&a,&b,&c,&d);
    
        //求ab
        max1 = max(a,b);
        //求abc
        max2 = max(max1,c);
        //求abcd
        max3 = max(max2,d);
        
        printf("%d,%d,%d,%d中最大%d\n",a,b,c,d,max3);
        return 0;
    }
    

函数的返回值

  • 若不需要返回值,函数可以没有return语句。

    //如果返回类型是void,return可以省略
    void fun1
    {
        
    }
    
    //return 可以省略,默认 0
    int fun2()
    {
        
    }
    //return 可以省略,默认 0
    fun3()
    {
        
    }
  • 一个函数中可以有多个return语句,但任一时刻只有一个return语句被执行

    int eq(int num)
    {
        if(num % 2 == 0)
        {
            printf("%d\n",num);
            return 0;
        }
        printf("%d\n",num);
        return 0;
    }
  • 返回值类型一般情况下要和函数中return语句返回的数据类型一样,如果不一致,以函数定义时指定的返回值类型为标准。

案例

需求:输入两个整数,要求用一个函数求最大数

  • 案例1:

    /*************************************************************************
      > File Name:    demo04.c
      > Author:       
      > Description:  
      > Created Time: 2025年03月14日 星期五 16时01分54秒
     ************************************************************************/
    
    #include <stdio.h>
    
    /**
     * 定一个函数
     * @param x,y
     * @return max
     */
    int get_max(int x, int y)
    {
        if (x > y) return x;
    
        return y;
    }
    
    int main(int argc,char *argv[])
    {
        int a,b,max;
    
        printf("请输入\n");
        scanf("%d%d",&a,&b);
    
        max = get_max(a,b);
        printf("%d,%d中最大数是%d\n",a,b,max);
    
        return 0;
    }
    

  • 案例2

    /*************************************************************************
      > File Name:    demo05.c
      > Author:       
      > Description:  
      > Created Time: 2025年03月14日 星期五 16时01分54秒
     ************************************************************************/
    
    #include <stdio.h>
    
    /**
     * 定一个函数
     * @param x,y
     * @return max
     */
    double get_max(int x, int y)
    {
        if (x > y) return x;
    
        return y;
    }
    
    int main(int argc,char *argv[])
    {
        int a,b,max;
    
        printf("请输入\n");
        scanf("%d%d",&a,&b);
    
        max = (int)get_max(a,b);
        printf("%d,%d中最大数是%d\n",a,b,max);
    
        return 0;
    }
    

  • 案例3:

    /*************************************************************************
      > File Name:    demo06.c
      > Author:       
      > Description:  
      > Created Time: 2025年03月14日 星期五 16时01分54秒
     ************************************************************************/
    
    #include <stdio.h>
    
    /**
     * 定一个函数
     * @param x,y
     * @return max
     */
    double get_max(int x, int y)
    {
        double z;
    
        z = x > y ? x : y;
    
        return (int)z;
    }
    
    int main(int argc,char *argv[])
    {
        int a,b,max;
    
        printf("请输入\n");
        scanf("%d%d",&a,&b);
    
        max = get_max(a,b);
        printf("%d,%d中最大数是%d\n",a,b,max);
    
        return 0;
    }
    

    运行结果:

相关文章:

  • LeetCode 2711.对角线上不同值的数量差:O(mn)时间O(1)空间 - 位运算优化 - C++/Go双百版本 - 三种方法(一步步优化)
  • Axios核心原理
  • Python与文件——保存文件
  • 微软Copilot与向量数据库:智能化办公的技术架构与实现路径
  • 李宏毅机器学习笔记(1)—机器学习基本概念+深度学习基本概念
  • 软件工程面试题(六)
  • 解决linux centos ubuntu等无法启动谷歌chrome浏览器问题
  • HarmonyOS NEXT——【鸿蒙相册图片以及文件上传Picker封装】
  • Stereolabs ZED Box Mini:NVIDIA Orin™驱动,双GMSL2输入,智能机器视觉AI新选择”
  • android studio调试aosp手机userdebug版本无法查看局部变量和参数问题如何解决?
  • 【从零实现Json-Rpc框架】- 项目实现 -抽象消息类实现篇
  • Uni-app入门到精通:subPackages节点为小程序的分包加载配置
  • 实现金蝶与钉钉无缝对接以高效管理银行账号信息
  • 人脸识别新规落地,“多模态认证”将成常态
  • 每日一题之日期统计
  • 为什么大模型在 OCR 任务上表现不佳?
  • 包络解调在故障诊断中的应用-广义检波解调案例
  • 架构师面试(二十二):TCP 协议
  • PDF处理控件Spire.PDF系列教程:使用 JavaScript 在 React 中将 PDF 转换为 HTML
  • java八股文之企业场景
  • 上交所五方面落实募资新规:强化关键少数责任和股东权利保障
  • 晋级四强!WTA1000罗马站:郑钦文2比0萨巴伦卡
  • 从能源装备向应急装备蓝海拓展,川润股份发布智能综合防灾应急仓
  • 6连败后再战萨巴伦卡,郑钦文期待打出更稳定发挥
  • 新剧|《藏海传》定档,《折腰》《人生若如初见》今日开播
  • 长沙查处疑似非法代孕:有人企图跳窗,有女子被麻醉躺手术台