【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.mzph.cn/news/93800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASUS (k013) ME176CX不进入系统恢复出厂设置的方法

k013 me176cx ASUS k013 ME176CX不进入系统恢复出厂设置的方法 当忘记系统密码或系统异常导致无法进入系统时&#xff0c;可以按以下步骤尝试不进入系统恢复出厂设置来解决。 注意&#xff1a;执行恢复出厂设置前&#xff0c;请先将资料备份至外接设备&#xff0c;否则资料都…

Linux基本指令(上)——“Linux”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;小雅兰的内容是Linux啦&#xff01;&#xff01;&#xff01;主要是Linux的一些基本指令和Linux相关的基本概念&#xff08;系统层面&#xff09;&#xff0c;下面&#xff0c;让我们进入Linux的世界吧&#xff01;&#xff01;…

微服务技术栈-Ribbon负载均衡和Nacos注册中心

文章目录 前言一、Ribbon负载均衡1.LoadBalancerInterceptor&#xff08;负载均衡拦截器&#xff09;2.负载均衡策略IRule 二、Nacos注册中心1.Nacos简介2.搭建Nacos注册中心3.服务分级存储模型4.环境隔离5.Nacos与Eureka的区别 总结 前言 在上面那个文章中介绍了微服务架构的…

金融机构操作风险与内控合规的介绍

目录 一.前言 术语 二.功能设计 三.部分功能简介 流程管理 流程清单 流程详情 流程重检 流程重检反馈 风险与控制自我评估&#xff08;RCSA&#xff09; 评估计划管理 评估结果管理 关键风险指标&#xff08;KRI&#xff09; 指标库管理 基础数据项录入 指标监测…

使用晶体管做布尔逻辑和逻辑门

目录 二进制&#xff0c;三进制&#xff0c;五进制 true&#xff0c;false表示0&#xff0c;1 早期计算机采用进制 布尔逻辑 三个基本操作&#xff1a;NOT,AND,OR 基础“真值表” NOT 如何实现&#xff1f; AND如何实现&#xff1f; OR如何实现&#xff1f; 图标表示…

Collagen

\ collagen XV/XVIII, Endostatin- angiogenesis inhibitor; c-type lectin 结构&#xff1b; TSP ( 含有 Laminin-G)

BIT.8_Linux 多线程

lesson35: 一、 1.OS调度的基本单位&#xff08;0&#xff1a;13&#xff1a;5&#xff09; 2.进程XXXX&#xff08;0&#xff1a;14&#xff1a;15&#xff09; a.进程的内核数据结构包含哪几个部分&#xff1f;&#xff08;n个&#xff09;&#xff08;0&#xff1a;15&a…

openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT

文章目录 openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT88.1 前置条件检查88.2 转换88.3 转换示例 openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT …

MQTT 服务器搭建(基于mosquitto)

1、前言 MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&#xff09;模式的"轻量级"通讯协议&#xff0c;该协议构建于TCP/IP协议上&#xff0c;…

Vue项目搭建图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 预备工作 请在本地创建文件夹用于存放Vue项目&#xff0c;例如&#xff1a;创建HelloWorld文件夹存放即将创建的Vue新项目。 创建Vue项目 首先&#xff0c;请在DOS中将目录…

八大排序源码(含优化)

文章目录 1、直接插入排序2、希尔排序3、选择排序4、冒泡排序5、堆排序6、快速排序快速排序递归实现霍尔法挖坑法前后指针法快速排序小区间优化 快速排序非递归实现 7、归并排序归并排序递归实现归并排序非递归 8、计数排序 大家好&#xff0c;我是纪宁&#xff0c;这篇文章是关…

[Realtek sdk-3.4.14b]RTL8197FH-VG 2.4G to WAN吞吐量低于60%的问题分析及解决方案

问题描述 RTL8197FH-VG 2.4G wifi to WAN吞吐量低于65%的标准,正常2T2R的wifi 300Mbps x 65% = 195Mbps,但是实际只能跑到160Mbps,这个时候CPU的idl已经为0,sirq占用率达到98%左右 网络拓扑 一台PC通过2.4G WiFi连接到RTL8197FH-VG,另外一台PC直接通过WAN口连接到RTL8197…

【pwn入门】用gdb实现第1个pwn

声明 本文是B站你想有多PWN学习的笔记&#xff0c;包含一些视频外的扩展知识。 有问题的源码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> char sh[]"/bin/sh"; int func(char *cmd){system(cmd);return 0; }int main(){char …

MongoDB快速上手

文章目录 1、mongodb相关概念1.1、业务应用场景1.2、MongoDB简介1.3、体系结构1.3.1 数据库 (databases) 管理语法1.3.2 集合 (collection) 管理语法 1.4、数据模型1.5、MongoDB的特点 2、单机部署3、基本常用命令3.1、案例需求3.2、数据库操作3.2.1 选择和创建数据库3.2.2 数据…

新一代网络框架UringNet,基于最新的异步I/O

介绍 在去年的一篇文章中&#xff0c;笔者曾经提到了最新一代的网络I/O框架UringNet。具体内容可以参考Rings’ Power,性能“世界第一”的Web I/O框架。这是基于最新Linux内核的异步I/O组件io_uring开发的网络框架。由于采用了最新的异步框架&#xff0c;因此在同等硬件配置条件…

漏洞扫描环境:win10系统用VMware Workstation打开虚拟机若干问题

win10系统用VMware Workstation打开虚拟机若干问题 一 .VMware打开虚拟机就蓝屏重启怎么解决&#xff1f;一. VMware打开虚拟机就蓝屏重启怎么解决&#xff1f;方法一&#xff1a;1、同时按下CTRLSHIFTESC打开任务管理器功能&#xff0c;之后依次点击-详细信息-性能后出现下列界…

辅助驾驶功能开发-测试篇(2)-真值系统介绍

1 真值系统概述 1.1 真值评测系统核心应用 快速构建有效感知真值,快速完成感知性能评估,快速分析感知性能缺陷。 主要应用场景包括: 1. 感知算法开发验证: 在算法开发周期中,评测结果可以作为测试报告的一部分,体现算法性能的提升。 2. 遴选供应…

九、2023.10.3.Linux(end).9

文章目录 33、简述mmap的原理和使用场景&#xff1f;34、互斥量能不能在进程中使用&#xff1f;35、协程是轻量级线程&#xff0c;轻量级表现在哪里&#xff1f;36、说说常见信号有哪些&#xff0c;表示什么含义&#xff1f;37、说说线程间通信的方式有哪些&#xff1f;38、说说…

【Java 进阶篇】JDBC查询操作详解

在数据库编程中&#xff0c;查询是一项非常常见且重要的操作。JDBC&#xff08;Java Database Connectivity&#xff09;提供了丰富的API来执行各种类型的查询操作。本篇博客将详细介绍如何使用JDBC进行查询操作&#xff0c;包括连接数据库、创建查询语句、执行查询、处理结果集…

python——Django框架

一、基本介绍 Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 使用 Django&#xff0c;只要很少的代码&#xff0c;Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容&#xff0c;并进一步开发出全功能的 Web 服务 Django 本身基于 MVC …