【C语言】详解函数(下)(庖丁解牛版)

news2024/10/6 1:55:05

文章目录

  • 1. 前言
  • 2. 数组做函数形参
  • 3. 函数嵌套调用和链式访问
    • 3.1 嵌套调用
    • 3.2 链式访问

1. 前言

详解C语言函数(上)的链接:http://t.csdnimg.cn/EGsfe

经过对函数的初步了解之后,相信大家已经对C语言标准库里的函数已经有初步的认知了,并且还学会了如何自定义函数。

在之前我们学过的数据类型中,有整型、字符型、浮点型、布尔类型还有数组。这就会引发一个问题,我们说形参相当于我们给函数的一个可操作的初始变量的值,而在我们之前举的例子中,我都是用整型变量作为形参。那如果我用数组作为形参,又会是怎么样的呢?那么,在本文中就会给大家介绍,数组作为形参的效果

另外,还会讲解如果函数的函数体里面还有个函数,又会是什么情况。

那么,让我们一起扬帆起航吧!!!🚢🚢🚢

2. 数组做函数形参

在使用函数解决问题时,我们肯定会遇到一种情况:对数组里面的元素进行操作。那这就意味着,我们得把数组作为参数传递给函数,让函数来帮我们处理。那在主函数把参数传递给函数的过程中,会发生什么情况呢?这难免会引起我们对此的一泡浓厚兴趣。

我们以基本现象来逐步深入问题的本质:
假如,现在要求你写一个功能:在一个函数将整个数组的内容,全部置为-1,在写一个函数打印数组的内容。

简单思考一下,不难写出主函数里面的基本框架:

#include<stdio.h>
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	int sz = sizeof(arr) / sizeof(arr[0]); //计算数组元素的个数
	set_arr(); //作用:将数组里面的元素都置为-1。里面的参数有待填写
	print_arr(); //作用:打印整个数组的元素。里面的参数有待填写
	return 0;
}

这⾥的set_arr函数要能够对数组内容进⾏设置,就得把数组作为参数传递给函数,同时函数内部在设置数组每个元素的时候,也得遍历数组,需要知道数组的元素个数。所以我们需要给set_arr传递2个参数,⼀个是数组,另外⼀个是数组的元素个数。仔细分析print_arr也是⼀样的,只有拿到了数组和元素个数,才能遍历打印数组的每个元素。

#include<stdio.h>
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	int sz = sizeof(arr) / sizeof(arr[0]); //计算数组元素的个数
	set_arr(arr,sz); //作用:将数组里面的元素都置为-1。
	print_arr(arr,sz); //作用:打印整个数组的元素。
	return 0;
}

数组作为参数传递给了set_arr和print_arr函数了,那么这两个函数具体如何设计呢?

在此之前,我们就要得先了解数组传参的几个重要的知识点了(敲黑板,干货来了):

  1. 函数的形式参数要和函数的实参个数匹配
  2. 函数的是参数数组,形参也可以写成数组的形式
  3. 形参如果是一维数组,数组的大小可以省略不写
  4. 形参如果是二维数组,行可以省略,但列不可以省略
  5. 数组传参时,形参是不会创建新的数组的
  6. 形参操作的数组和实参的数组是同一数组

根据上述的信息,我们可以实现这两个函数了:

void set_arr(int arr[], int sz)
{
	int i = 0;
	for(i = 0; i < sz; i++)
	{
		arr[i] = -1;
	}
}

void print_arr(int arr[], int sz)
{
	int i = 0;
	for(i = 0; i< sz; i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}

这样的完成了我们的要求了。相信通过上述的例子和讲解,你已经大概清楚了数组作为函数的参数时,是如何设计自定义函数的形参,以及如何在函数内操作数组的了。

关于数组作为函数参数进行传参的过程中,还有更多的细节,碍于篇幅的限制,目前只需要了解到这里就已经很不错了。后续我也会写一篇关于数组作为函数参数传参细节的文章,到时候希望大家来捧场。🥺

3. 函数嵌套调用和链式访问

有些读者可能对这个概念比较陌生,那我就先讲解一下这个概念,究竟什么时函数的嵌套调用和链式访问?

3.1 嵌套调用

嵌套调用就是函数间的相互调用。说白了,就是你中有我,我中有你。
也可以这么理解,把每个函数想象成一个个乐高零件,正是因为有这么多乐高零件的相互配合、相互成全,才成就出一个巨大且精美的乐高玩具,这也就是函数嵌套调用的精髓所在。

下面我给一道题目,我们在题目中理解概念:

题目:假如我们计算某年某月有多少天?

拿到这个题目时,我们就会想,平年和闰年在2月份有区别。每个月份的天数也有区别。
根据这个思路,我们就可以设计这两个函数:
一个是用于判断年份是否位闰年,is_leap_year()
另一个是用于说明对应月份的对应天数,get_days_of_month()

int is_leap_year(int y)
{
 	if(((y%4==0)&&(y%100!=0))||(y%400==0))
		 return 1;
 	else
		 return 0;
}

int get_days_of_month(int y, int m)
{
	int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 	int day = days[m];
 	if (is_leap_year(y) && m == 2)
 		day += 1;
 
 return day;
}

int main()
{
 	int y = 0;
 	int m = 0;
 	scanf("%d %d", &y, &m);
 	int d = get_days_of_month(y, m);
 	printf("%d\n", d);
 	return 0;
}

分析:这⼀段代码,完成了⼀个独⽴的功能。代码中反应了不少的函数调⽤:

  • main 函数调⽤ scanfprintfget_days_of_month
  • get_days_of_month 函数调⽤ is_leap_year

未来的稍微⼤⼀些代码都是函数之间的嵌套调⽤,但是函数是不能嵌套定义的

3.2 链式访问

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

这个其实也很好理解,比如:你现在接收到一个任务,你需要把一个待卡扣绳子的一端,扣在另一根绳子上。这个"卡扣"就是一个函数的返回值,"被扣的那个绳子"就是另一个函数。它们相互配合,共同完成了一个任务。

下面写一个链式访问(说不定,你在不经意间就已经用过了)的情况:

#include<stdio.h>
#include<string.h>
int main()
{
	printf("%d\n", strlen("I love learning C!")); //链式访问
	return 0;
}

下面我给大家一段有趣的代码,大家下来可以自己思考一下:

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

想要知道这个结果,接得先了解printf函数的返回值。这时候,你也许会惊讶,真的假的,我用了这么久的的printf函数,竟然都不知道printf函数还有返回值。

其实是有的,不信的话,可以去官网找一下这个函数的文档。为了方便研究,我就帮大家找好了。
printf函数
printf函数
看到这里,你就清楚了,printf函数返回的是被成功打印屏幕上的字符的个数。

上⾯的例⼦中,我们就第⼀个printf打印的是第⼆个printf的返回值,第⼆个printf打印的是第三个printf的返回值。

第三个printf打印43,在屏幕上打印2个字符,再返回2
第⼆个printf打印2,在屏幕上打印1个字符,再放回1
第⼀个printf打印1
所以屏幕上最终打印:4321

最后的最后,如果觉得文章写的还不错的话,请多多点赞。你们的认可是我前进和分享知识的动力之一。🙏🙏🙏

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

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

相关文章

HashMap第2讲——put方法源码及细节

上篇文章介绍了HashMap在JDK 1.8前后的四大变化&#xff0c;今天就进入到put方法的源码解析。HashMap的设计非常巧妙&#xff0c;细节也很多&#xff0c;今天来看看部分细节&#xff0c;后续的文章会一一介绍。 ps&#xff1a;学习源码的目的不仅仅是为了了解它的运行机制&…

Java——Stream流(2/2):Stream流的中间方法、终结方法(方法、案例演示)

目录 Stream流的中间方法 方法 案例演示 Stream流的终结方法 方法 案例演示1 收集 案例演示2 Stream流的中间方法 方法 中间方法指的是调用完成后会返回新的Stream流&#xff0c;可以继续使用(支持链式编程)。 Stream提供的常用中间方法说明Stream<T> filter(P…

Ansible部署 之 zookeeper集群

简介 Ansible是近年来越来越火的一款轻量级运维自动化工具&#xff0c;主要功能为帮助运维实现运维工作的自动化、降低手动操作的失误、提升运维工作效率。常用于自动化部署软件、自动化配置、自动化管理&#xff0c;支持playbook编排。配置简单&#xff0c;无需安装客户端&am…

【小白专用 已验证24.5.30】ThinkPHP6 视图

ThinkPHP6 视图 模板引擎支持普通标签和XML标签方式两种标签定义&#xff0c;分别用于不同的目的 标签类型描述普通标签主要用于输出变量、函数过滤和做一些基本的运算操作XML标签也称为标签库标签&#xff0c;主要完成一些逻辑判断、控制和循环输出&#xff0c;并且可扩展 c…

keil下载及安装(社区版本)

知不足而奋进 望远山而前行 目录 文章目录 前言 Keil有官方版本和社区版本&#xff0c;此文章为社区版本安装&#xff0c;仅供参考。 1.keil MDK 2.keil社区版介绍 3.keil下载 (1)打开进入登录界面 (2)点击下载,跳转到信息页面 (3)填写个人信息,点击提交 (4)点击下载…

基于web的垃圾分类回收系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;公告管理&#xff0c;运输管理&#xff0c;基础数据管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;运输管理&#xff0c;公告…

Web安全:Web体系架构存在的安全问题和解决方案

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

Python算法于强化学习库之rlax使用详解

概要 在强化学习领域,开发和测试各种算法需要使用高效的工具和库。rlax 是 Google 开发的一个专注于强化学习的库,旨在提供一组用于构建和测试强化学习算法的基础构件。rlax 基于 JAX,利用 JAX 的自动微分和加速计算功能,使得强化学习算法的实现更加高效和简洁。本文将详细…

植物大战僵尸杂交版2.0.88最新版安装包

游戏简介 游戏中独特的杂交植物更是为游戏增添了不少亮点。这些杂交植物不仅外观独特&#xff0c;而且拥有更强大的能力&#xff0c;能够帮助玩家更好地应对游戏中的挑战。玩家可以通过一定的条件和方式&#xff0c;解锁并培养这些杂交植物&#xff0c;从而不断提升自己的战斗…

SpringBoot:SpringBoot中使用Redisson实现分布式锁

一、前言 Redisson是一个在Redis的基础上实现的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它不仅提供了一系列的分布式的Java常用对象&#xff0c;还提供了许多分布式服务。 刚好项目中需要使用到分布式锁&#xff0c;记录一下Redisson是如何使用分布式…

SpringBoot+Vue幼儿园管理系统(前后端分离)

技术栈 JavaSpringBootMavenMyBatisMySQLVueElement-UI 系统角色 教师用户管理员 功能截图

C++ STL - 容器

C STL&#xff08;标准模板库&#xff09;中的容器是一组通用的、可复用的数据结构&#xff0c;用于存储和管理不同类型的数据。 目录 零. 简介&#xff1a; 一 . vector&#xff08;动态数组&#xff09; 二. list&#xff08;双向链表&#xff09; 三. deque&#xff08…

k8s Pods漂移时间配置

默认为300秒 apiVersion: apps/v1 kind: Deployment metadata:name: my-test spec:replicas: 1selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: my-containerimage: nginx:latestports:- containerPort: 80tolerations:- key: &…

LabVIEW传感器虚拟综合实验系统

LabVIEW传感器虚拟综合实验系统 开发了一个基于LabVIEW的传感器虚拟综合实验系统&#xff0c;该系统集成了NIELVIS和CSY系列传感器实验平台&#xff0c;通过图形化编程语言进行数据处理和实验管理。系统允许用户进行多种传感器参数的测量和实验报告的自动生成&#xff0c;支持…

使用DLL还是通讯协议进行LabVIEW设备集成

在使用LabVIEW进行设备集成时&#xff0c;可以选择通过设备提供的DLL或直接使用通讯协议。选择方法取决于开发效率、性能、灵活性和维护成本等因素。本文将从这几个方面详细分析两种方法的优劣&#xff0c;帮助做出最佳决策。 分析角度 1. 开发效率&#xff1a; DLL&a…

全能大模型AIGC产品的使用体验、选择倾向与未来展望

随着人工智能技术的迅猛发展&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;领域正迎来前所未有的繁荣。其中&#xff0c;全能大模型产品以其强大的生成能力和广泛的应用场景&#xff0c;吸引了众多用户的关注。腾讯元宝APP的上线更是为这一领域注入了新的活力。本文…

Echarts柱状图数据太多,自定义长度之后,自适应浏览器缩放

不知道是不是最优解&#xff0c;但是当前解决了我遇到的问题&#xff0c;如有更好的方法&#xff0c;希望看到这篇文章的同学可以不吝指导一番&#xff0c;非常感谢 1、问题描述&#xff1a; 因Ecahrts柱状图数据有时多有时少&#xff0c;所以在数据达到一定程度之后&#xff…

spring mvc 中怎样定位到请求调用的controller

前言 在java web开发过程中&#xff0c;正常情况下controller都是我们自己写的&#xff0c;我们可以很方便的定位到controller的位置。但是有些时候我们引入的其他依赖中可能也有controller&#xff0c;为了找到并方便的调试jar包中的controller&#xff0c;我们一般会进行全局…

【CMake系列】10-cmake测试集成googletest与第三方库自动化构建

cmake测试&#xff0c;使用ctest 可能不能满足我们的需求&#xff0c;需要我们使用更为强大的第三方测试框架&#xff0c;如googletest&#xff0c;完成项目中的测试工作 本篇文章将第三方测试框架 googletest&#xff0c;引入&#xff0c;同时也可以作为 关于 第三方包 自动化…

Nginx编译安装,信号,升级nginx

编译安装nginx&#xff1a;前面博客有写编译安装过程 systemctl stop firewalld setenforce 0 mkdir /data cd /data wget http://nginx.org/download/nginx-1.18.0.tar.gz tar xf nginx-1.18.0.tar.gz cd nginx-1.18.0/ yum -y install make gcc pcre-devel openssl-devel …