C语言中的函数(超详细)

C语言中的函数(超详细)

    • 一、函数概述
    • 二、C语言中函数的分类
    • 1.库函数
    • 2.自定义函数
    • 三、函数的参数
    • 1.实际参数(实参)
    • 2.形式参数(形参)
    • 四、函数的调用
    • 1.传值调用
    • 2.传址调用
    • 五、函数的嵌套调用和链式访问
    • 1.嵌套调用
    • 2.链式访问
    • 六、函数的声明和定义
    • 1.函数声明
    • 2. 函数定义
    • 七、函数递归

  • 🎈个人主页:库库的里昂
  • 🎐CSDN新晋作者
  • 🎉欢迎 👍点赞✍评论⭐收藏
  • ✨系列专栏C语言初阶、代码小游戏
  • 🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗

【前言】

函数是指将一组能完成一个功能或多个功能的语句放在一起的代码结构。在C语言程序中,至少会包含一个函数,及主函数main()。本章将详细讲解关于函数的相关内容。

一、函数概述

我们都知道函数是数学里的重要组成部分,数学中我们常见到函数的概念,但是你了解C语言中的函数吗?
其实函数就相当于一个子程序,那什么是子程序呢?

  • 在计算机科学中,子程序是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。
  • 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库

二、C语言中函数的分类

1.库函数

1.1什么是库函数?

其实库函数就是存放在函数库中的函数,具有明确的功能、入口调用参数和返回值。下面举一些例子:

  1. 我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格式打印到屏幕上(printf)。
  2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)。
  3. 在编程是我们也计算,总是会计算n的k次方这样的运算(pow)。

1.2库函数是C语言提供的吗?

不是,C语言标准中约定好,由编译器的厂商提供实现。

1.3为什么会有库函数呢?

像上面我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员
进行软件开发。

1.4那怎么学习库函数呢?

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

这里我给大家推荐一个可以很好查到有关库函数的网站链接:可查到库函数资料

简单的总结,C语言常用的库函数都有:

  • IO函数
  • 字符串操作函数
  • 字符操作函数
  • 内存操作函数
  • 时间/日期函数
  • 数学函数
  • 其他库函数

注!!!
库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件。

2.自定义函数

如果库函数能干所有的事情,那还要程序员干什么?
所有更加重要的是自定义函数!!!
自定义函数和库函数一样,有函数名,返回值类型和函数参数。
所谓自定义就是这些都是我们自己来设计。这给我们自己一个很大的发挥空间!!!

函数的组成:
我们举一个例子:写一个函数可以找出两个整数中的最大值。

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
	return (x > y) ? (x) : (y);//三目运算符:x大于y返回x,x小于y返回y
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int max = get_max(num1, num2);
	printf("max = %d\n", max);
	return 0}

这里我们输入a=10 b=20结果是
在这里插入图片描述
正确的,说明我们自己定义的函数还是比较成功的哈👏
上面可以看到,我们定义的一个函数get_max()是为了得到一个最大值,而get max也能理解为这个意思,由此可以看出咱们在定义函数的时候取的名字尽量要有意义,不然别人读你的代码根本不知道你这写的什么函数,你要知道,我们写代码是要给别人看的,你总不能写个乱七八糟的函数,让你写东你写个西在上面,你让别人怎么看呀,是不是。所以还是要考虑别人的感受!!!
扯远了哈,咱们继续

三、函数的参数

1.实际参数(实参)

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

比如上面的例子:get_max(num1, num2)中num1和num2就是实参

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

get_max(3, 5)
get_max(num1, 8)
get_max(num1, 8+2)
get_max(num1, get_max(3,5))//链式结构,后面我们会讲到

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

就是实参不能是变量

2.形式参数(形参)

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

比如上面中的get_max(int x, int y),其中xy就是形式参数。
我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝。

四、函数的调用

1.传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
比如get_max()函数,它只是求出两个数中的最大值,没有改变参数内部的数值,所以用的是传值调用。

2.传址调用

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

举个例子:交换两个数的值

void Swap2(int*p1, int*p2)
{
	int tmp = 0;
	tmp = *p1;//tmp = a;
	*p1 = *p2;//a = b;
	*p2 = tmp;//b = tmp;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	printf("交换前:a = %d b = %d\n", a, b);
	Swap2(&a, &b);
	printf("交换后:a = %d b= %d\n", a, b);
	return 0;
}

这里我们输入a=10 b=20
在这里插入图片描述
说明我们定义的函数是对的,但是我们看上面Swap(&a,&b)中使用的是取地址a和取地址b,这是为什么呢?为什么不用Swap(a,b)呢?

好好好,这么问是吧,那我就只好回答你了!

因为我们需要的是交换a、b的值,仅仅使用传值调用的话只能改变实参的表面数值,而实参内部没有被传到形参,当形参执行函数时只带上了实参的数值,而形参内部还是形参本身,那么虽然输出的结果是符合要求的,但是内部功能可能会有差异。所以我们采用传址调用,这样我们把a、b的地址传到形参里面,形参就能根据地址输出我们想要的效果。这么说,你该懂了吧!那么能否奉上阁下的一件三连呢!不要辜负我的一番苦心啊!!!

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

1.嵌套调用

假如我们需要定义两个函数,分别为x函数和y函数

void x()
{
	
}
void y()
{
	x();
}
int main()
{
	y();
}

我只是举个例子来表示嵌套调用,你们可不要这么写哈。
注意!!!
函数可以嵌套调用,但是不能嵌套定义。

2.链式访问

把一个函数的返回值作为另外一个函数的参数

回到我们上面讲到的一个例子:get_max(num1, get_max(3,5)),这就是链式结构,以此类推可以放很多个函数在另一个函数的参数上面。

六、函数的声明和定义

1.函数声明

  • 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
    声明决定不了。
  • 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
  • 函数的声明一般要放在头文件中的。
    其实就是在使用函数前应该加上函数声明

例:

int get_max(int x, int y);//<font color = green>函数声明
int main()
{
	get_max(a,b);
}

加在最上面或者get_max(a,b)上面都可以。

2. 函数定义

函数的定义是指函数的具体实现,交待函数的功能实现。

例:

int get_max(int x, int y)
{
	return (x > y) ? (x) : (y);//三目运算符:x大于y返回x,x小于y返回y
}

这就是函数定义。

学习了函数声明和函数定义以后,我们是不是就知道怎么使用函数了,好,那我们就来写一道题:写一个函数,完成2个整数的相加
这里我们可以创建一个函数Add(),它要完成两个数相加,那么函数就可已定义为:

int Add(int x, int y)
{
	return x + y;
}

函数声明为:

int Add(int x, int y);

那么我们就可以开始写这个程序,代码就是

#include<stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int Add(int x, int y);
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int ret = Add(a, b);
	printf("%d\n", ret);
	return 0;
}

输入a=10 b=20
运行结果:
在这里插入图片描述
到这里你是不是觉得没什么问题,确实没什么问题哈。
但事实上,在工程里面是这样用的吗?
如果你只是写一个文件的话,这样写是没有任何问题的。
但是我们未来在工程中,代码是比较多的,如果还是用我们上面这种方法的话,那可就太繁琐了,所以,我们的函数一般是放在.h文件中声明,在.c文件中实现的!

下面我给大家来演示一遍(VS2019)

  1. 新建一个头文件add.h
    在这里插入图片描述
    因为头文件是进行函数的声明,所以在头文件中输入函数声明

在这里插入图片描述

  1. 新建两个源文件add.c和test.c
    在这里插入图片描述
    add.c里面用来定义我们的函数

在这里插入图片描述

test.c是我们自己输入跑程序要用的代码

当我们需要用到Add()函数时,只要在前面加上一个#include"add.h"

在这里插入图片描述
程序跑起来就是这个样子
在这里插入图片描述

  • 这样看着很复杂的样子,但在一个较大的工程里面是需要多人协作的,而我们这样是合理分配了各自的工作。
  • 比如三个人来做一个工程,总不可能一个做累了另一个接着做吧,这时就应该三个人分别来做add.h、add.c、test.c,这样是不是就能加快咱们的效率。

七、函数递归

对于初学者而言函数递归是比较难啃的一块,所以本库打算后面单独发一篇文章来教大家学习递归。

今天超级详细的C语言中的函数就分享到这里啦!希望各位多多点赞收藏评论!!你的支持是我最大的动力!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念&#xff1a; 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面&#xff0c;以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计&#xff0c;旨…

基于Java+SpringBoot+vue前后端分离新闻推荐系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

第五章 传输层

第五章 传输层 5.1 运输层的功能 运输层功能&#xff1a; 运输层为应用进程之间提供 端到端的逻辑通信&#xff08;但网络层是为主机之间提供逻辑通信&#xff09;。 运输层还要对收到的报文进行差错检测。 运输层提供面向连接和无连接的服务 ​ 从通信和信息处理的角度看…

linux V4L2子系统——v4l2架构(1)之整体架构

概述 V4L&#xff08;Video for Linux&#xff09;是Linux内核中关于视频设备的API接口&#xff0c;涉及视频设备的音频和视频信息采集及处理、视频设备的控制。V4L出现于Linux内核2.1版本&#xff0c;经过修改bug和添加功能&#xff0c;Linux内核2.5版本推出了V4L2&#xff08…

基于包围框回归的目标检测网络原理及Tensorflow实现

对象检测是对图像内的对象进行分类和定位。 换句话说&#xff0c;它是图像分类和对象定位的结合。 构建用于图像分类的机器学习模型更简单&#xff0c;我在我的一篇文章中对此进行了描述。 然而&#xff0c;图像分类器无法准确判断对象在图像内的位置。 为了实现这一目标&#…

全光谱对眼睛视力好不好?全光谱对眼睛的影响

什么是全光谱&#xff1f;全光谱指的是光谱中包含紫外光、可见光、红外光的光谱曲线&#xff0c;并且在可见光部分中红绿蓝的比例与阳光近似&#xff0c;显色指数Ra接近于100的光谱。与普通LED相比&#xff0c;全光谱LED光谱更加连续&#xff0c;色域更广泛。简单来说&#xff…

【javaSE】初识Java

目录 Java是什么 Java语言发展简史 初识Java的main方法 运行Java程序 JDK、JRE、JVM之间的关系 Java中的标识符 Java是什么 Java是一种优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语义. 不仅如此&#xff0c;Java还是一个有一系列计算机软件和规…

K8s使用Ceph作为后端存储

Ceph概述 部署Ceph集群 Ceph存储使用 Pod使用Ceph持久化数据 Ceph监控 Rook部署Ceph Ceph概述 Ceph介绍 Ceph架构 Ceph核心概念 Ceph介绍 Ceph是一个开源的分布式存储系统&#xff0c;具有高扩展性、高性能、高可靠性等特点&#xff0c;提 供良好的性能、可靠性和可扩展性。…

2023 数字生态发展大会,和鲸 ModelWhale 入选中国信通院“铸基计划”《高质量数字化转型产品及服务全景图》

7月27日&#xff0c;由中国信通院主办的“2023数字生态发展大会”暨中国信通院“铸基计划”年中会议在北京召开。本次大会重磅发布了《高质量数字化转型产品及服务全景图&#xff08;2023&#xff09;》&#xff0c;和鲸科技旗下数据科学协同平台 ModelWhale 成功入选&#xff…

【论文阅读】DEPIMPACT:反向传播系统依赖对攻击调查的影响(USENIX-2022)

Fang P, Gao P, Liu C, et al. Back-Propagating System Dependency Impact for Attack Investigation[C]//31st USENIX Security Symposium (USENIX Security 22). 2022: 2461-2478. 攻击调查、关键边、入口点 开源&#xff1a;GitHub - usenixsub/DepImpact 目录 1. 摘要2. 引…

深度学习入门教学——神经网络

深度学习就是训练神经网络。 1、神经网络 举个最简单的例子&#xff0c;以下是一个使用线性回归来预测房屋价格的函数。这样一个用于预测房屋价格的函数被称作是一单个神经元。大一点的神经网络&#xff0c;就是将这些单个神经元叠加起来。例如&#xff1a;神经网络根据多个相…

如何往MySQL中插入100万条数据?

需求 现在有一个 数据量 为100万的数据样本 100w_data.sql 其数据格式如下&#xff0c;截取最后十条数据 999991,XxGdnLZObA999991,XxGdnLZObA,XxGdnLZObA,2020-3-18,1 999992,TBBchSKobC999992,TBBchSKobC,TBBchSKobC,2020-9-8,2 999993,rfwgLkYhUz999993,rfwgLkYhUz,rfwgLk…

重发布及路由策略

目录 重发布 作用 条件 规则 名词解释点 点 向 单点重发布 双点重发布 路由策略 控制层流量和数据层流量 抓流量 ACL列表 前缀列表( ip-prefix) 实例演示 做策略 过滤策略(过滤器-策略) 路由策略(route-policy) 基本配置 路由策略使用 配置实验 重发布 在…

3、线性数据结构

线性数据结构&#xff0c;从名字可以看出&#xff0c;和“线”脱离不了关系。 那么从“线”联想&#xff0c;水平的&#xff0c;我们可以想到食堂打饭排的队伍&#xff0c;垂直的&#xff0c;我们可以联想到书桌上层叠摆放的书籍。 打饭的队伍一般遵循“先来先服务”的原则&a…

低成本32位单片机空调内风机方案

空调内风机方案主控芯片采用低成本32位单片机MM32SPIN0230&#xff0c;内部集成了具有灵动特色的电机控制功能&#xff1a;高阶4路互补PWM、注入功能的高精度ADC、轨到轨运放、轮询比较器、32位针对霍尔传感器的捕获时钟、以及硬件除法器和DMA等电机算法加速引擎。 该方案具有…

Windows 不同方式打开的cmd/dos窗口属性配置不同

文章目录 1. 默认值&#xff08;控制台窗口&#xff09;属性2. "C:\Windows\System32\cmd.exe" 属性3. "命令提示符"属性4. 自定义某标题cmd窗口属性5. cmd快捷方式的属性总结 最近在写某个批处理脚本时&#xff0c;意外发现 Windows系统中&#xff0c;在不…

通过cmake工程生成visual studio解决方案

1、前言 visual studio是一个很强大的开发工具&#xff0c;这个工具主要是通过解决方案对我们的源码进行编译等操作。但是我们很多时候拿到的可能并不是一个直接的解决方案&#xff0c;可能是是一个cmake工程&#xff0c;那么这个时候我们就需要通过cmake工程生成解决方案&…

三元运算符引发的自动拆装箱问题

文章目录 问题背景问题排查排查过程问题扩展总结 问题背景 生产环境上出现空指针异常&#xff0c;追踪报错位置得知以下代码报错 if (isNull(aiGroup)) {return null;}aiGroup.setNum(isNull(param.getNum()) ? aiGroup.getNum() : param.getNum().doubleValue());问题排查 …

【C语言】文件操作重点内容梳理

本文目录 1. 什么是文件 1.1 程序文件 1.2 数据文件 1.3 文件名 2. 文件的打开和关闭 2.1 文件指针 2.2 文件的打开和关闭 3. 文件的顺序读写 3.1 顺序读写函数介绍 4. 文件的随机读写 4.1 fseek 4.2 ftell 4.3 rewind 5. 文本文件和二进制文件 6. 文件读取结束的判定 6.1 被错…

Bert经典变体学习

ALBert ALBERT就是为了解决模型参数量大以及训练时间过长的问题。ALBERT最小的参数只有十几M, 效果要比BERT低1-2个点&#xff0c;最大的xxlarge也就200多M。可以看到在模型参数量上减少的还是非常明显的&#xff0c;但是在速度上似乎没有那么明显。最大的问题就是这种方式其实…