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

C语言基础(11)【函数1】

内容提要

  • 函数

文章目录

    • 内容提要
    • 函数
      • 函数的描述
      • 函数的分类
      • 相关概念
      • 函数的定义:
        • 定义:
        • 案例:
      • 形参和实参
        • 形参(形式参数)
        • 实参(实际参数)
        • 案例:
      • 函数的返回值
        • 案例:

函数

函数的描述

  • 函数:实现一定功能的,独立的代码模块。我们的函数一定是先定义,后使用
  • 使用函数的优势:
    • 我们可以通过函数提供功能给别人使用。当然我们也可以使用别人提供的函数,减少代码 量。
    • 借助函数可以减少重复性的代码。
    • 实现结构化(模块化)程序设计思想。
    • 关于结构化设计思想:将大型的任务功能划分为相互独立的小型的任务模块来设计。
  • 函数是C语言程序的基本组成单元:
    • C语言程序是由一个(必然是main函数)或多个函数组成。

函数的分类

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

相关概念

  • 主调函数与被调函数:

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

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

    • 举例:

      // 这里的main函数就是 主调函数
      int main()
      {// 这里的printf函数就是 被调函数printf("hello world!\n");
      }
    • 很多时候,尤其是对于自定义函数来说,一个函数有可能既是主调函数,又是被调函数。

      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类型的匿名变量,此时转换属于自动类型转换
    dobule 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, int y, int z)
    {...
    }
  • 如果形参列表中没有参数,我们可以不写,也可以用void来表示,举例:

    // 写法一
    int main(){..}  // 推荐
    // 写法二
    int main(void){..}
    
  • 一个完整C程序中的所有函数可以放在一个文件中,也可以放在多个文件中,举例:

    • 同一个文件:

      #include <stdio.h>
      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之间自然数的阶乘
  • 代码:
/*************************************************************************> File Name:    demo01.c> Author:       袁厚锋> Description:函数案例:求:1~n之间的自然数的阶值> Created Time: 2025年05月14日 星期三 10时29分03秒************************************************************************/#include <stdio.h>
/**求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;
}

案例:

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

  • 代码:

    /*************************************************************************> File Name:    demo02.c> Author:       袁厚锋> Description:函数案例:计算一个圆台的两个面积之和  > Created Time: 2025年05月14日 星期三 10时52分55秒************************************************************************/
    #include <stdio.h>
    #define PI 3.1415926
    /**定义一个函数根据半径计算面积*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);//调用函数计算圆形的面积area1 = circle_area(r1);area2 = circle_area(r2);printf("一个圆台的两个圆形的面积之和是:%.2lf\n",area1+area2);return 0;
    }
    

    形参和实参

    形参(形式参数)

函数定义时,指定的参数,形参是用来接收数据的,函数定义时,系统不会为形参申请内存,只有当函数被调用时,系统才会为形参开辟内存,主要用于存储实际的数据,并且当函数返回时,系统会自动 回收为形参申请的内存资源。(本质上所有函数都有一个return,只不过当我们的函数返回类型是 void类型的时候,return是隐式)

//关于默认的return
void fun1()
{//此时return是不建议写出来的,这时候的return;隐式的
}
fun2
{//默认为return 0;这里建议写出来
}
//关于函数的跳出处理
void fun3(int n)
{if(n % 2 == 0){printf("%d是一个偶数!\n",n);return;}printf("%d是一个奇数!\n",n);
}int fun4(int n)
{if(n % 2 == 0){printf("%d是一个偶数!\n",n);return -1;}printf("%d是一个奇数!\n",n);return 0;
}
实参(实际参数)
  • 函数调用时主调函数传递的数据参量(常量、符号常量、变量、表达式,只要有确定的值),实参就是传递的数据。
  • 实参和形参必须类型相同,如果类型不同按照赋值的规定进行强制转换。
  • 在C语言中,参数的传递必须遵循单项值传递,实参只是将自己的值传给形参,而不是实参本身。形参的值的改变不会影响但实参。
int fun(int n)
{printf("%d\n",n);//10;
}
int main()
{int a = 10;fun(a);	//这里的意思是将a的值拷贝了一份副本传递给形参na = 20;return 0 ;
}
  • 实参与形参在内存中占据不停的存储空间(建议实参和形参的名字是一致的)
double fun(double a,double b)
{return a + b;
}
int main()
{int x = 12,int y = 13;int c = (int)fun(x ,y)
}
案例:

案例1:

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

  • 代码:

    #include <stdio.h>
    /*
    定义一个函数求两个中的最大值
    x,y外部传入的整数
    最大值
    */
    int max(int x,inty)
    {return x >y ? x :y;
    }
    int main()
    {int a,b,c;printf("请输入第1个数!!\n");if(scanf("%d",&a)!= 1);{//清楚缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}printf("请输入第2个数:\n");if(scanf("%d",&b)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}//求最大值://用变量接收最大值c = max(a,b);printf("%,%d中最大的值是:%d\n",a,b,c);return 0;
    }
    

函数的返回值

  • 若不需要返回值,函数可以没有return语句
// 这种写法,没有返回值 return;
void fun1()
{}
// 这种写法,有返回值,返回 return 0
int fun2()
{}
// 这种写法,有返回值,返回 return 0
fun3()  // 返回类型标识符如果不写,默认是int
{}
  • 一个函数中可以有多个return语句,但任一时刻只有一个return语句被执行

    int eq(int num)
    {if(num % 2 == 0){printf("%d是偶数\n",num);return 0;}printf("%d是奇数\n",num);return 0;
    }
    
  • 被调函数返回给主调函数结果数据(可以是==变量、常量、表达式…,==只要是确定值就可以了。

    int fun1(int a,int b)
    {return a + b;	//返回表达式,表达式的计算结果是int
    }
    int fun2(int num)
    {if(num %2 == 0)return 0;	//如果num 是一个偶数,那么就返回一个0;return -1;//如果num不是一个偶数,那么就返回一个 1-1;
    }
    
  • 返回值类型一般情况下要和函数中return语句返回的数据类型一致,如果不一致,以函数定时 指定的返回类型为标准。也就是返回值类型和实际返回值的类型可以存在转换转换关系,一般 是将 返回值类型返回类型

案例:
  • 需求:输入两个整数,要求用一个函数求出最大值

  • 案例1

#include <stdio.h>
/*** 定义一个函数,求两个数中的最大数* @param x,y:外部传入的整数* @return 最大值*/
int max(int x,int y)
{if (x > y)return x;return y;
}
int main(int argc,char *argv[])
{int a,b,c;printf("请输入第1个数:\n");if(scanf("%d",&a)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}printf("请输入第2个数:\n");if(scanf("%d",&b)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}// 求最大值c = max(a,b);printf("%d,%d中的最大值是%d\n",a,b,c);return 0;
}
  • 案例2:
#include <stdio.h>
/*** 定义一个函数,求两个数中的最大数* @param x,y:外部传入的整数* @return 最大值*/
double max(int x,int y){if (x > y)return x;return y;
}
int main(int argc,char *argv[])
{int a,b,c;printf("请输入第1个数:\n");if(scanf("%d",&a)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}printf("请输入第2个数:\n");if(scanf("%d",&b)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}// 求最大值c = (int)max(a,b);printf("%d,%d中的最大值是%d\n",a,b,c);return 0;
}
  • 案例3:
#include <stdio.h>
int max(int x,int y)
{double z;z = x > y ? x : y;return (int)z;
}
int main(int argc,char *argv[])
{int a,b,c;printf("请输入第1个数:\n");if(scanf("%d",&a)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}printf("请输入第2个数:\n");if(scanf("%d",&b)!=1){// 清除缓冲while(getchar()!='\n');printf("输入有误!\n");return -1;}// 求最大值c = max(a,b);printf("%d,%d中的最大值是%d\n",a,b,c);return 0;
}

相关文章:

C语言基础(11)【函数1】

内容提要 函数 文章目录 内容提要函数函数的描述函数的分类相关概念函数的定义&#xff1a;定义&#xff1a;案例&#xff1a; 形参和实参形参&#xff08;形式参数&#xff09;实参&#xff08;实际参数&#xff09;案例&#xff1a; 函数的返回值案例&#xff1a; 函数 函数…...

R语言基础| 下载、安装

在此前的单细胞教程中&#xff0c;许多小伙伴都曾因为R语言基础不足而十分苦恼。R语言是一种开源的编程语言和软件环境&#xff0c;专门用于统计分析、图形表示和数据挖掘。它最初由Ross Ihaka和Robert Gentleman在1993年创建&#xff0c;旨在为统计学家和数据分析师提供一个广…...

【hive sql】窗口函数

参考 包括窗口函数在内的执行顺序 from & join --确定数据源 where --行级过滤 group by --分组 having --组级过滤 窗口函数 --计算窗口函数结果 select --选择列 distinct --去重 order by --最终排序&#xff08;可对窗口函数结果进行排序&#xff09; limit/offset -…...

Ubuntu24.04 交叉编译 aarch64 ffmpeg

ffmpeg 官网: https://ffmpeg.org文档: https://ffmpeg.org/documentation.html 编译参数说明: https://trac.ffmpeg.org/wiki/CompilationGuide/Generic在Linux下编译: https://trac.ffmpeg.org/wiki/CompilationGuide 下载页: https://ffmpeg.org/download.html 安装依赖 …...

《AI角色扮演反诈技术解析:原理、架构与核心挑战》

AI角色扮演反诈技术解析&#xff1a;原理、架构与核心挑战 研究目标 技术栈梳理&#xff1a; 系统总结AI角色扮演在执法场景中的实现路径&#xff0c;涵盖大型语言模型&#xff08;LLM&#xff09;、提示词工程&#xff08;Prompt Engineering&#xff09;、多模态交互链路等…...

微软的新系统Windows12未来有哪些新特性

在今年即将到来的重大设计升级中,苹果计划对其全线操作系统统一按年份命名,作为另一巨头微软的win12还远吗?win11和win10是微软现在正在用的主流版本,win11系统发布于2021年6月24日,win10系统发布于2015年7月29日。预计win12尝鲜版可能在2025年下半年或明年。 尽管win12还…...

树莓派超全系列教程文档--(54)如何使用rsync在计算机之间同步文件夹

如何使用rsync在计算机之间同步文件夹 使用 rsync 在计算机之间同步文件夹 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rsync 在计算机之间同步文件夹 您可以使用 rsync 在计算机之间同步文件夹。例如&#xff0c;您可以使用 rsync 将R…...

华为ICT和AI智能应用

在华为的业务布局中&#xff0c;AI智能创新则贯穿于华为多个业务领域&#xff0c;二者紧密相关&#xff0c;共同推动华为及相关行业的发展。以下是具体介绍&#xff1a; Techco转型 - 背景&#xff1a;随着5G - A、云、人工智能等技术的发展&#xff0c;运营商从传统连接服…...

ROS2与Unitree机器人集成指南

Tested systems and ROS2 distro systemsROS2 distroUbuntu 20.04foxyUbuntu 22.04humblesrc目录上级才可以colcon build git clone https://github.com/unitreerobotics/unitree_ros2 Install Unitree ROS2 package 1. Dependencies sudo apt install ros-humble-rmw-cyclon…...

在虚拟宇宙中低语——进程间通信,Linux命名管道的前世今生

文章目录 &#x1f30c; 序章&#x1f320; 一、命名管道的宿命与哲学1.1、创建及简单使用1.2、命名管道的工作原理1.3、命名管道与匿名管道的区别 2、命名管道的特点及特殊场景2.1、特点2.2、四种特殊场景 3、命名管道实操3.1、实现文件拷贝3.2、实现进程控制 小结 &#x1f3…...

Cursor 工具项目构建指南:Java 21 环境下的 Spring Boot Prompt Rules 约束

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 Cursor 工具项目构建指南:Java 21 环境下的 Spring Boot Prompt Rules 约束前言项目简…...

各个布局的区别以及示例

各个布局的区别以及示例 在前端开发中&#xff0c;常见的布局方式主要有以下几种&#xff0c;每种布局都有其适用场景和特点&#xff1a; 1. 普通文档流&#xff08;Normal Flow&#xff09; 特点&#xff1a;默认布局方式&#xff0c;元素按照HTML顺序依次排列。适用场景&am…...

什么是MVC?

导语&#xff1a; 在Java后端面试中&#xff0c;“MVC架构”是绕不开的基础话题。它不仅关乎项目的整体设计思路&#xff0c;更体现了候选人的架构理解能力与编码规范意识。本文将从面试官视角出发&#xff0c;结合高频问题、代码示例、答题技巧与加分项&#xff0c;带你全面吃…...

STM32的ADC简介

一、ADC简介 STM32的ADC是一种12位逐次逼近型模拟数字转换器。它具备18个通道&#xff0c;能够测量16个外部信号源以及2个内部信号源。各通道的A/D转换可以执行单次、连续、扫描或间断模式。转换结果可采用左对齐或右对齐的方式&#xff08;12位&#xff09;存储于16位数据寄存…...

Bash shell四则运算

文章目录 四则运算1. ‌expr 命令‌2. ‌$(( )) 表达式&#xff08;推荐&#xff09;‌3. ‌$[ ] 表达式&#xff08;已弃用&#xff09;‌4. ‌let 命令‌小数运算i 和 i 区别 四则运算 算术运算&#xff1a; - * / %&#xff08;取模&#xff0c;求余数&#xff09; Bash sh…...

(javaSE)Java数组进阶:数组初始化 数组访问 数组中的jvm 空指针异常

数组的基础 什么是数组呢? 数组指的是一种容器,可以用来存储同种数据类型的多个值 数组的初始化 初始化&#xff1a;就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程。 数组初始化的两种方式&#xff1a;静态初始化&#xff0c;动态初始化 数组的静态初始化 初始化…...

力扣刷题Day 70:在排序数组中查找元素的第一个和最后一个位置(34)

1.题目描述 2.思路 方法1&#xff08;自己写的&#xff09;&#xff1a;一次二分查找找到等于target的一个元素索引axis&#xff0c;然后向左右延伸找边界。 方法2&#xff08;灵茶山艾府佬的闭区间二分查找写法&#xff09;&#xff1a;定义一个lower_bound()函数找到第一个…...

vue 多端适配之pxtorem

在 Vue 3 Vite 项目中使用 postcss-pxtorem 自动将 px 单位转换为 rem 单位&#xff0c;可以按照以下步骤配置&#xff1a; 一、基础版本 1. 安装依赖 首先安装必要的插件&#xff1a; npm install postcss postcss-pxtorem autoprefixer -D # 或 yarn add postcss postcs…...

图片压缩工具 | 图片属性详解及读取解析元数据

ℹ️ 图片信息及属性 基本属性 格式类型&#xff1a;JPEG、PNG、GIF、WEBP、BMP、TIFF等文件大小&#xff1a;以KB、MB等为单位的存储空间占用创建/修改日期&#xff1a;文件的元数据时间戳 视觉属性 尺寸/分辨率 宽度&#xff08;像素&#xff09;高度&#xff08;像素&…...

React---day8

9.6 不可变数据的力量 我们知道是不能够修改this.state里面的数据的 举个例子 export class App extends React.PureComponent{constructor(){super();this.state {userList:[{name : "tom" , age : 18},{name : "lily" , age : 20},{name : "tik…...

C# Onnx 动漫人物人脸检测

目录 效果 模型信息 项目 代码 下载 参考 效果 模型信息 Model Properties ------------------------- stride&#xff1a;32 names&#xff1a;{0: face} --------------------------------------------------------------- Inputs ------------------------- name&am…...

C++内存列传之RAII宇宙:智能指针

文章目录 1.为什么需要智能指针&#xff1f;2.智能指针原理2.1 RAll2.2 像指针一样使用 3.C11的智能指针3.1 auto_ptr3.2 unique_ptr3.3 shared_ptr3.4 weak_ptr 4.删除器希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 智能指针是 C 中用于自动…...

PVE 虚拟机安装 Ubuntu Server V24 系统 —— 一步一步安装配置基于 Ubuntu Server 的 NodeJS 服务器详细实录1

前言 最近在基于 NodeJS V22 写一个全栈的项目&#xff0c;写好了&#xff0c;当然需要配置服务器部署啦。这个过程对于熟手来说&#xff0c;还是不复杂的&#xff0c;但是对于很多新手来说&#xff0c;可能稍微有点困难。所以&#xff0c;我把整个过程全部记录一下。 熟悉我…...

GitHub 趋势日报 (2025年06月03日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 2404 onlook 860 system-design-primer 380 nautilus_trader 372 agent-zero 357 …...

出现dev/nvmeOnip2 contains a file system with errors, check forced 解决方法

目录 前言1. 问题所示2. 原理分析3. 解决方法4. 彩蛋前言 爬虫神器,无代码爬取,就来:bright.cn Java基本知识: java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)【Java项目】实战CRUD的功能整理(持续更新)1. 问题所示 出现如下问题: dev/nvmeOnip2 co…...

Vue3.5 企业级管理系统实战(二十二):动态菜单

在前几篇内容中已完成菜单、角色及菜单权限等相关开发&#xff0c;若要在左侧菜单根据用户角色动态展示菜单&#xff0c;需对 Sidebar 中的相关数据进行修改。鉴于其他相关方法及类型已在前文实现&#xff0c;本文不再重复阐述。 1 修改 Sidebar 组件 在 src/layout/componen…...

磨皮功能 C++/C的OpenCV 实现

磨皮功能 C/C的OpenCV 实现 前提条件 OpenCV 安装&#xff1a; 你需要正确安装 OpenCV 库。C 编译器&#xff1a; 如 G。 C 代码 #include <opencv2/opencv.hpp> #include <iostream> #include <string>// 使用标准命名空间 using namespace std; using …...

蓝牙防丢器应用方案

蓝牙防丢器通常由两个主要部分构成&#xff1a;一个小型装置&#xff0c;亦称为标签&#xff0c;以及一个与之配对的手机应用程序。该标签内置一个微型蓝牙芯片&#xff0c;能够与配对的手机应用程序进行通信。一旦标签与手机之间的连接中断&#xff0c;手机应用程序便会接收到…...

TDengine 开发指南——高效写入

高效写入 本章内容将介绍如何发挥 TDengine 最大写入性能&#xff0c;通过原理解析到参数如何配置再到实际示例演示&#xff0c;完整描述如何达到高效写入。 为帮助用户轻松构建百万级吞吐量的数据写入管道&#xff0c;TDengine 连接器提供高效写入的特性。 启动高效写入特性…...

Linux kill 暂停命令

暂停进程 kill -19 在一台服务器上部署了360Pika服务&#xff0c;先用RedisClient连接一下&#xff0c;可以连接 现在暂停进程 暂停后发现再次连接无法连接 恢复进程 kill -18 恢复后可连接...