函数的秘密

1. 函数的概念

在数学中我们学习过函数,而在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/

举例:

double sqrt (double x);
//sqrt 是函数名
//x 是函数的参数,表⽰调⽤sqrt函数需要传递⼀个double类型的值
//double 是返回值类型 - 表⽰函数计算的结果是double类型的值

对其具体展开介绍:

2.2.1 sqrt的功能

Compute square root 计算平⽅根
Returns the square root of x.(返回平⽅根)

2.2.2 头文件包含

库函数是在标准库中对应的头⽂件中声明的,所以库函数的使⽤,务必包含对应的头⽂件,不包含是可能会出现⼀些问题的。
库函数sqrt使用时,需头文件<math.h>进行声明。

2.2.3 sqrt实践

  求16的平方根

  代码示例:

#include <stdio.h>
#include <math.h>
int main()
{double d = 16.0;double r = sqrt(d);printf("%lf\n", r);return 0;
}

  运行结果:

2.2.4 库函数文档的一般格式

1. 函数原型
2. 函数功能介绍
3. 参数和返回类型说明
4. 代码举例
5. 代码输出
6. 相关知识链接

3. 自定义函数

了解了库函数,我们的关注度应该聚焦在⾃定义函数上,⾃定义函数其实更加重要,也能给程序员写代码更多的创造性

3.1 函数语法形式

ret_type fun_name(形式参数)
{}
//• ret_type 是函数返回类型
//• fun_name 是函数名
//• 括号中放的是形式参数
//• {}括起来的是函数体

下面形象具体的介绍一下:

我们可以把函数想象成⼩型的⼀个加⼯⼚,⼯⼚得输⼊原材料,经过⼯⼚加⼯才能⽣产出产品,那函数也是⼀样的,函数⼀般会输⼊⼀些值(可以是0个,也可以是多个),经过函数内的计算,得出结果。
ret_type 是⽤来表⽰函数计算结果的类型,有时候返回类型可以是 void ,表⽰什么都不返回。
fun_name 是为了⽅便使⽤函数;就像⼈的名字⼀样,有了名字⽅便称呼,函数有了名字⽅便  
,所以函数名尽量要根据函数的功能起的有意义
函数的参数就相当于⼯⼚中送进去的原材料,函数的参数也可以是 void ,明确表⽰函数没有参
数。如果有参数,要交代清楚参数的类型和名字,以及参数个数
{}括起来的部分被称为函数体,函数体就是完成计算的过程。

3.2 函数举例

写⼀个加法函数,完成2个整型变量的加法操作:
代码示例:
#include<stdio.h>
int add(int x, int y)//自定义加法函数
{int z = x + y;//函数体return z;//返回值
}
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int r = add(a, b);//函数调用printf("%d\n", r);return 0;
}

运行结果:

函数的参数部分需要交代清楚:参数个数,每个参数的类型是啥,形参的名字叫啥。
上⾯只是⼀个例⼦,未来我们是根据实际需要来设计函数,函数名、参数、返回类型都是可以灵活变化的。
下面我们介绍一下函数中的参数:

4. 函数中的参数

函数在使用的过程中,把函数的参数分为实参和形参

结合上述代码,简单介绍下。

4. 1  实参

定义好add函数后,进行调用,此时传递给函数的参数a和b称为实际参数,简称实参。

实际参数就是真实传递给函数的参数。

实参可能是变量,也可能是常量,也可能是宏,也可能是指针。

4.2 形参

定义函数add时,在函数名add后括号中写的x和y称为形式参数,简称形参。

为什么叫形式参数呢?实际上,如果只是定义了 a dd 函数,⽽不去调⽤的话, a dd 函数的参数 x y 只是形式上存在的不会向内存申请空间不会真实存在的,所以叫形式参数。形式参数只有在 函数被调⽤的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形式的实例化。

4.3 实参和形参的关系

1. 实参是传递给形参的,它们之间是有联系的,但是形参和实参各⾃是独⽴的内存空
间。
2. 形参是实参的一份临时拷贝。
3. 形参的修改不会影响实参。
学了一段时间的C语言,就会发现每一个完整的代码都有return语句,return语句在函数中也经常出现,下面讲一下return语句使用的注意事项:

5. return语句

return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执⾏表达式,再返回表达式的结果
return后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是void的情况。
return返回的值和函数返回类型不⼀致,系统会⾃动将返回的值隐式转换为函数的返回类型
return语句执⾏后,函数就彻底返回,后边的代码不再执⾏
如果函数中存在if等分⽀的语句,则要保证每种情况下都有return返回,否则会出现编译错误。
下面介绍函数与数组的结合:

6. 数组做函数参数

题目举例:写⼀个函数对将⼀个整型数组的内容,全部置换为-1,再写⼀个函数打印数组的内容。

代码示例:

#include<stdio.h>
int zh(int arr[],int sz)
{int i = 0;for (i = 0; i < sz; i++){arr[i] = -1;}return 0;
}
int print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
int main()
{int arr[5] = { 1,2,3,4,5 };int sz = sizeof(arr) / sizeof(arr[0]);zh(arr, sz);print(arr, sz);return 0;
}

运行结果:

上述代码中有两个参数:数组和数组的元素个数,对数组的内容进行置换,需把数组作为参数传递给函数,将每个元素置换为-1,需遍历数组,需要知道数组元素个数,也作为参数。定义函数对数组进行置换打印,完成操作。

另外需要注意的是:函数传参时

函数的形式参数要和函数的实参个数匹配
函数的实参是数组,形参也是可以写成数组形式的
形参如果是⼀维数组,数组⼤⼩可以省略不写
形参如果是⼆维数组,⾏可以省略,但是列不能省略
数组传参,形参是不会创建新的数组的
形参操作的数组和实参的数组是同⼀个数组
通过上面的学习,我们对函数有了一定的理解,下面介绍函数的另类使用:

7. 嵌套调用和链式访问

7.1 嵌套调用

嵌套调⽤就是函数之间的互相调⽤,每个函数就⾏⼀个乐⾼零件,正是因为多个乐⾼的零件互相⽆缝的配合才能搭建出精美的乐⾼玩具,也正是因为函数之间有效的互相调⽤,最后写出来了相对⼤型的程序。

题目举例:计算某年某⽉有多少天

代码示例:

#include<stdio.h>
int rbr(int year)//定义判断闰年的函数rbr
{if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))return 1;//闰年,返回1,真。elsereturn 0;//不是闰年,返回0,假。
}
int md(int year, int month)//定义判断天数的函数md
{int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//正常年份每月天数int day = days[month];//下标month,多加一个0是为了使month对应相应月份。if (rbr(year) && month == 2)//特殊情况,闰年的2月份为29天。day += 1;return day;
}
int main()
{int year = 0;int month = 0;scanf("%d%d", &year, &month);int day = md(year, month);printf("%d\n", day);return 0;
}

运行结果:

这道题目是对之前牛刀小试---闰年的判断http://t.csdnimg.cn/NqBAZ进一步扩展,在其基础上运用了函数和数组的知识。

上述代码,完成了⼀个独⽴的功能。代码中反应了不少的函数调⽤:
main 函数调⽤ scanf printf 、 md
md 函数调⽤ rbr
未来的稍微⼤⼀些代码都是函数之间的嵌套调⽤,但是 函数是不能嵌套定义的

7.2 链式访问

所谓链式访问就是将⼀个函数的返回值作为另外⼀个函数的参数,像链条⼀样将函数串起来就是函数的链式访问。
代码示例:
#include <stdio.h>
int main()
{printf("%d\n", strlen("abcdef"));//链式访问return 0;
}

将strlen函数的返回值作为库函数printf的参数

上述代码可以拆分为:


#include <stdio.h>
int main()
{int len = strlen("abcdef");//1.strlen求⼀个字符串的⻓度printf("%d\n", len);//2.打印⻓度 return 0;
}

下面再看一个链式访问的代码,猜一猜代码运行的结果:

#include <stdio.h>
int main()
{printf("%d", printf("%d", printf("%d", 43)));return 0;
}

运行结果:

有没有猜对?
这个结果是怎么得到的呢?
关键:printf函数返回的是打印在屏幕上的字符的个数
上⾯的例⼦中,第⼀个printf打印的是第⼆个printf的返回值,第⼆个printf打印的是第三个
printf的返回值。
第三个printf打印43,在屏幕上打印2个字符,再返回2
第⼆个printf打印2,在屏幕上打印1个字符,再放回1
第⼀个printf打印1
所以屏幕上最终打印:4321
讲了函数的另类应用,下面介绍函数的声明和定义:

8. 函数的声明和定义

8.1 单个文件

⼀般我们在使⽤函数的时候,直接将函数写出来就使⽤了

代码举例:

#include <stido.h>
//判断⼀年是不是闰年
int is_leap_year(int y)//函数的定义
{if(((y%4==0)&&(y%100!=0)) || (y%400==0))return 1;elsereturn 0;
}
int main()
{int y = 0;scanf("%d", &y);int r = is_leap_year(y);//函数的调用if(r == 1)printf("闰年\n");elseprintf("⾮闰年\n");return 0;
}

先定义后调用,定义在调用之前。另外定义在调用之后也是可以的,但需进行函数的声明:

#include<stdio.h>
int is_leap_year(int y);//函数声明
int main()
{int y = 0;scanf("%d", &y);int r = is_leap_year(y);if (r == 1)printf("闰年\n");elseprintf("⾮闰年\n");return 0;
}
//判断⼀年是不是闰年
int is_leap_year(int y)
{if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))return 1;elsereturn 0;
}

声明函数只要交代清楚:函数名,函数的返回类型和函数的参数

函数声明中参数只保留类型,省略掉名字也是可以的
函数的调⽤⼀定要满意,先声明后使⽤
函数的定义也是⼀种特殊的声明

8.2 多个文件

⼀般在企业中我们写代码时候,代码可能⽐较多,不会将所有的代码都放在⼀个⽂件中;我们往往会根据程序的功能,将代码拆分放在多个⽂件中。
⼀般情况下,函数的声明、类型的声明放在头⽂件(.h)中,函数的实现是放在源⽂件(.c)⽂件中。
示例:最开始我们定义的加法函数及应用可以分成多个文件来写

//函数的定义.c
int Add(int x, int y)
{return x+y;
}

//函数的声明.h
int Add(int x, int y);
//函数的调用.c
#include <stdio.h>
#include "函数的声明.h"
int main()
{int a = 10;int b = 20;//函数调⽤int c = Add(a, b);printf("%d\n", c);return 0;
}

这样写有着一定的好处:

1. 逻辑清晰

2. 方便多人协同

3. 适当隐藏代码

本篇文章就到这里了,如果对你学习函数有帮助的话,不要忘记点赞哦,后续将会有更多内容呈现。

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

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

相关文章

《ARM Linux内核源码剖析》读书笔记——0号进程(init_task)的创建时机

最近在读《ARM Linux内核源码剖析》&#xff0c;一直没有看到0号进程&#xff08;init_task进程)在哪里创建的。直到看到下面这篇文章才发现书中漏掉了set_task_stack_end_magic(&init_task)这行代码。 下面这篇文章提到&#xff1a;start_kernel()上来就会运行 set_task_…

怎么取消开机密码?4个必备方法!

“每次我开机都要输入密码&#xff0c;感觉有点麻烦&#xff0c;有什么方可以快速取消开机密码的吗&#xff1f;快给我推荐推荐吧&#xff01;” 为电脑设置开机密码&#xff0c;可以更好地保护电脑中的重要数据。但是用户需要在每次开机时都输入密码。这对于部分用户来说可能是…

Python数据结构——列表

目录 一、认识Python数据结构 二、列表概述 三、列表切片 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;常见形式 &#xff08;三&#xff09;特别说明 四、列表的基本操作 &#xff08;一&#xff09;创建列表 &#xff08;二&#xff09;列表元素增加…

全新加密叙事,以Solmash为代表的 LaunchPad 平台如何为用户赋能?

铭文市场的火爆带来“Fair Launch”这种全新的代币启动方式&#xff0c;Fair Launch 的特点在于其为所有人参与 Launch 带来了公平的机会&#xff0c;所有链上玩家们都需要通过先到先得的方式 Mint 资产&#xff0c;VC 在 Fair Launch 中几乎没有话语权&#xff0c;不同的投资者…

CSS伪类:为网页增添交互和样式

CSS伪类是一项强大的特性&#xff0c;它允许开发者根据不同的状态、位置和结构选择器来选择和样式化HTML元素。通过使用CSS伪类&#xff0c;我们可以为网页增添交互性、响应性和样式化效果。本文将深入探讨CSS伪类的概念、常见用法和一些实用示例。 CSS伪类是什么 CSS伪类是一…

【AI的未来 - AI Agent系列】【MetaGPT】1. AI Agent如何重构世界

上篇文章我们跑起来了第一个MetaGPT程序。本文主要学习了一下理论&#xff0c;什么是智能体&#xff0c;以及智能体如何重构世界。 0. 什么是智能体 智能体 LLM观察思考行动记忆 多智能体 智能体环境SOP评审路由订阅经济 用人话说&#xff0c;我理解的Agent&#xff1a; 智…

C#MQTT编程01--MQTT介绍

1、前言 近年来物联网的发展如火如荼已经渗透到我们生活的方方面面。从智能家居到工业自动化从智慧城市到智慧农业物联网&#xff0c;正在以前所未有的速度改变着我们的生活。 大家现在可能已经习惯了通过手机控制家里的灯光、空调和电视&#xff0c;这就是物联网在智能家居领域…

完美解决报错Please verify that the package.json has a valid “main“ entry处理方法

出现下图中的错误 &#xff0c;说明缺少main入口 解决方法&#xff1a; 1.删除 node_modules 和 package-lock.json这两个文件 2.命令行输入npm i 会重新下载包 3.重新执行检查没有报错

01循环算法

1.求小数点的某一位&#xff0c;且超出float和double的精度问题 【题目描述】 分数a/b化为小数后&#xff0c;小数点后第n位的数字是多少&#xff1f; 【输入】 三个正整数a&#xff0c;b&#xff0c;n&#xff0c;相邻两个数之间用单个空格隔开。0<a<b<100&#…

【微信小程序独立开发2】授权登录 上

前言&#xff1a;这一节设想完成的功能为进入小程序后请求授权信息&#xff0c;用户授权登录后&#xff0c;弹出宠物登记页面&#xff0c;并根据宠物类型播放背景音乐 小程序昵称头像在之前的版本获取规则为触发后弹出用户授权弹窗&#xff0c;授权后可直接获取用户头像和昵称&…

使用 CMake 和 Ninja 构建 C/C++ 项目的教程

使用 CMake 和 Ninja 构建 C/C 项目的教程 CMake 是一个跨平台的开源构建工具&#xff0c;它简化了项目的构建过程。而 Ninja 是一个快速、轻量级的构建系统&#xff0c;与 CMake 配合使用可以提高项目的构建效率。本教程将向你介绍如何使用 CMake 和 Ninja 来构建你的 C/C 项…

金融科技革命:数字化如何塑造未来经济_光点科技

当今世界&#xff0c;数字化不仅是一种趋势&#xff0c;更是深刻重塑经济和金融领域的关键力量。在这个过程中&#xff0c;金融科技&#xff08;FinTech&#xff09;崭露头角&#xff0c;成为革命性变化的代名词。以下是数字化技术在经济和金融领域的几个关键应用&#xff0c;它…

YOLOv5独家原创改进:多层次特征融合(SDI)结合PConv、DualConv、GSConv,实现二次创新 | UNet v2最新论文

💡💡💡本文独家改进:多层次特征融合(SDI)高效结合DualConv、PConv、GSConv等实现二次创新 1)替代原始的Concat; 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! 💡�…

高度自适应scroll-view,uniapp项目

中间粉红的区域高度自适应,不管换什么机型&#xff0c;高度都自适应 <template><!-- 合同-待确认 --><view class"viewport"><!-- 上 --><view class"top-box"><!-- tab --><view class"tabs"><te…

HTML5+CSS3+JS小实例:音频可视化

实例:音频可视化 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><m…

C++学习笔记——私有继承、多重继承、类模板

目录 一、私有继承 二、多重继承 三、类模板 四、一个使用私有继承的示例代码 4.1代码 4.2输出结果 五、多重继承案列 六、类模板案例 C中的继承和模板是非常强大和灵活的特性&#xff0c;它们可以帮助我们实现代码复用、抽象和泛化等目标。本文将着重介绍私有继承、多…

class_1:qt的安装及基本使用方式

一、选择组件&#xff1a; 1、windows编译工具&#xff1a;MinGW 7.30 32-bit MinGW 7.30 64-bit 2、QT源代码&#xff1a;sources 3、QT的绘图模块&#xff1a;QT charts 4、QT虚拟键盘&#xff1a;QT Virtual Keyboard 5、QT Creational 4.12.2 GDB 二、新建QT项目 文…

Linux完全卸载Anaconda3和MiniConda3

如何安装Anaconda3和MiniConda3请看这篇文章&#xff1a; 安装Anaconda3和MiniConda3_minianaconda3-CSDN博客文章浏览阅读474次。MiniConda3官方版是一款优秀的Python环境管理软件。MiniConda3最新版只包含conda及其依赖项如果您更愿意拥有conda以及超过720个开源软件包&…

高通平台开发系列讲解(USB篇)adb function代码分析

文章目录 一、FFS相关动态打印二、代码入口三、ffs_alloc_inst四、ep0、ep1&ep2的注册五、读写过程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文主要介绍高通平台USB adb function代码f_fs.c。 一、FFS相关动态打印 目录:msm-4.14/drivers/usb/gadget/fun…

docker+jmeter实现windows作为主控机,linux作为负载机的分布式压测环境搭建

dockerjmeter实现windows作为主控机&#xff0c;linux作为负载机的分布式压测环境搭建 1、搭建环境说明2、windows主控机安装Jmeter3、linux负载机安装Jmeter3.1、安装docker环境3.2、使用docker安装jmeter 4、windows主控机分发测试任务 1、搭建环境说明 准备一台windows主机…