【C语言】函数规则及入门知识

news2024/11/26 11:31:07

🚩纸上得来终觉浅, 绝知此事要躬行。
🌟主页:June-Frost
🚀专栏:C语言
⚡注:此篇文章的 部分内容 将根据《高质量 C++/C 编程指南》 —— 林锐 进行说明。该部分将用橙色表示。

🔥该篇将简单了解 函数知识

目录

    • 函数概念
    • 函数分类
      • 库函数
      • 自定义函数
    • 函数的参数
      • 实际参数
      • 形式参数
    • 函数调用
      • 传值调用
      • 传址调用
    • 函数的嵌套调用和链式访问
    • 函数声明和定义
    • 结语

函数概念

在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性

一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

函数分类

函数分为库函数和自定义函数。

库函数

库函数—— c语言中把常用的功能封装为函数提供出来使用。这些常用的非业务性的代码封装后,就拥有了可移植性并且提高了编程效率,方便了软件开发。

需要注意:C语言只是为库函数提供了标准,例如函数的名称,参数。返回值,功能,但是函数的实现一般是由编译器完成的,C语言是并不直接实现库函数。

当然,常用的库函数有IO函数,字符串操作函数,字符操作函数,内存操作函数,时间/日期函数,数学函数…

如果想了解库函数,可以查询文献
https://cplusplus.com/

自定义函数

库函数的功能是有限的,当需要更复杂的功能时,我们就需要自定义函数。
自定义函数和库函数一样,有着函数名,参数,返回类型。我们可以根据需求来设计这些以及具体实现。

函数组成:

ret_type  fun_name(paral)
{
  statement;
}

1. 每个函数定义结束之后都要加空行。
2. ‘,’之后要留空格,如 Function(x, y, z)。

通过一个例子来具体了解:找出两个整数的最大值。

#include<stdio.h>
int GetMax(int x, int y)
{
	int max = (x > y) ? x : y;
	return max;
}
//空行
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int max = GetMax(a, b);
	printf("%d", max);
	return 0;
}

📙我们也可以将函数想象为一个工厂,例如A调用B,A为公司,B为工厂,A向B下订单(调用)并提供材料(传参),B工厂开始加工(程序执行函数体),并将产品给公司(返回值)。

当然函数也可以没有返回值和参数。


函数的参数

实际参数

真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。

形式参数

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


通过一个例子说明一些性质:通过函数交换两个值 。

第一个代码:

#include<stdio.h>
void Swap(int x, int y)
{
	int temp = 0;
	temp = x;
	x = y;
	y = temp;
}

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;
}

❗️结果:

发现结果出现了运行时错误,与预期结果不一样。

VS2022调试:

可以看出 形参的值交换了,但是实参的值没有交换的。而且,x,y,a,b的地址都是不一样的,是四个独立的内存空间,相互之间没有直接联系。
⭐️所以交换两个数的关键就是让形参与实参拥有一定的联系,也就是说,可以利用指针去建立一个关系,通过指针就可以找到变量去进行值的修改。

第二个代码:

#include<stdio.h>
void Swap(int *px, int *py)
{
	int temp = 0;
	temp = *px;
	*px = *py;
	*py = temp;
}

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;
}

❗️结果

VS2022调试:

可以发现px指向了a,py指向了b,从而* px与a是同一空间,*py与b是同一空间,这样本质交换的就是变量a,b和 temp。

总结:

形参实例化之后其实相当于实参的一份临时拷贝。
当实参传递给形参的时候,形参是实参的一份临时拷贝,所以对形参的修改不会影响实参。

函数调用

对于函数调用,有传值调用传址调用
上述代码1——就是传值调用,代码2——传址调用。

传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。

传址调用

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

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

嵌套调用:

为实现需求可以将函数互相调用。例如:在函数A中调用函数B。

例如:

#include<stdio.h>
void Fun2()
{
	printf("World");
}

void Fun1()
{
	printf("Hello ");
	Fun2();
}

int main()
{
	Fun1();
	return 0;
}

该函数就是main函数调用Fun1函数,Fun1函数再调用Fun2函数。
但是要注意函数可以嵌套调用,但是不能嵌套定义。

❗️不可以写成这样:

#include<stdio.h>
void Fun1()
{
	printf("Hello ");
	void Fun2()
	{
		printf("Wrold");
	}
}

int main()
{
	Fun1();
	return 0;
}

链式访问

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

例如:求一个字符串长度
可以这样写

int main()
{
	char arr[20] = "abcdef";
	int ret = strlen(arr);
	printf("%d", ret);
	return 0;
}

也可以链式访问:
将strlen的返回值作为printf的第二个参数。

int main()
{
	char arr[20] = "abcdef";
	printf("%d", strlen(arr));
	return 0;
}

函数声明和定义

举个例子:

如果有参数,声明可以写为void test(int x, int y);,也可以写为void test(int , int );

函数声明:

告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。

一般来说,函数的使用要满足:先声明后使用

但是,如果函数定义写在函数调用前面也是可以不声明的,因为函数的定义也是一种特殊的声明

例如:

#include<stdio.h>

void test()
{
	printf("Hello Wrold\n");
}

int main()
{
	test();
	return 0;
}

但是在写项目的时候,通常是将函数定义和函数实现写到不同的文件,将函数的声明放在头文件中,将函数的实现放在源文件中。
例如:

这么做是为了什么?

  • 可以方便协作,对一个大的项目,可以分工,最后整合。
  • 可以将代码的实现和声明分离,方便对函数的实现包装为静态库。

通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库
功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。


结语

函数作为 C++/C 程序的基本功能单元,我们都需要了解更多的书写规则去写出优质的代码,一起加油💖💖💖

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

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

相关文章

新手建站:使用腾讯云轻量服务器宝塔面板搭建WP博客教程

腾讯云轻量应用服务器怎么搭建网站&#xff1f;太简单了&#xff0c;轻量服务器选择宝塔Linux镜像&#xff0c;然后在宝塔面板上添加站点&#xff0c;以WordPress建站为例&#xff0c;腾讯云服务器网来详细说下腾讯云轻量应用服务器搭建网站全流程&#xff0c;包括轻量服务器配…

html5视频播放器代码实例(含倍速、清晰度切换、续播)

本文将对视频播放相关的功能进行说明&#xff08;基于云平台&#xff09;&#xff0c;包括初始化播放器、播放器尺寸设置、视频切换、倍速切换、视频预览、自定义视频播放的开始/结束时间、禁止拖拽进度、播放器皮肤、控件按钮以及播放控制等。 图 / html5视频播放器调用效果&a…

java web 基础springboot

1.SprintBootj集成mybaits 连接数据库 pom.xml文件添加依赖 <!-- mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><!-- …

学习HCIP的day.09

目录 一、BGP&#xff1a;边界网关路由协议 二、BGP特点&#xff1a; 三、BGP数据包 四、BGP的工作过程 五、名词注解 六、BGP的路由黑洞 七、BGP的防环机制—水平分割 八、BGP的基本配置 一、BGP&#xff1a;边界网关路由协议 是一种动态路由协议&#xff0c;且是…

花果山博客

1&#xff1a;前言 2&#xff1a;项目介绍 3&#xff1a;统一返回结果 4&#xff1a;登录功能实现 前言 简单介绍一个写这个博客的目的。 因为之前学开发都是学完所需的知识点再去做项目&#xff0c;但是这时候在做项目的过程中发现以前学过的全忘了&#xff0c;所以为了减少这…

Vue3导入Element-plus方法

先引入依赖 npm install element-plus --savemain.js中要引入两个依赖 import ElementPlus from element-plus; import "element-plus/dist/index.css";然后 这个东西 我们最好还是挂载vue上 所以 还是 createApp(App).use(ElementPlus)然后 我们可以在组件上试一…

腾讯云轻量服务器镜像安装宝塔Linux面板怎么使用?

腾讯云轻量应用服务器宝塔面板怎么用&#xff1f;轻量应用服务器如何安装宝塔面板&#xff1f;在镜像中选择宝塔Linux面板腾讯云专享版&#xff0c;在轻量服务器防火墙中开启8888端口号&#xff0c;然后远程连接到轻量服务器执行宝塔面板账号密码查询命令&#xff0c;最后登录和…

从零搭建微服务-认证中心(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff1a;https://gitee.com/csps/mingyue 文档地址&#xff1a;https://gitee.com/csps/mingyue/wikis 创建新项目 MingYue Idea 创建 maven 项目这…

操作系统第五章——输入输出管理(下)

提示&#xff1a;枕上诗书闲处好&#xff0c;门前风景雨来佳。 文章目录 5.3.1 磁盘的结构知识总览磁盘 磁道 扇区如何从磁盘中读/写数据盘面 柱面磁盘的物理地址磁盘的分类知识回顾 磁盘调度算法知识总览磁盘的读写操作需要的时间先来先服务算法FCFS最短寻找时间优先SSTF扫描算…

SVG图形滤镜

SVG有提供Filter(滤镜)这个东西&#xff0c;可以用来在SVG图形上加入特殊的效果&#xff0c;像是图形模糊化、产生图形阴影、将杂讯加入图形等。以下介绍的是图形模糊化、产生图形阴影这2个滤镜效果。 浏览器对于SVG Filter的支援 SVG : 滤镜 (仅列出部分有使用到的属性) <…

【数据结构】超详细之实现栈

栈的实现步骤 栈的介绍栈的初始化栈的插入(入栈)栈的出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空销毁栈栈元素打印 栈的介绍 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xf…

快捷转换/互转 Markdown 文档和 TypeScript/TypeDoc 注释

背景 作为文档工具人&#xff0c;经常需要把代码里面的注释转换成语义化的 Markdown 文档&#xff0c;有时也需要进行反向操作。以前是写正则表达式全局匹配&#xff0c;时间长了这种方式也变得繁琐乏味。所以写了脚本来互转&#xff0c;增加一些便捷性。 解决方案 注释转 M…

【C++】初遇C++

认识C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。为了解决软件危机&#xff0c; 20世纪80年代&#xff0c; 计算机界提出了OOP(object orient…

学好网络安全,每年究竟能挣多少钱呢?

薪资的高低&#xff0c;应该是想要转行网络安全的同学最关心的话题了。毕竟薪资是个人水平和自我价值的体现嘛。&#xff08;文末资料&#xff09; 今天就展开谈谈网络安全行业的薪资吧。 先来看张图&#xff0c; 大家在求职时都有一个期望薪资&#xff0c;企业会有一个实际薪…

5月的面试难度有点大....

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

R语言实践——使用rWCVP映射多样性

使用rWCVP映射多样性 加载库工作流1. 物种丰富度2. 特有物种丰富度3. 特定区域的物种热力图 加载库 library(rWCVP) library(tidyverse) library(sf) library(gt)工作流 1. 物种丰富度 我们可以使用 wcvp_summary 将所有物种的全球出现数据压缩为每个 WGSRPD 3 级区域的原始…

chatgpt赋能python:Python三角函数角度的介绍

Python三角函数角度的介绍 Python语言为各种计算提供了强大的支持。而Python在数学领域的支持更是非常强大&#xff0c;包括对三角函数角度的计算。在Python中&#xff0c;支持常用的三角函数&#xff0c;例如sin、cos、tan等。这些函数都需要将角度转换为弧度&#xff0c;并且…

车载网络测试 - CANCANFD - 基础篇_01

目录 问题思考&#xff1a; 一、为什么需要总线? 二、什么是CAN总线? 三、为什么是CAN总线? 四、曾经的车用总线 1、SAEJ1850(Class2) 2、SAEJ1708 3、K-Line 4、BEAN 5、 byteflight, K-Bus 6、D2B 五、当前的车用总线 1、CAN 2、LIN 3、FlexRay 4、MOST 六…

C#中的DataGridView中添加按钮并操作数据

背景&#xff1a;最近在项目中有需求需要在DataGridView中添加“删除”、“修改”按钮&#xff0c;用来对数据的操作以及显示。 在DataGridView中显示需要的按钮 首先在DataGridView中添加需要的列&#xff0c;此列是用来存放按钮的。 然后在代码中“画”按钮。 if (e.Column…

你知道什么叫三目表达式吗

目录 什么是三目表达式&#xff1f; 运用 1.单个使用 2.嵌套使用 什么是三目表达式&#xff1f; 1.三目表达式是一种编程中常见的表达式,它能够有效地帮助我们解决一些问题。 2.三目表达式由三个部分组成,分别是:条件表达式、结果表达式 听不懂么&#xff0c;那我们就来举个…