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语言中的函数就分享到这里啦!希望各位多多点赞收藏评论!!你的支持是我最大的动力!!!

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

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

相关文章

X2Keyarch迁移工具实战 | 将CentOS高效迁移至浪潮云峦操作系统KeyarchOS

X2Keyarch迁移工具实战 | 将CentOS高效迁移至浪潮云峦操作系统KeyarchOS 1. 搭建仿真线上业务环境2. 安装KeyarchOS操作系统和X2Keyarch迁移工具3. 将CentOS系统业务迁移至KeyarchOS系统 浪潮信息云峦操作系统KeyarchOS基于Linux Kernel、OpenAnolis等开源技术自主研发的一款服…

Django 入门学习总结8-管理页面的生成

修改polls/admin.py文件为&#xff1a; from django.contrib import admin from .models import Choice, Question class ChoiceInline(admin.StackedInline): model Choice extra 3 class QuestionAdmin(admin.ModelAdmin): fieldsets [ (None, {&q…

【Linux】权限的理解和使用

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

智能座舱架构与芯片- (15) 测试篇 下

三、持续集成与交付 3.1 自动化编译框架 在智能座舱软件中&#xff0c;分为上层应用软件和底层软件。有些上层应用软件是与指令集平台无关的&#xff0c;例如Java应用程序等&#xff0c;它们对所运行的CPU平台没有依赖性&#xff0c;可以很好的适配当前平台进行执行。而在底层…

微服务学习|初识Docker、使用Docker、自定义镜像、DockerCompose、Docker镜像仓库

初识Docker 项目部署的问题 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题 依赖关系复杂&#xff0c;容易出现兼容性问题 开发、测试、生产环境有差异 Docker如何解决依赖的兼容问题的? 将应用的Libs (函数库)、Deps (依赖)配置与应用…

缓存雪崩、击穿、穿透及解决方案_保证缓存和数据库一致性

文章目录 缓存雪崩、击穿、穿透1.缓存雪崩造成缓存雪崩解决缓存雪崩 2. 缓存击穿造成缓存击穿解决缓存击穿 3.缓存穿透造成缓存穿透解决缓存穿透 更新数据时&#xff0c;如何保证数据库和缓存的一致性&#xff1f;1. 先更新数据库&#xff1f;先更新缓存&#xff1f;解决方案 2…

虚拟机里为什么桥接模式可以广播,NAT模式不能广播?

虚拟机里为什么桥接模式可以广播&#xff0c;NAT模式不能广播&#xff1f; 我们在虚拟机里做调试的时候&#xff0c;进场会遇到NAT广播包发不出&#xff0c;而桥接模式可以。下面是找到的资料。 在虚拟机网络配置中&#xff0c;桥接模式&#xff08;Bridged mode&#xff09;允…

Android组件化搭建学习

什么是组件化&#xff1f; 为什么要用组件化&#xff1f;在项目的开发过程中&#xff0c;随着开发人员的增多及功能的增加&#xff0c;如果提前没有使用合理的开发架构&#xff0c;那么代码会越来臃肿&#xff0c;功能间代码耦合也会越来越严重&#xff0c;这时候为了保证项目…

Redisson分布式锁源码解析

一、使用Redisson步骤 Redisson各个锁基本所用Redisson各个锁基本所用Redisson各个锁基本所用 二、源码解析 lock锁 1&#xff09; 基本思想&#xff1a; lock有两种方法 一种是空参 另一种是带参 * 空参方法&#xff1a;会默认调用看门狗的过期时间30*1000&…

JMeter压测常见面试问题

1、JMeter可以模拟哪些类型的负载&#xff1f; JMeter可以模拟各种类型的负载&#xff0c;包括但不限于Web应用程序、API、数据库、FTP、SMTP、JMS、SOAP / RESTful Web服务等。这使得JMeter成为一个功能强大且灵活的压力测试工具。 2、如何配置JMeter来进行分布式压力测试&a…

防爆智能安全帽、防爆手持终端,防爆智能矿灯守护安全,在煤矿安全生产远程可视化监管中的应用

煤矿安全新守护&#xff1a;如何通过防爆智能装备实现远程可视化监管 煤矿是国民经济的重要支柱产业&#xff0c;但长期以来&#xff0c;安全生产事故的频发一直是困扰煤矿行业发展的严峻问题。安全生产事故不仅危及矿工的生命安全&#xff0c;也对企业和地方经济造成了重大的…

驯服大数据的超强利器——PySpark数据处理引擎

你是否曾经为了处理大规模数据而烦恼&#xff1f;是否曾经为了解决日常的数据科学挑战而彻夜难眠&#xff1f;现在&#xff0c;Spark数据处理引擎正在向你敞开大门。这是一个惊人的分析工厂&#xff0c;输入原始数据&#xff0c;输出洞察。 PySpark&#xff0c;作为Spark的核心…

壹基金宣传进瑞金河背街社区 安全家园项目防灾减灾深入人心

11月16日下午&#xff0c;瑞金赋能公益、蓝天救援队等联合象湖镇河背街社区开展家庭安全计划社区活动包挑战赛活动暨壹基金安全家园项目防灾减灾宣传社区行活动。活动得到了救助儿童会北京代表处、壹基金、艾特公益、益心益意公益的指导&#xff0c;得到了阿里巴巴公益平台广大…

服务器 jupyter 文件名乱码问题

对于本台电脑&#xff0c;autodl服务器&#xff0c;上传中文文件时&#xff0c;从压缩包名到压缩包里的文件名先后会出现中文乱码的问题。 Xftp 首先是通过Xftp传输压缩包到Autodl服务器&#xff1a; 1、打开Xftp&#xff0c;进入软件主界面&#xff0c;点击右上角【文件】菜…

C++设计模式之工厂模式(上)——简单工厂模式

工厂模式 概述简单工厂模式介绍示例示例使用运行结果缺点 概述 工厂模式属于一种创建型设计模式。其可以分为简单工厂模式&#xff0c;工厂模式和抽象工厂模式。工厂模式分为上、中、下三篇&#xff0c;本篇主要介绍简单工厂模式。 简单工厂模式 介绍 简单工厂模式可以理解…

竞赛选题 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…

二百零七、Flume——Flume实时采集5分钟频率的Kafka数据直接写入ODS层表的HDFS文件路径下

一、目的 在离线数仓中&#xff0c;需要用Flume去采集Kafka中的数据&#xff0c;然后写入HDFS中。 由于每种数据类型的频率、数据大小、数据规模不同&#xff0c;因此每种数据的采集需要不同的Flume配置文件。玩了几天Flume&#xff0c;感觉Flume的使用难点就是配置文件 二、…

【电路笔记】-星三角变换(Star-Delta Transformation)

星三角变换&#xff08;Star-Delta Transformation&#xff09; 文章目录 星三角变换&#xff08;Star-Delta Transformation&#xff09;1、概述1.1 单相配置1.2 多相配置 2、三相连接2.1 Y配置2.2 Δ配置 3、Y-Δ 和 Δ-Y 变换3.1 Y-Δ变换3.2 Δ-Y变换3.3 应用 4、总结 本文…

2023年DevOps国际峰会暨BizDevOps企业峰会(DOIS北京站)-核心PPT资料下载

一、峰会简介 在数字化转型的大背景下&#xff0c;企业选择实践 DevOps 来提升 IT 效能成为常态&#xff0c;BizDevOps 作为企业自身数字化变革的重要主题之一&#xff0c;需要全行业共同努力促进繁荣和发展。从 DevOps 到 BizDevOps&#xff0c;业务与技术如何融合&#xff1…

大模型的交互能力

摘要&#xff1a; 基础大模型显示出明显的潜力&#xff0c;可以改变AI系统的开发人员和用户体验&#xff1a;基础模型降低了原型设计和构建AI应用程序的难度阈值&#xff0c;因为它们在适应方面的样本效率&#xff0c;并提高了新用户交互的上限&#xff0c;因为它们的多模式和生…