C语言 -- 函数
C语言 -- 函数
- 1. 函数的概念
- 2. 库函数
- 2.1 标准库和头文件
- 2.2 库函数的使用方法
- 2.2.1 功能
- 2.2.2 头文件包含
- 2.2.3 实践
- 2.2.4 库函数文档的一般格式
- 3. 自定义函数
- 3.1 函数的语法形式
- 3.2 函数的举例
- 4. 形参和实参
- 4.1 实参
- 4.2 形参
- 4.3 实参和形参的关系
- 5. return 语句
- 6. 数组做函数参数
- 7. 嵌套调⽤和链式访问
- 7.1 嵌套调用
- 7.2 链式访问
1. 函数的概念
数学中我们其实就见过函数的概念,比如:一次函数 y=kx+b ,k和b都是常数,给一个任意的x,就得到一个y值。
其实在C语言也引入函数(function)的概念,有些翻译为:子程序,子程序这种翻译更加准确一些。C语言中的函数就是⼀个完成某项特定的任务的一小段代码。这段代码是有特殊的写法和调用方法的。C语言的程序其实是由无数个小的函数组合而成的,也可以说:一个大的计算任务可以分解成若若个较小的函数(对应较小的任务)完成。同时一个函数如果能完成某项特定任务的话,这个函数也是可以复的用,提升了开发软件的效率。
在C语言中我们一般会见到两类函数:
- 库函数 – 是现成的,可以直接使用的函数
- 自定义函数 – 是根据需要,自己设计和创造的函数
2. 库函数
2.1 标准库和头文件
- C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSI C规定了一些常用的函数的标准,被称为标准库,那不同的编译器厂商根据ANSI提供的C语言标准就给出了一系列函数的实现。这些函数就被称为库函数。
- 我们前面内容中学到的 printf 、 scanf 都是库函数,库函数的也是函数,不过这些函数已经是现成的,我们只要学会就能直接使用了。有了库函数,一些常见的功能就不需要程序员自己实现了,一定程度提升了效率;同时库函数的质量和执行效率上都更有保证。
- 各种编译器的标准库中提供了一系列的库函数,这些库函数根据功能的划分,都在不同的头文件中进行了声明。
- 库函数相关头文件:https://zh.cppreference.com/w/c/header
2.2 库函数的使用方法
库函数的学习和查看工具很多,比如:
C/C++官方的链接:https://zh.cppreference.com/w/c/header
cplusplus.com:https://legacy.cplusplus.com/reference/clibrary/
举例:sqrt
2.2.1 功能
Compute square root 计算平方根
Returns the square root of x.(返回平方根)
2.2.2 头文件包含
库函数是在标准库中对应的头文件中声明的,所以库函数的使用,务必包含对应的头文件,不包含是可能会出现⼀些问题的。
2.2.3 实践
2.2.4 库函数文档的一般格式
- 函数原型
- 函数功能介绍
- 参数和返回类型说明
- 代码举例
- 代码输出
- 相关知识链接
3. 自定义函数
了解了库函数,我们的关注度应该聚焦在自定义函数上,自定义函数其实更加重要,也能给程序员写代码更多的创造性。
3.1 函数的语法形式
其实自定义函数和库函数是一样的,形式如下:
- ret_type 是函数返回值的类型
- fun_name 是函数名
- 括号中放的是形式参数
- {}括起来的是函数体
我们可以把函数想象成小型的一个加工厂,工厂得输⼊原材料,经过工厂加工才能生产出产品,那函数也是⼀样的,函数一般会输入一些值(可以是0个,也可以是多个),经过函数内的计算,得出结果。
- ret_type 是用来表示函数计算结果的类型,有时候返回类型可以是 void ,表示什么都不返回。
- fun_name 是为了方便使用函数;就像人的名字一样,有了名字方便称呼,函数有了名字方便调用,所以函数名尽量要根据函数的功能起的有意义。
- 函数的参数就相当于,工厂中送进去的原材料,函数的参数也可以是 void ,明确表示函数没有参数。如果有参数,要交代清楚参数的类型和名字,以及参数个数。
- {}括起来的部分被称为函数体,函数体就是完成计算的过程。
3.2 函数的举例
写一个加法函数,完成2个整型变量的加法操作。
Add函数也可以简化为:
函数的参数部分需要交代清楚:参数个数,每个参数的类型是啥,形参的名字叫啥。
上面只是⼀个例子,未来我们是根据实际需要来设计函数,函数名、参数、返回类型都是可以灵活变化的。
4. 形参和实参
在函数使用的过程中,把函数的参数分为,实参和形参。
再看看我们前面写的代码:
4.1 实参
如上图:调用Add函数时,传递给函数的参数a和b,称为实际参数,简称实参。实际参数就是真实传递给函数的参数。
4.2 形参
如上图:定义函数的时候,在函数名 Add 后的括号中写的 x 和 y ,称为形式参数,简
称形参。
为什么叫形式参数呢?实际上,如果只是定义了 Add 函数,而不去调用的话, Add 函数的参数 x和 y 只是形式上存在的,不会向内存申请空间,不会真实存在的,所以叫形式参数。形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形式的实例化。
4.3 实参和形参的关系
虽然我们提到了实参是传递给形参的,他们之间是有联系的,但是形参和实参各自是独立的内存空间。
这个现象是可以通过调试来观察的。请看下面的代码和调试演示:
下面是在VS2022 X86环境调试的
我们在调试的可以观察到,x和y确实得到了a和b的值,但是x和y的地址和a和b的地址是不一样的,所以我们可以理解为形参是实参的一份临时拷贝。
5. return 语句
在函数的设计中,函数中经常会出现return语句,这里讲⼀下return语句使用的注意事项。
• return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执行表达式,再返回表达式的结果。
• return后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是void的情况。
• return返回的值和函数返回类型不⼀致,系统会自动将返回的值隐式转换为函数的返回类型。
• return语句执行后,函数就彻底返回,后边的代码不再执行。
• 如果函数中存在if等分支的语句,则要保证每种情况下都有return返回,否则会出现编译错误。
- 函数的返回类型如果什么都不写,默认函数的类型是int.
6. 数组做函数参数
在使用函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进行操作。
比如:写一个函数对将一个整型数组的内容,全部置为-1,再写⼀个函数打印数组的内容。
根据上述的信息,我们就可以实现这两个函数:
图示:
代码如下:
#include <stdio.h>
void set_arr(int arr2[], int sz2)
{int i = 0;for (i = 0; i < sz2; i++){arr2[i] = -1;}
}void print_arr(int arr[],int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz1 = sizeof(arr1) / sizeof(arr1[0]);print_arr(arr1, sz1);//打印数组的所有内容set_arr(arr1, sz1);//将数组的元素全部设置为-1print_arr(arr1, sz1);//打印数组的所有内容return 0;
}
7. 嵌套调⽤和链式访问
7.1 嵌套调用
嵌套调⽤就是函数之间的互相调用,每个函数就行一个乐高零件,正是因为多个乐高的零件互相⽆缝的配合才能搭建出精美的乐高玩具,也正是因为函数之间有效的互相调用,最后写出来了相对大型的程序。
假设我们计算某年某月有多少天?,如果要函数实现,可以设计2个函数:
• is_leap_year():根据年份确定是否是闰年
• get_days_of_month():调用is_leap_year确定是否是闰年后,再根据月计算这个月的天数
这⼀段代码,完成了⼀个独立的功能。代码中反应了不少的函数调用:
• main 函数调⽤ scanf 、 printf 、 get_days_of_month
• get_days_of_month 函数调⽤ is_leap_year
未来的稍微大一些代码都是函数之间的嵌套调用,但是函数是不能嵌套定义的。
7.2 链式访问
所谓链式访问就是将一个函数的返回值作为另外一个函数的参数,像链条一样将函数串起来就是函数的链式访问。
前面的代码完成动作写了2条语句,把如果把strlen的返回值直接作为printf函数的参数呢?这样就是一个链式访问的例子了。
在看⼀个有趣的代码,下⾯代码执行的结果是什么呢?
这个代码的关键是明白printf 函数的返回是啥?
printf函数返回的是打印在屏幕上的字符的个数。
上面的例子中,我们就第一个printf打印的是第二个printf的返回值,第而个printf打印的是第三个printf的返回值。
第三个printf打印43,在屏幕上打印2个字符,再返回2
第⼆个printf打印2,在屏幕上打印1个字符,再放回1
第⼀个printf打印1
所以屏幕上最终打印:4321
再看下面一个例子:
相关文章:

C语言 -- 函数
C语言 -- 函数 1. 函数的概念2. 库函数2.1 标准库和头文件2.2 库函数的使用方法2.2.1 功能2.2.2 头文件包含2.2.3 实践2.2.4 库函数文档的一般格式 3. 自定义函数3.1 函数的语法形式3.2 函数的举例 4. 形参和实参4.1 实参4.2 形参4.3 实参和形参的关系 5. return 语句6. 数组做…...

Cesium 立式雷达扫描
Cesium 立式雷达扫描 自定义 Primitive 实现支持水平和垂直交替扫描...

Oracle HTTP Server(OHS)与Oracle数据库的紧密绑定
Oracle HTTP Server(OHS)与Oracle数据库的紧密绑定通常是通过一系列的配置和集成步骤来实现的。以下是这些步骤的详细归纳,包括必要的分点表示和参考信息: 一、安装和配置Oracle HTTP Server 安装OHS: 在安装Oracle…...

mmcv安装失败及解决方案
假如想安装的版本是mmcv1.4.0, 但是pip install mmcv1.4.0总是失败,若是直接pip install mmcv会安装成功,但是安装的就是最新版本,后面代码跑起来还会报错,怎么办呢? 接下来分享一个mmcv指定版本安装的方式。 网页&a…...

国产强大免费WAF, 社区版雷池动态防护介绍
雷池WAF,基于智能语义分析的下一代 Web 应用防火墙 使用情况 我司于2023年4月23日对雷池进行测试,测试一个月后,于2023年5月24日对雷池进行正式切换,此时版本为1.5.1。 里程碑纪念 后续一直跟随雷池进行版本升级,当前…...

【Django】网上蛋糕项目商城-首页
概念 本文在上一文章搭建完数据库,以及创建好项目之后,以及前端静态文件后,对项目的首页功能开发。 后端代码编写 在views.py文件中创建方法,连接数据库,并获取首页需要的数据 def getGoodsList(type):# 获取所有横…...

Vue 父子页面使用指南
Vue3父子页面使用指南 Vue3作为一种现代化的前端框架,提供了强大的组件化功能,使得页面开发更加模块化和可维护。本文将深入探讨Vue3中父子页面的使用方法,包括如何传递参数、父组件如何调用子组件的方法,以及父子页面的加载原理…...

TVBox自定义配置+软件密码版本
apk地址 : https://gitee.com/wheat-wheat/kekeda-duck-apk 1、安装安卓SDK Android SDK Windows 安装及环境配置教程_sdk manager windows-CSDN博客 修改点: 基础配置: java版本:...

Java单体架构项目_云霄外卖-特殊点
项目介绍: 定位: 专门为餐饮企业(餐厅、饭店)定制的一款软件商品 分为: 管理端:外卖商家使用 用户端(微信小程序):点餐用户使用。 功能架构: (…...

一文搞懂 java 线程池:ScheduledThreadPool 和 WorkStealingPool 原理
你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…...

轮换IP是什么?——深入了解轮换IP的特点
大家在日常上网时,可能听说过“轮换IP”这个词。那么,轮换IP到底是什么?它有哪些特点?今天,我们就来揭开轮换IP的神秘面纱。 什么是轮换IP? 简单来说,轮换IP是指定期更换上网时使用的IP地址。…...

中英双语介绍美国的州:华盛顿州(Washington)
中文版 华盛顿州简介 华盛顿州(Washington)位于美国太平洋西北地区,以其壮丽的自然景观和蓬勃发展的经济闻名。以下是对华盛顿州的详细介绍,包括其地理位置、人口、经济、教育、文化和主要城市。 地理位置 华盛顿州北接加拿大…...

美工画师必看!AI绘画Stable Diffusion 一键生成 B 端图标教程,轻松制作商业可用的设计图标,从此告别加班!(附安装包)
大家好,我是画画的小强 在日常工作中,设计师在应对运营和UI设计的B端图标时,常常面临大量的构思、制作和渲染等工作,耗时耗力。我们可以利用Stable Diffusion(以下简称SD)结合AI的方式,帮助设计师优化图标的设计流程&…...

使用表单系统快速搭建邀请和签到系统
在组织活动时,邀请和签到环节往往是活动成败的关键之一。传统的纸质邀请和签到方式不仅费时费力,还容易出现各种问题,例如名单遗漏、签到混乱等。而使用TDuckX“搭建邀请和签到系统”将彻底改变这一现状,为活动组织者提供了一种高…...

Vue 3 入门与精通:为初学者打造的全面学习指南
引言: Vue.js,这款由尤雨溪创建的轻量级前端框架,以其简洁的API、双向数据绑定和组件化的开发模式,深受广大开发者喜爱。Vue 3 的发布,带来了更多的性能优化和功能增强,为开发者提供了更广阔的空间。本文旨…...

React+TS前台项目实战(二十四)-- 全局常用绘制组件Qrcode封装
文章目录 前言Qrcode组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示(pc端 / 移动端) 总结 前言 今天要封装的Qrcode 组件,是通过传入的信息,绘制在二维码上,可用于很多场景,如区块链项目中的区块显示交易地址时就可以用到…...

寄5公斤哪个快递便宜?寄10多斤的物品怎么寄最划算?
作为一个频繁需要寄东西的大学生,每次选择快递公司都是一件头疼的事。尤其是寄5公斤左右的包裹,既要考虑价格,又要看服务质量。今天,我就来分享一些寄5公斤包裹省钱的干货,希望能帮到大家。云木寄快递首先要推荐的就是…...

【postgresql】索引
见的索引类型: B-tree 索引:这是最常用的索引类型,适用于大多数查询。B-tree索引可以高效地处理范围查询。 Hash 索引:适用于等值查询,但不支持范围查询。 GiST 索引:通用搜索树(GiST…...

2D Game Kit在unity的使用
本文参考: 如何制作游戏?【不需要编程 __】新手30分钟 学会制作2D游戏!_ 如何制作游戏 _ unity教学 _ 制作游戏 _ 2d游戏_哔哩哔哩_bilibili 1、下载2d game kit 新建一个unity工程,进入该工程后,在Window -> Ass…...

使用中国大陆镜像源安装最新版的 docker Deamon
在一个智算项目交付过程中,出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷,需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…...
机器学习原理之 -- 支持向量机分类:由来及原理详解
支持向量机(Support Vector Machine, SVM)是统计学习理论的一个重要成果,广泛应用于分类和回归问题。SVM以其高效的分类性能和良好的泛化能力在机器学习领域中占据重要地位。本文将详细介绍支持向量机的由来、基本原理、构建过程及其优缺点。…...

华为机试HJ8合并表记录
华为机试HJ8合并表记录 题目: 数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。 想法:…...

Leetcode 2043简易银行交易系统
题目描述 简易银行系统 尝试过 中等 相关标签 相关企业 提示 你的任务是为一个很受欢迎的银行设计一款程序,以自动化执行所有传入的交易(转账,存款和取款)。银行共有 n 个账户,编号从 1 到 n 。每个账号的初始余额存储…...

适合职场小白的待办事项管理方法和工具
刚入职场那会儿,我每天都像只无头苍蝇,忙得团团转却效率低下。待办事项像潮水般涌来,会议、报告、客户跟进……每一项都像是悬在头顶的利剑,让我焦虑不堪。我深知,管理好待办事项是职场生存的必修课,但该如…...

相机参数与图像处理技术解析
01. 相机内参和外参的含义?如果将图像放大两倍,内外参如何变化? 相机有两个最基础的数据:内参(Instrinsics)和外参(Extrinsics),内参主要描述的是相机的CCD/CMOS感光片尺寸/分辨率以及光学镜头的系数,外参主…...

Ubuntu20.04安装Prometheus监控系统
环境准备: 服务器名称内网IP公网IPPrometheus服务器192.168.0.23047.119.21.167Grafana服务器192.168.0.23147.119.22.8被监控服务器192.168.0.23247.119.22.82 更改主机名方便辨认 hostnamectl set-hostname prometheus hostnamectl set-hostname grafana hostn…...

kafka consumer客户端消费逻辑解析
kafka consumer客户端消费逻辑解析 一、主要步骤二、提交策略【步骤2代码解析】【提交策略总结】 三、拉取策略四、消费策略【代码解析】【消费策略总结】 一、主要步骤 这是kafka客户端拉取消息的入口,有4个主要部分 1、启动后的准备 consumer线程启动后ÿ…...

打印机出现多个副本无法删除
打印机出现多个副本很烦人,尤其是在打印机在局域网内被多个主机共享的时候,一旦出现新的副本,原有副本全都变成脱机状态,其他电脑连接的共享打印机是原来的副本,所以要重新设置打印机共享,很烦人。 想要删…...

FlinkSQL 开发经验分享
作者:汤包 最近做了几个实时数据开发需求,也不可避免地在使用 Flink 的过程中遇到了一些问题,比如数据倾斜导致的反压、interval join、开窗导致的水位线失效等问题,通过思考并解决这些问题,加深了我对 Flink 原理与机…...

JVM原理(十二):JVM虚拟机类加载过程
一个类型从被加载到虚拟机内存中开始,到卸载为止,它的整个生命周期将会经过 加载、验证、准备、解析、初始化、使用、卸载七个阶段。其中 验证、准备、解析三个部分统称为 连接 1. 加载 加载是整个类加载的一个过程。在加载阶段,Java虚拟机…...