【C语言】函数的定义、传参与调用(一)

 目录

导读:

1. 为什么要用函数

2. C语言中函数的分类

2.1 库函数

2.1.1 什么是库函数

2.1.2 C语言常用的库函数

2.2 自定义函数

2.2.1 什么是自定义函数

2.2.2 定义函数的方法

2.2.3 举例

 3. 函数的参数

3.1 传参不同的对比

3.2 形式参数(形参)和实际参数(实参)

3.3 解析代码

4. 函数的调用

4.1 传值调用

4.2 传址调用 

4.3 练习 

4.3.1 传值练习

4.3.2 传址练习

博主有话说


导读:

本章节我们来学习一下函数是什么,为什么要用函数,怎样取定义一个函数

相关的库函数使用可以看一下:

字符串操作函数

字符串操作函数

1. 为什么要用函数

  • 使用函数可以使代码变得模块化和更易读,同时也可以减少代码的重复性。
  • 函数可以接受参数,以便在不同的情况下执行相同的操作。在代码的其他部分需要调用这个操作时,只需要调用函数而不必重复编写代码。
  • 函数可以使代码更容易维护和测试,因为它们将相对独立的代码块隔离出来。
  • 通过使用函数,可以使代码更加清晰、简洁和易于理解。

2. C语言中函数的分类

库函数                    自定义函数

2.1 库函数

2.1.1 什么是库函数

库函数是现成的函数库中可用的函数。

这些函数通常作为程序员的工具,在编程过程中被调用使用。库函数通常包含在操作系统或者编程语言的标准库中,以便程序员方便地调用这些函数来完成特定的任务,例如字符串操作、文件操作、网络操作等。库函数经过长时间的使用和测试,已经经过优化,因此程序员可以使用这些函数来提高代码的可维护性、可读性和执行效率。

2.1.2 C语言常用的库函数

字符串操作函数:如strlen()、strcpy()、strcat()、strcmp()等

动态内存分配函数:如malloc()、calloc()、realloc()、free()等。

时间函数:如time()、asctime()、mktime()等

数学函数:如sin()、cos()、tan()、log()、exp()、sqrt()等

 注意:

使用库函数,必须包含 #include 对应的头文件。

2.2 自定义函数

如果库函数能干所有的事情,那还要程序员干什么?

所以更加重要的是自定义函数。

2.2.1 什么是自定义函数

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

但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间

2.2.2 定义函数的方法

ret_type fun_name( para1,  *  )

{

        statement;//语句项

}

ret_type 返回类型

fun_name 函数名

para1     函数参数

2.2.3 举例

写一个函数可以找出两个整数中的最大值。

//get_max函数的设计
int get_max(int x, int y)
{return (x > y) ? (x) : (y);
}
int main()
{int num1 = 10;int num2 = 20;int max = get_max(num1, num2);printf("max = %d\n", max);return 0;
}

 

 3. 函数的参数

3.1 传参不同的对比

我们来看下面的代码:

写一个函数,实现交换两个整形变量的内容。

void Swap1(int x, int y)
{int tmp = 0;tmp = x;x = y;y = tmp;
}
int main()
{int num1 = 10;int num2 = 20;Swap1(num1, num2);printf("Swap1::num1 = %d num2 = %d\n", num1, num2);return 0;
}

我们把num1和num2传参给Swap1这个函数,x 和 y 分别来接收,让其实现两个数的交换,结构如何呢?

我们发现两个值并没有实现交换,我们换一种传参方式试一下

void Swap2(int* px, int* py)
{int tmp = 0;tmp = *px;*px = *py;*py = tmp;
}
int main()
{int num1 = 10;int num2 = 20;Swap2(&num1, &num2);printf("Swap2::num1 = %d num2 = %d\n", num1, num2);return 0;
}

这次我们把num1和num2的地址传给Swap2函数,让指针变量*px和*py来接收,结果又是如何呢?

成功交换!

这就是形参和实参的区别

3.2 形式参数(形参)和实际参数(实参)

形式参数:

形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有 效。

实际参数: 

真实传给函数的参数,叫实参。

实参可以是:常量、变量、表达式、函数等。

无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。

上面 Swap1 和 Swap2 函数中的参数 &num1 , x,y,px,py都是形式参数。

在main函数中传给 Swap1 的 num1、num2 和传给Swap2函数的&num1、&num2 是实际参数。

3.3 解析代码

Swap1:

我们来进入调试,查看两块代码的不同

当函数调用时,实参的值被复制到函数的形参中。

这意味着,形参在函数的局部作用域内创建,并且在函数调用结束时被销毁。

因此,在内存中,形参的值存在于函数的栈帧中,而实参的值仍然存在于调用函数的上下文中。

Swap1 函数在调用的时候,x,y拥有自己的空间,同时拥有了和实参一模一样的内容。

所以我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝。

Swap2:

指针变量px和py存储着num1和num2的地址,改变对px和py解引用操作后,指向的就是num1和num2这片空间的值,才能实现两者的调换

4. 函数的调用

在函数调用中,参数可以通过传值调用或传址调用来传递。

4.1 传值调用

传值调用是指将实参的值复制一份传递给形参的过程。

在函数内部,对形参的任何修改都不会影响到实参。

这种方式比较简单,但是如果需要传递大量的参数或者需要频繁修改参数的值,可能会比较低效

4.2 传址调用 

传址调用是指将实参的地址传递给形参的过程。

在函数内部,可以通过该地址直接访问实参的内容。

如果对形参进行修改,就相当于对实参进行了修改,因为它们指向同一块内存。

这种方式比较高效,但是需要注意不要意外修改实参的内容。

4.3 练习 

4.3.1 传值练习

判断一个数是否是素数

int isPrime(int num) 
{int i;if (num < 2) { //小于 2 的数都不是素数return 0; // 返回 false}for (i = 2; i * i <= num; i++) { //从 2 开始到 sqrt(num) 循环if (num % i == 0) { // 如果可以整除,说明不是素数return 0; // 返回 false}}return 1; // 如果上述循环完毕还没有返回 false,则说明是素数,返回 true
}
int main() 
{int num;printf("请输入一个整数:");scanf("%d", &num);if (isPrime(num)) {printf("%d是素数\n", num);}else {printf("%d不是素数\n", num);}return 0;
}

测试:

1       3       8       9

 

4.3.2 传址练习

写一个函数,每调用一次这个函数,就会将n值增加1

void increase(int* n) 
{(*n)++;
}
int main() 
{int a = 1;printf("a = %d\n", a);increase(&a);printf("a = %d\n", a);increase(&a);printf("a = %d\n", a);return 0;
}

博主有话说

有关函数的内容今天就到这里,接下来还有函数的嵌套调用、声明和定义以及函数递归。

更多内容关注博主,掌握最新内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147731.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

列表的增删改查和遍历

任务概念 什么是任务 任务是一个参数为指针&#xff0c;无法返回的函数&#xff0c;函数体为死循环不能返回任务的实现过程 每个任务是独立的&#xff0c;需要为任务分别分配栈称为任务栈&#xff0c;通常是预定义的全局数组&#xff0c;也可以是动态分配的一段内存空间&#…

腾讯云域名API解析升级版本(通过Java实现)腾讯云动态公网IP绑定域名实现内网服务器公网穿透

公众号推广: 目前CSDN进行VIP可见,文章可在微信公众号进行免费的阅读。 文章内容经过认证实践,比较的清晰易懂,适合初次接触的人员。 请关注微信公众号:菜鸟编程踩坑之路,进入公众号搜索关键词 内网穿透 需求场景: 首先我自己组装了一台自己的服务器,相比较购买的阿…

CVE-2020-11978 Apache Airflow 命令注入漏洞分析与利用

简介 漏洞软件&#xff1a;Apache Airflow影响版本&#xff1a;< 1.10.10 环境 Vulhub 漏洞测试靶场 复现步骤 进入 /root/vulhub/airflow/CVE-2020-11978/ 目录运行以下命令启动环境 # 初始化数据库 docker compose run airflow-init # 开启服务 docker compose up -…

计算机算法分析与设计(4)---凸多边形的最优三角划分(含C++代码)

文章目录 一、概述1.1 概念说明1.2 与矩阵连乘对应关系1.3 递归定义 二、代码 一、概述 1.1 概念说明 1. 用多边形顶点的逆时针序列表示凸多边形&#xff0c;即P{V0, V1, … Vn-1, Vn}表示具有n1条边的凸多边形。 2. 若Vi和Vj是多边形上不相邻的两个顶点&#xff0c;则线段ViV…

华为鸿蒙手表开发之动态生成二维码

华为鸿蒙手表开发之动态生成二维码 前言&#xff1a; 最近入职新公司&#xff0c;由于之前的哥们临时离职&#xff0c;走得很突然&#xff0c;所以没有任何交接和文档&#xff0c;临时顶上公司手表应用的上架&#xff0c;更换了新的密钥和key之后重新测试功能和流程&#xff…

unity 鼠标标记 左键长按生成标记右键长按清除标记,对象转化为子物体

linerender的标记参考 unity linerenderer在Game窗口中任意画线_游戏内编辑linerender-CSDN博客 让生成的标记转化为ARMarks游戏对象的子物体 LineMark.cs using System.Collections; using System.Collections.Generic; using UnityEngine;public class LineMark : MonoBeh…

【Docker】docker拉取镜像错误 missing signature key

问题 当我使用docker拉取一个特定的镜像时&#xff0c;提示错误&#xff1a; 错误 missing signature key 但是拉取其他镜像又可以访问&#xff0c;&#xff0c;&#xff0c;&#xff0c;于是&#xff0c;我怀疑是否是docker版本问题。 docker --version结果确实&#xff0…

【网络安全-sqlmap】sqlmap以及几款自动化sql注入工具的详细使用过程,超详细,SQL注入【5】

一&#xff0c;sqlmap 工具的详细使用 kali系统自带这个工具&#xff0c;无需安装直接sqlmap 后面接参数使用 Windows上参照以下方法安装即可 1-1 工具下载 1-1-1 sqlmap下载 sqlmap 工具下载地址&#xff1a; GitHub - sqlmapproject/sqlmap: Automatic SQL injection a…

获取网卡上的IP、网关及DNS信息,获取最佳路由,遍历路由表中的条目(附源码)

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

flutter开发实战-应用更新apk下载、安装apk、启动应用实现

flutter开发实战-应用更新apk下载、安装apk、启动应用实现 在开发过程中&#xff0c;经常遇到需要更新下载新版本的apk文件&#xff0c;之后进行应用更新apk下载、安装apk、启动应用。我们在flutter工程中实现下载apk&#xff0c;判断当前版本与需要更新安装的版本进行比对判断…

【强化算法专题一】双指针算法

【强化算法专题一】双指针算法 1.双指针算法--移动零2.双指针算法--复写零3.双指针算法--快乐数4.双指针算法--盛水最多的容器5.双指针算法--有效三角形的个数6.双指针算法--和为s的两个数7.双指针算法--三数之和8.双指针算法--四数之和 1.双指针算法–移动零 算法原理解析----…

普通人需要做副业吗?有什么合适的副业

普通人现在需要做副业吗&#xff0c;我觉得有这个必要&#xff0c;当然也要根据个人情况选择&#xff0c;那么做副业有什么好处呢&#xff1f;做副业可以带来额外的收入&#xff0c;增加灵活性&#xff0c;提升技能&#xff0c;发展创造力&#xff0c;降低风险&#xff0c;提供…

计算机竞赛 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

【高强度聚焦超声模拟器】模拟分层介质中的高强度聚焦超声波束和加热效应(Matlab代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

实体行业数字化转型怎么做?线上线下相结合的新零售体系怎么做?

如今&#xff0c;实体行业想要取得收入增长&#xff0c;只做线下业务或者只做线上业务&#xff0c;在当前的市场环境中是难以长久生存的&#xff0c;因此一定要线上线下相结合&#xff0c;将流量运作与线下转化进行充分结合&#xff0c;才能更好地发挥实体优势&#xff0c;带来…

Java后端模拟面试,题集①

1.Spring bean的生命周期 实例化 Instantiation属性赋值 Populate初始化 Initialization销毁 Destruction 2.Spring AOP的创建在bean的哪个时期进行的 &#xff08;图片转载自Spring Bean的完整生命周期&#xff08;带流程图&#xff0c;好记&#xff09;&#xff09; 3.MQ如…

毛玻璃用户卡交互

效果展示 页面结构组成 从效果展示可以看到&#xff0c;此效果都是比较常规的。主要的核心就是卡片的悬停效果。 CSS 知识点 backdrop-filter 回顾transitiontransform 页面基础布局实现 <section><div class"container"><div class"card&q…

第8期ThreadX视频教程:应用实战,将裸机工程移植到RTOS的任务划分,驱动和应用层交互,中断DMA,C库和中间件处理等注意事项

视频教程汇总帖&#xff1a;【学以致用&#xff0c;授人以渔】2023视频教程汇总&#xff0c;DSP第12期&#xff0c;ThreadX第8期&#xff0c;BSP驱动第26期&#xff0c;USB实战第5期&#xff0c;GUI实战第3期&#xff08;2023-10-01&#xff09; - STM32F429 - 硬汉嵌入式论坛 …

【springboot3.x 记录】关于spring-cloud-gateway引入openfeign导致的循环依赖问题

最近升级springboot3真是一挖一个坑&#xff0c;又给我发现了 spring-cloud-gateway 引入 openfeign 会导致循环依赖异常&#xff0c;特此记录一下这个坑 一、发现问题 网关里面有一个全局的过滤器&#xff0c;因为要查询一些配置信息&#xff0c;目前是通过 feign client 的方…

掌机小霸王,开源俄罗斯方块小游戏

俄罗斯方块试玩gi PC或手机 点开即玩: https://chvin.github.io/react-tetris/?lanzh-cn 也可以扫码开玩: 实现了数据的持久化 游戏进度的数据可以持久存储到本地浏览器, 即使刷新网页也无需重新开始游戏 小结: 俄罗斯方块属于超级经典的游戏, 感兴趣可以玩一下, 找回一点童…