「函数小课堂」~(C语言)

news2025/3/13 17:10:21

先赞后看,不足指正!

这将对我有很大的帮助!

所属专栏:C语言知识

阿哇旭的主页:Awas-Home page


目录

引言 

1. 函数的概念

2. 函数的类型

2.1 库函数

 2.2 自定义函数

 2.2.1 语法

 2.2.2 举例

3. 函数的参数

3.1 实参

3.2 形参

3.3 实参与形参的关系

4. 数组作为函数的参数

5. return 语句

6. 嵌套调用和链式访问

6.1 函数的嵌套调用

6.2 函数的链式访问

7. 函数的声明和定义

7. 1 单个文件

7.1.1 函数定义在函数调用前

7.1.2 函数定义在函数调用后

7.2 多个文件

8. 结语


引言 

        相信大家对函数的概念并不陌生,在我们数学学习中经常穿插着这个概念,比如,一次函数y=kx+b,k和b都是常数,我们给一个任意的x,就可以得到y的值。

         那么,话不多说,我们一起来看看吧!


1. 函数的概念

        在C语言中引入了函数(function)的概念,也称作子程序,而构成C程序的基本单元是函数,函数中包含程序的可执行代码。同时一个函数如果能完成某项特定任务的话,这个函数也是可以复用的,提升了开发软件的效率。

        我们可以举一个例子让大家更好地理解函数:

        例如盖一栋楼房,在工程师的指挥下,有工人搬运建造材料,有工人建造房屋结构,有工人粉刷内外墙壁,各司其职。编写程序与盖楼的道理是差不多的,主函数就像工程师,控制每一步程序的执行,而子函数就像工人,分别去完成自己的工作。

#include<stdio.h>

// 执行搬运功能
void Move()
{
	printf("搬运建筑材料");
}

// 执行建造功能
void Build()
{
	printf("建造房屋结构");
}

// 执行粉刷功能
void Paint()
{
	printf("粉刷内外墙壁");
}

int main()
{
	Move(); // 执行搬运函数
	Build(); // 执行建造函数
	Paint(); // 执行粉刷函数
	return 0;
}

2. 函数的类型

2.1 库函数

        C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSI C规定了一些常用的函数的标准,被称为标准库,那不同的编译器厂商根据ANSI提供的C语言标准就给出了一系列函数的实现。这些函数就被称为库函数。

        比如,我们经常使用的 printf scanf 都是库函数,而库函数也是函数,通常使用库函数都需要包含对应的头文件,不要忘记哦!

        库函数的学习和查看工具很多,比如:

       (1) 了解更多库函数头文件

       (2)  cplusplus.com

 2.2 自定义函数

        自定义函数是指由程序员自己编写的、用于执行特定任务的函数。而自定义函数更加灵活,也能给程序员写代码更多的创造性。

 2.2.1 语法

        自定义函数和库函数是一样的,都有函数返回类型、函数名、形式参数以及函数体,具体形式如下:

datatype fun_Name(形式参数)
{
    fun_body
}
  • datatype是函数返回值类型,可以是int 、char、float等,有时候返回类型可以是 void ,表示什么都不返回。
  • fun_Name是函数名,也是函数的标识符,遵循标识符的命名规则。
  • 形式参数是函数定义中的一部分,它用于接收传递给函数的值。参数可以是任意合法的数据类型,例如整数、浮点数、字符、指针等。在函数体中,我们可以使用参数的值来执行相应的操作。
  • { fun_body }括起来的部分被称为函数体,是函数定义的主要部分,它包含了一系列的语句和表达式,用于实现函数的具体功能。函数体中的代码会按照定义的顺序被执行。
  • 返回值是函数执行完毕后返回给调用函数的结果。在函数体中,我们可以使用return语句将结果返回给调用函数的地方。返回值的类型必须与函数头中指定的返回类型相匹配。

 2.2.2 举例

        自定义一个加法函数,完成两个整形变量的相加操作:

#include<stdio.h>

int Add(int x, int y)
/*int ->函数返回类型
* Add ->自定义函数名称
* a、b是形式参数,均是int型
*/
{
	int sum = 0;
	sum = x + y;
	return sum;
}

int main()
{
	int a = 0;
	int b = 0;
	// 注意输入内容与格式化内容一致
	scanf("%d %d", &a, &b); 
	int ret = Add(a, b);
	printf("a + b = %d\n", ret);
	return  0;
}

输入:22 17

输出:x + y = 39

        当然,我们可以把Add函数简化一下:

int Add(int x, int y)
{
	return x + y; // 直接返回结果
}

3. 函数的参数

3.1 实参

        实参,也称为实际参数,也就是主函数main调用子函数时,传递给函数的参数a和b,而实际参数就是真实传递给函数的参数。

int ret = Add(a, b); // 加法函数举例

3.2 形参

         形参,也称为形式参数,也就是在函数名 Add 后的括号中写的 x 和 y,在函数未调用时不会向内存申请空间,形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形参的实例化。

int Add(int x, int y) // 加法函数举例
{
}

3.3 实参与形参的关系

        我们来观察下列代码,来探究二者之间的关系:

#include<stdio.h>

int Swap(int x, int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 0;
	int b = 0;
	// 注意输入内容与格式化内容一致
	scanf("%d %d", &a, &b);
	printf("交换前:a=%d, b=%d\n", a, b);
	Swap(a, b);
	printf("交换后:a=%d, b=%d\n", a, b);
	return  0;
}

输入:1 5

输出:交换前:a=1, b=5      交换后:a=1,b=5

        我们可以观察到,交换前后的结果相同,为什么会这样?我们可以通过调试来发现问题。

         通过调试,我们不难发现,x和y的值确实发生了交换,但并未影响到a和b,是因为x和y的地址和a和b的地址是不一样的,在各自的内存空间内互不干扰。

        当函数调用结束要返回的时候,前面创建的函数栈帧也要销毁。这里包含函数栈帧的创建和销毁的知识,我会在后面的章节为大家讲解,这样理解起来就更容易。

        由此,我们可以得出一个结论:形参是实参的一份临时拷贝,改变形参并不会影响到实参。


4. 数组作为函数的参数

        写一个函数将一个整型数组的内容,全部重置为0,再写一个函数打印重置后数组的内容。

#include<stdio.h>

// 重置数组函数
void Set_arr(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		arr[i] = 0;
	}
}

// 打印数组函数
void Print_arr(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int size = sizeof(arr) / sizeof(arr[0]);
	Print_arr(arr, size); // 重置前
	Set_arr(arr, size); // 重置数组
	Print_arr(arr, size); // 重置后
	return 0;
}

        需要我们注意的是, Set_arr函数要能够对数组内容重置,就得把数组作为参数传递给函数,同时函数内部在设置数组每个元素的时候,也得遍历数组,需要知道数组的元素个数。所以我们需要给Set_arr传递2个参数,一个是数组,另外一个是数组的元素个数。Print_arr函数也是这样,只有得到了数组和元素个数,才能遍历打印数组的每个元素。


5. return 语句

        在函数中,也会经常使用return语句,下面是我们要注意的几点:

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

6. 嵌套调用和链式访问

6.1 函数的嵌套调用

        在C语言中,我们学习了分支和循环结构的嵌套使用,而函数嵌套调用就是函数之间的互相调用。

        我们可以举一个简单的例子:

#include <stdio.h>

void func1()
{
    printf("函数1\n");
}

void func2()
{
    printf("函数2\n");
    func1(); // 在函数2中调用函数1
}

void func3()
{
    printf("函数3\n");
    func2(); // 在函数3中调用函数2
}

int main()
{
    printf("主函数\n");
    func3(); // 在主函数中调用函数3
    return 0;
}

         因此,当我们运行这段代码时,会按照函数的嵌套调用顺序,依次输出以下内容:

主函数

函数3

函数2

函数1

        在上面的代码中,主函数main使用库函数printf,也是属于函数嵌套调用。 

        注:函数之间可以嵌套调用,但是不能嵌套定义。

6.2 函数的链式访问

        所谓链式访问就是将一个函数的返回值作为另外一个函数的参数,像链条一样将函数串起来就是函数的链式访问。

#include <stdio.h>
#include <string.h>

int main()
{
	printf("%d\n", strlen("abcdef"));//链式访问
	return 0;
}

输出:6

        我们可以观察下列代码,猜测输出结果是什么?

#include <stdio.h>

int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

 输出:4321

        为什么呢?我在第一次遇见也卡住了。

        注:printf函数返回的是打印在屏幕上的字符的个数。

        从上面代码中,可以知道第一个printf打印的是第二个printf的返回值,第二个printf打印的是第三个 printf的返回值。

        第三个printf打印43,在屏幕上打印2个字符,再返回2;

        第二个printf打印2,在屏幕上打印1个字符,再返回1;

        第一个printf打印1,所以最终输出:4321。


7. 函数的声明和定义

7. 1 单个文件

7.1.1 函数定义在函数调用前

#include<stdio.h>

 // 函数定义
int Add(int x, int y)
{
	int sum = 0;
	sum = x + y;
	return sum;
}

int main()
{
	int a = 0;
	int b = 0;
	// 注意输入内容与格式化内容一致
	scanf("%d %d", &a, &b); 
	int ret = Add(a, b); // 函数调用
	printf("a + b = %d\n", ret);
	return  0;
}

7.1.2 函数定义在函数调用后

#include<stdio.h>

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("a + b = %d\n", ret);
	return  0;
}

// 函数定义
int Add(int x, int y)
{
	int sum = 0;
	sum = x + y;
	return sum;
}

         在函数调用之前先声明一下这个函数,这样代码就能正常编译运行。

7.2 多个文件

        在大项目中,代码可能比较多,通常不会将所有的代码都放在一个文件中;我们往往会根据程序的功能,将代码拆分放在多个文件中,这样有助于提高代码的可读性、可维护性和可扩展性。

        一般情况下,函数的声明、类型的声明放在头文件(.h)中,函数的实现是放在源文件(.c)中。

        应用举例:~扫雷游戏来啦~


8. 结语

        希望这篇文章对大家有所帮助,如果你有任何问题和建议,欢迎在评论区留言,这将对我有很大的帮助。

        完结!咻~

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

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

相关文章

International Marine Purchasing Association 7(IMPA7)

​IMPA7物料 物料手持下载链接&#xff1a;https://pan.baidu.com/s/13m0EELpEZWlL55UhsRvI5g?pwd8888 提取码&#xff1a;8888 国际船舶物料准则International Marine Purchasing Association 7(IMPA7)。 IMPA是英文“International Marine Purchasing Association”缩写…

vue-vuex(七)

阅读文章你可以收获&#xff1a; 1 了解什么是vuex 2 知道如何在vue项目中集成vuex 3 知道vuex由什么组成&#xff0c;并如何使用 vuex概述 1. 是什么&#xff1a;vuex 是一个 vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;vuex 是一个插件&#xff0…

Swing程序设计(10)列表框,文本框,文本域,密码框

文章目录 前言一、列表框二、文本框&#xff08;域&#xff09; 1.文本框2.文本域三、密码框总结 前言 该篇文章简单介绍了Java中Swing组件里的列表框、文本框、密码框。 一、列表框 列表框&#xff08;JList&#xff09;相比下拉框&#xff0c;自身只是在窗体上占据固定的大小…

CSS概述 | CSS的引入方式 | 选择器

文章目录 1.CSS概述2.CSS的引入方式2.1.内部样式表2.2.行内样式表2.3.外部样式表 3.选择器 1.CSS概述 CSS&#xff0c;全称Cascading Style Sheets&#xff08;层叠样式表&#xff09;&#xff0c;是一种用来设置HTML&#xff08;或XML等&#xff09;文档样式的语言。CSS的主要…

文件夹删不掉,显示在另一个文件中打开怎么办

问题&#xff1a; 一、想要删掉这个文件夹&#xff0c;却因为文件夹中的文件打开了删不掉&#xff0c;这里我因为做的测试&#xff0c;所以是知道打开了什么 二、一般情况下文件比较多时&#xff0c;是不知道打开了什么的&#xff0c;长这个样子 解决&#xff1a; 一、打开任…

【C Primer Plus第六版 学习笔记】 第十七章 高级数据表示

有基础&#xff0c;进阶用&#xff0c;个人查漏补缺 链表&#xff1a;假设要编写一个程序&#xff0c;让用户输入一年内看过的所有电影&#xff0c;要储存每部影片的片名和评级。 #include <stdio.h> #include <stdlib.h> /* 提供malloc()的原型 */ #include <s…

数据结构之时空复杂度

一、前言 1&#xff09;什么是数据结构 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的 集合。 2&#xff09;什么是算法 算法(Algorithm):就是定义良好的计算过程&#xff0c;他取一个或一组的值为输入&am…

Faithful Vision-Language Interpretation via Concept Bottleneck Models (FVLC)

本篇文章发表于ICLR 2024。 文章链接&#xff1a;https://openreview.net/attachment?idrp0EdI8X4e&namepdf 一、概述 这篇文章也是CBMs“大家庭”的一员。众所周知&#xff0c;CBMs需要大量的人工annotation&#xff0c;Label-Free CBM借用pre-trained多模态模型自动生…

Oracle 基础入门指南

一、什么是Oracle&#xff1f; Oracle是一款由美国Oracle公司开发的关系型数据库管理系统。它支持SQL查询语言&#xff0c;并提供了丰富的功能和工具&#xff0c;用于管理大规模数据存储、处理和访问。Oracle被广泛应用于企业级应用中&#xff0c;包括金融、电信、零售等各行各…

Ubuntu Desktop - Details (设备详情)

Ubuntu Desktop - Details [设备详情] 1. OverviewReferences 1. Overview System Settings -> Details -> Overview ​ References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

人力资源智能化管理项目(day10:首页开发以及上线部署)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/humanResourceIntelligentManagementProject 首页-基本结构和数字滚动 安装插件 npm i vue-count-to <template><div class"dashboard"><div class"container"><!-- 左侧内…

Code Composer Studio (CCS) - Comment (注释)

Code Composer Studio [CCS] - Comment [注释] References Add Block Comment: 选中几行代码 -> 鼠标右键 -> Source -> Add Block Comment shortcut key: Ctrl Shift / Remove Block Comment: 选中几行代码->鼠标右键->Source->Remove Block Comment s…

AD高速板常见问题和过流自锁

可以使用电机减速器来增大电机的扭矩&#xff0c;低速运行的步进电机更要加上减速机 减速电机就是普通电机加上了减速箱&#xff0c;这样便降低了转速增大了扭矩 HDMI布线要求&#xff1a; 如要蛇形使其等长&#xff0c;不要在HDMI的一端绕线。 HDMI走线时两边拉线&#xff0…

2023年中国数据智能管理峰会(DAMS上海站2023):核心内容与学习收获(附大会核心PPT下载)

随着数字经济的飞速发展&#xff0c;数据已经渗透到现代社会的每一个角落&#xff0c;成为驱动企业创新、提升治理能力、促进经济发展的关键要素。在这样的背景下&#xff0c;2023年中国数据智能管理峰会&#xff08;DAMS上海站2023&#xff09;应运而生&#xff0c;汇聚了众多…

如何清除谷歌浏览器的缓存?这里有详细步骤

如果你想解决加载或格式化问题&#xff0c;以改善你在谷歌Chrome上的浏览体验&#xff0c;那么清除缓存和cookie是一个很好的开始。以下是删除它们的方式和操作。 删除缓存和cookie时会发生什么 当你访问一个网站时&#xff0c;它有时会保存&#xff08;或记住&#xff09;某…

自然语言编程系列(三):自然语言编程工具

自然语言编程工具尝试让用户以更接近日常对话的方式描述任务&#xff0c;然后将其自动转换成合适的代码。 自然语言编程工具&#xff08;Natural Language Programming, NLP&#xff09;旨在降低编程门槛&#xff0c;使得不具备传统编程技能的用户能够以他们习惯的日常对话方式…

【开源】JAVA+Vue.js实现天然气工程业务管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…

排序前言冒泡排序

目录 排序应用 常见的排序算法 BubbleSort冒泡排序 整体思路 图解分析 ​ 代码实现 每趟 写法1 写法2 代码NO1 代码NO2优化 时间复杂度 排序概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递…

记录 | 验证pytorch-cuda是否安装成功

检测程序如下&#xff1a; import torchprint(torch.__version__) print(torch.cuda.is_available()) 或者用终端 Shell&#xff0c;运行情况如下

docker (六)-进阶篇-数据持久化最佳实践MySQL部署

容器的数据挂载通常指的是将宿主机&#xff08;虚拟机或物理机&#xff09;上的目录或文件挂载到容器内部 MySQL单节点安装 详情参考docker官网文档 1 创建对应的数据目录、日志目录、配置文件目录(参考二进制安装&#xff0c;需自己建立数据存储目录) mkdir -p /data/mysq…