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

【C语言】函数

目录

一、函数的概念

二、库函数

2.1 ❥ 标准库

2.2 ❥ 库函数的使用方法

三、自定义函数

四、形参和实参

4.1 ❥ 实参(实际参数)

4.2 ❥ 形参(形式参数)

五、return语句

六、函数的调用

6.1 ❥ 传值调用

6.2 ❥ 传址调用

七、函数的嵌套调用和链式访问

7.1 ❥ 嵌套调用

7.2 ❥ 链式访问

八、函数的声明和定义

8.1 ❥ 函数的声明

8.2 ❥ 函数的定义


一、函数的概念

函数(function)又称为:子程序。

C语言中的函数是一个完成某项特定任务的一小段代码,而且相较于其它代码,具备相对的独立性。

一般会有输入参数也有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

C语言的程序是由无数个小的函数组合而成的,也就是说:一个大的计算任务可以分解成若干个较小的函数(对应较小的任务)完成。同时一个函数如果能完成某项特定任务的话,这个函数也是可以复用的,提升了开发软件的效率。

在C语言中我们一般会见到两类函数:

  • 库函数
  • 自定义函数

二、库函数

为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。

2.1 ❥ 标准库

C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数。

C语言的国际标准ANSI C规定了一些常用的函数的标准,被称为标准库。不同的编译器厂商根据ANSI提供的C语言标准就给出了一系列函数的实现,这些函数就被称为库函数


我们学到的 printf 、scanf、pow都是库函数,库函数的也是函数,不过这些函数是现成的,我们只要学会就能直接使用了。

有了库函数,⼀些常见的功能就不需要程序员自己实现了,一定程度提升了效率;同时库函数的质量和执行效率上都更有保证。
 

2.2 ❥ 库函数的使用方法

C/C++官方的链接:https://zh.cppreference.com/w/c/header
cplusplus.com:https://legacy.cplusplus.com/reference/clibrary/

各种编译器的标准库中提供了一系列的库函数,这些库函数根据功能的划分,都在不同的头文件中进行了声明。

库函数是在标准库中对应的头文件中声明的,所以使用库函数,必须包含#include对应的头文件。

例如sqrt的使用如下图:

三、自定义函数

自定义函数:是由程序员自己来创造的一个函数。

自定义函数和库函数一样,有函数名,返回值类型和函数参数。

语法形式如下:

ret_type  fun_name(形式参数)
{

语句项;
}

  • ret_type :函数返回类型
  • fun_name :函数名
  • 括号中放的是形式参数
  • { }括起来的是函数体

我们可以把函数想象成小型的一个加工厂,工厂得输入原材料,经过工厂加工才能生产出产品,函数也是一样的,函数一般会输入一些值(可以是0个,也可以是多个),经过函数内的计算,得出结果。

  •  ret_type 用来表示函数计算结果的类型,当返回类型是 void的时候 ,表示什么都不返回。
  • fun_name 是为了方便使用函数;就像人的名字⼀样,有了名字方便称呼,函数有了名字方便调用,所以函数名尽量要根据函数的功能起的有意义。
  •  函数的参数就相当于,工厂中送进去的原材料,函数的参数也可以是 void ,明确表示函数没有参数。如果有参数,要交代清楚参数的类型和名字,以及参数个数。
  • {}括起来的部分被称为函数体,函数体就是完成计算的过程。

四、形参和实参

4.1 ❥ 实参(实际参数)

  • 真实传给函数的参数,叫实参。
  • 实参可以是:常量,变量,表达式,函数等。
  • 无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
  • 实参是函数的前提是该函数一定得有返回值

4.2 ❥ 形参(形式参数)

  • 形式参数是指函数名后括号中的变量。
  • 因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。
  • 当函数调用完成之后形式参数就自动销毁了,因此形参只在函数中有效。
  • 形式参数在函数不调用的情况下只是形式上的存在,只有在调用的时候才会真正的开辟内存空间。
  • 形参实例化之后相当于实参的一份临时拷贝。

4.3 ❥ 举例

五、return语句

在函数的设计中,函数经常会出现return语句,那return语句的使用需要哪些注意事项呢?

  1. return后边可以是一个数值,也可以是一个表达式,如果是表达式则先执行表达式,再返回表达式结果。
  2. return后边也可以什么都没有,直接写return; ,这种写法适合函数返回值类型是void的情况
  3. return返回的值和函数返回类型不一致,系统会自动将返回的值隐式转换为函数的返回类型。
  4. return语句执行后,函数就彻底返回,后边的代码不再执行。
  5. 如果函数中存在if等分支的语句,则要保证每种情况下都有return返回,否则会出现编译错误。

六、函数的调用

6.1 ❥ 传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。

例如下面代码:

#include <stdio.h>
void Swap(int x, int y)
{int c = 0;c = x;x = y;y = c;
}
int main()
{int a = 10;int b = 20;printf("交换前:a=%d,b=%d\n", a, b);Swap(a, b);printf("交换后:a=%d,b=%d\n", a, b);return 0;
}

6.2 ❥ 传址调用

  • 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
  • 这种传参的方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。

例如下面代码:

#include <stdio.h>
void Swap(int* x, int* y)
{int c = 0;c = *x;*x = *y;*y = c;
}
int main()
{int a = 10;int b = 20;printf("交换前:a=%d,b=%d\n", a, b);Swap(&a, &b);printf("交换后:a=%d,b=%d\n", a, b);return 0;
}

6.3 ❥ 适用场景

那么什么时候需要&取地址什么时候不需要呢?

  • 当对变量(实际参数)进行修改的时候,则需要取地址。
  • 如果该函数只是想得到变量(实际参数)的值,则不需要取地址。

七、函数的嵌套调用和链式访问

7.1 ❥ 嵌套调用

嵌套调用就是:函数和函数之间根据实际需求互相调用。

注意事项

  • 函数可以嵌套调用,但不能嵌套定义。
  • 嵌套定义的意思:是函数里包含着另一个函数。
  • 函数的地位都是平等的,都应该在同一位置上。

7.2 ❥ 链式访问

链式访问:就是将一个函数的返回值作为另外一个函数的参数,像链条一样将函数串起来就是函数
的链式访问。

我们看如下两段代码:

代码1

#include <stdio.h>
int main()
{int len = strlen("abcdef");printf("%d\n", len);printf("%d\n", strlen("abcdef")); //链式访问return 0;
}

代码2

出现该结果的原因是:printf函数返回的是打印在屏幕上的字符的个数。

上面例子中,第一个printf打印的是第二个printf的返回值,第二个printf打印的是第三个printf的返回值。

第三个printf打印43,在屏幕上打印2个字符,再返回2。

第二个printf打印2,在屏幕上打印1个字符,再返回1。

第一个printf打印1。

所以屏幕上最终打印:4321

注意事项

  • 链式访问的前提是函数得有返回值
  • 如果一个函数没有返回类型,返回类型写的void,那么就没法链式访问
  • 函数不写返回值类型的时候,默认返回值类型是int

形参是void的意思是:明确说明不需要传参,传参就会报警告。如果没有void就不会报错。

如下图所示:

说明test有void参数,明确声明不要传参数。

八、函数的声明和定义

8.1 ❥ 函数的声明

我们先看下面这一段代码:

红色框住的是函数的定义,紫色框住的是函数的调用

我们发现,通常在写函数的时候,会把函数的定义写在调用的前面,那如果写在后面呢?

我们来测试一下:

在vs2022上运行发现:代码会出现以上的警告信息。

原因:因为C语言编译器对源代码进行编译的时候,是从第一行往下扫描的,当遇见Add函数调用的时候,并没有发现前面有Add的定义,就会报出上述的警告。

如何才能解决这个问题,可以在函数调用之前先声明一下这个Add函数。声明函数只需要交代清楚函数名,函数的返回类型和函数的参数。

如:int Add(int x,int y);

这就是函数声明,函数声明中参数可以只保留类型,省略掉名字。

#include <stdio.h>int Add(int a, int b);//函数的声明int main()
{int a = 10;int b = 20;int c = Add(a, b);return 0;
}
int Add(int a, int b)
{return a + b;
}

注意事项

  • 函数的声明是告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。

具体存不存在,函数声明决定不了,可能上面声明了这个函数,主函数也去使用了,但去找那个函数,却发现没有,(发布假的声明)。是否真的有还是取决于函数的定义。

  • 函数的声明一般出现在函数的使用之前。要满足先声明后使用
  • 函数的定义也是一种特殊的声明,所以如果函数定义放在调用之前也是可以的。

多文件使用的时候,一般把函数的声明放在头文件(.h)中,函数的定义放在源文件(.c)中。

然后头文件就可以使用对应模块的代码。

注意:库里面提供的头文件,用尖括号<>;自己定义的头文件用双引号 " "

这里用双引号定义的头文件就相当于函数的声明,其实就是为了实现函数的声明这个效果。它的本质意义就是把头文件内容拷过来。

函数的声明和函数的定义分文件的好处:

本来可以不用函数的声明,函数的定义利用函数的外部链接属性也可以实现,但分开写可以把函数的实现这个模块变成静态库,静态库是二进制的,是看不懂的。一个静态库里可以放很多函数,所以可以适当的隐藏代码,保证代码的隐私性。

  1. 逻辑清晰
  2. 方便多人协调
  3. 适当的隐藏代码

8.2 ❥ 函数的定义

是指函数的具体实现,交代函数的功能实现。

相关文章:

【C语言】函数

目录 一、函数的概念 二、库函数 2.1 ❥ 标准库 2.2 ❥ 库函数的使用方法 三、自定义函数 四、形参和实参 4.1 ❥ 实参&#xff08;实际参数&#xff09; 4.2 ❥ 形参&#xff08;形式参数&#xff09; 五、return语句 六、函数的调用 6.1 ❥ 传值调用 6.2 ❥ 传址调…...

【LeetCode】每日一题 2024_5_13 腐烂的橘子(经典多源 BFS)

文章目录 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01;题目&#xff1a;找出不同元素数目差数组题目描述代码与解题思路 每天进步一点点 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 好久没写每日一题题解了&#xff0c;今天重新起航 干…...

【Linux系统编程】第十七弹---进程理解

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、进程的基本概念 2、描述进程-PCB 2.1、什么是PCB 2.2、为什么要有PCB 3、task_ struct 3.1、启动进程 3.2、创建进程…...

【网络安全入门】你必须要有的学习工具(附安装包)零基础入门到进阶,看这一篇就够了!

工欲善其事必先利其器 在新入门网络安全的小伙伴而言。这些工具你必须要有所了解。本文我们简单说说这些网络安全工具吧&#xff01; Web安全类 Web类工具主要是通过各种扫描工具&#xff0c;发现web站点存在的各种漏洞如sql注入、xss等。从而获取系统权限&#xff0c;常用的…...

【解决】:git clone项目报错fatal: fetch-pack: invalid index-pack output

象&#xff1a;之前一直使用gitee将个人学习和工作相关记录上传到个人gitee仓库&#xff0c;一直没出现过问题。直到有一天换电脑重新拉取代码发现出了问题&#xff0c;具体如下图&#xff1a; 原因分析&#xff1a; 经过查询发现主要原因是因为git clone的远程仓库的项目过大…...

python随机显示四级词汇

python实现一个浮动窗口随机显示四级单词在桌面跑来跑去 实现一个浮动窗体随机显示四级单词在windows桌面置顶移动 tkinter库来创建窗口和显示单词&#xff0c;以及random库来随机选择单词。 使用after方法来定时更新窗口的位置&#xff0c;实现单词窗口的慢慢移动效果 使用…...

vuerouter声明式导航

声明式导航-跳转传参数 1.查询参数传参 语法&#xff1a;to /path?参数名值 2.对应页面组件接受传来的值 $router.query.参数名 2.动态路由传参 1.配置动态路由 2.配置导航连接 to/path/参数值 3.对应页面组件接收传递过来的值 #route.params.参数名 多个参数传递&…...

视频断点上传

什么是断点续传 通常视频文件都比较大&#xff0c;所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制&#xff0c;但是客户的网络环境质量、电脑硬件环境等参差不齐&#xff0c;如果一个大文件快上传完了网断了没有上传完成&#xf…...

清华团队开发首个AI医院小镇模拟系统;阿里云发布通义千问 2.5:超越GPT-4能力;Mistral AI估值飙升至60亿美元

&#x1f989; AI新闻 &#x1f680; 清华团队开发首个AI医院小镇模拟系统 摘要&#xff1a;来自清华的研究团队最近开发出了一种创新的模拟系统&#xff0c;名为"Agent Hospital"&#xff0c;该系统能够完全模拟医患看病的全流程&#xff0c;其中包括分诊、挂号、…...

React Suspense与Concurrent Mode:探索异步渲染的新范式

React的Suspense和Concurrent Mode是两个强大的特性&#xff0c;它们共同改变了React应用处理异步数据加载和UI渲染的方式。下面我将通过一个简化的代码示例来展示如何使用这两个特性。 Concurrent Mode 和 Suspense 的基本用法 首先&#xff0c;确保你使用的是支持这些特性的…...

算法训练营day37

动态规划 1.斐波那契数 1.使用数组存储子问题结果 class Solution {public int fib(int N) {if (N 0) return 0;int[] dp new int[N 1];// base casedp[0] 0; dp[1] 1;// 状态转移for (int i 2; i < N; i) {dp[i] dp[i - 1] dp[i - 2];}return dp[N];} }2.使用变…...

基础ArkTS组件:帧动画,内置动画组件,跑马灯组件(HarmonyOS学习第三课【3.6】)

帧动画 帧动画也叫序列帧动画&#xff0c;其原理就是在时间轴的每帧上逐帧绘制不同的内容&#xff0c;使其连续播放而成动画。ArkUI开发框架提供了 ImageAnimator 组件实现帧动画能力&#xff0c;本节笔者介绍一下 ImageAnimator 组件的简单使用。 官方文献 说明 该组件从A…...

vant NavBar 导航栏详解

vant 是一个基于 Vue 的移动端 UI 组件库&#xff0c;而 NavBar 是其中的一个导航栏组件。下面是对 vant 的 NavBar 导航栏组件的详细解释&#xff1a; 1. 引入 NavBar 首先&#xff0c;你需要在你的 Vue 组件中引入 NavBar 组件&#xff1a; import { NavBar } from vant; …...

Python自动化办公实战案例:文件整理与邮件发送

目录 一、引言 二、案例背景 三、实战案例 &#xff08;一&#xff09;文件自动整理 &#xff08;二&#xff09;邮件自动发送 四、结语 一、引言 随着办公自动化的兴起&#xff0c;Python作为一门强大的编程语言&#xff0c;逐渐被应用于日常办公中。从文件整理到邮件…...

2024中国(重庆)无人机展览会8月在重庆举办

2024中国(重庆)无人机展览会8月在重庆举办 邀请函 主办单位&#xff1a; 中国航空学会 重庆市南岸区人民政府 招商执行单位&#xff1a; 重庆港华展览有限公司 报名&#xff1a;【交易会I 59交易会2351交易会9466】 展会背景&#xff1a; 为更好的培养航空航天产业和无人…...

自动驾驶技术与传感器数据处理

目录 自动驾驶总体架构 感知系统 决策系统 定位系统 ​计算平台​ 仿真平台​ 自动驾驶公开数据集 激光点云 点云表征方式 1) 原始点云 2) 三维点云体素化 3)深度图 4)鸟瞰图 点云检测障碍物的步骤 PCL点云库 车载毫米波雷达 车载相机 设备标定 自动驾驶…...

高效测评系统方案助力沃尔玛、亚马逊卖家提升产品销量

无论在哪个电商平台&#xff0c;测评确实是最有效的推广方式。测之前一定要选好产品&#xff0c;因为对于大部分卖家而言&#xff0c;不可能你店铺里所有的都是爆款&#xff0c;所以选择的是需要有潜力成为爆款的产品。测评是指通过搭建安全的环境模拟真实的买家购物行为&#…...

B/S模式的web通信(高并发服务器)

这里写目录标题 目标实现的目标 服务器代码&#xff08;采用epoll实现服务器&#xff09;整体框架main函数init_listen_fd函数&#xff08;负责对lfd初始化的那一系列操作&#xff09;epoll_run函数do_accept函数do_read函数内容补充&#xff1a;http中的getline函数 详解do_re…...

C语言每日一题—约瑟夫问题

13个人围成一圈&#xff0c;从第1个人开始顺序报号1、2、3&#xff0c;凡报到3的人退出圈子。找出最后留在圈子里的人原来的序号。要求用结构体编程实现。***输出提示&#xff1a;"\n出圈成员及顺序&#xff1a;" ***输出格式&#xff1a;"%3d" ***输出提示…...

语言:C#

一、VSCode生成exe 二、...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...