c语言(函数)

news2025/1/23 9:29:01

目录

何为函数

库函数

自定义函数

二分查找数组下标

链式访问

 函数的声明 

函数定义

递归

正向打印数字 

打印字符个数

使用临时变量

递归(不使用临时变量)

n的阶乘

一般形式

递归

斐波那契数

递归

正常做法


何为函数

        在计算机科学中,子程序是一个大型程序中的某部分代码, 由一个或多个语句块组
成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软
件库。

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

库函数

  • 库函数只提供函数名,参数,功能,返回类型,实现则由编译器厂商实现。
  • 库函数的使用需要包含对应的头文件。
  • c/c++库函数官网:https://cplusplus.com/

自定义函数

实际很多情况我们不能靠库函数解决,所以就诞生了自定义函数,我们可以自己实现内部细节和功能。

现在实现一个交换函数:

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

运行结果:

 为什么没有实现交换功能呢?

 我们可以看到它们的地址都不一样,所以没能实现交换,我们称传递的参数为实参,接收的参数为形参形参是实参的拷贝形参的建立与销毁只在调用函数的过程发生。所以它的交换只在函数体内。

void Swap(int* x, int* y)
{
	int z = 0;
	z = *x;
	*x = *y;
	*y = z;
}

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

我们传递地址,这样就可以实现交换功能了。

二分查找数组下标

我们利用一组数据有序的特点,这次我们试着用函数的方式封装二分查找这一功能。

找7,发现找不到,这是为什么呢?我们来看函数部分:

  通过调试发现,这里的right始终为0,这就是问题所在了,在c语言中,数组的传参是传递的指针而非整个数组,这是因为可以通过首元素地址找到整个下组,从而减少了不必要的开销

 完整代码:

	
int binary_search(int *arr, int k,int right)
{
	int left = 0;
	
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			return mid;//找到了
		}
	}
	return -1;//找不到
}
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int k = 7;
	int right = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr, k,sz);

	if (-1 == ret)
		printf("找不到\n");
	else
		printf("找到了,下标是:%d\n", ret);
}

函数允许嵌套调用,不允许嵌套定义。 

链式访问

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

比如printf函数的返回值是字符的个数:

 函数的声明 

函数的声明一般是包含在.h文件里,用于综合性的工程里。

//函数定义
int Add(int x, int y);
int Add(int, int);

如果我们创建一个add.h的头文件,里面写上函数的声明,我们可以这样包含达到使用我们自己的“库”的效果。

#include "add.h"

当然,如果你不小心将函数的定义放在了main函数后,你也可以这样使用:

int main()
{
    int Add(int, int);
	Add(a,b);
    return 0;
}
int Add(int a, int b)
{
	//..
}

函数定义

同理,我们可以把函数的定义放在.c文件里。

同时,要想不让人知道函数的具体实现过程,我们可以通过打包静态库的方式隐藏自己的函数文件。

递归

顾名思义,递归的核心是大事化小,通过一次一次迭代,达到最终效果的过程。

正向打印数字 

我们知道反向打印4个数可以:

1234%10 = 4;
1234/10 = 123;
123%10 = 3;

那正向怎么做呢,在知道我们可以轻松拿到它的末尾数字时,我们是不是可以反向思考一下?

123 (4)
12 (34)
1 (234)
void Print(unsigned int n)//1
{
	if (n > 9)
	{
		print(n / 10);
	}
	printf("%d ", n % 10);
}
void Print(unsigned int x)//2
{
	if (x < 10)
	{
		printf("%d ", x);
	}
	else
	{
		Print(x / 10);
		printf("%d ", x % 10);
	}
}

调用了4次函数,开辟了4次函数栈帧,在打印后返回上一层栈帧并销毁空间。 

  • 递归必须有限制条件
  • 每次递归会逐渐靠近这个限制条件

打印字符个数

使用临时变量

int my_strlen(char* s)
{
	int count = 0;
	while (*s != '\0')
	{
		count++;
		s++;
	}
	return count;
}

递归(不使用临时变量)

同理,例如一个字符串abc拆分成1+bc,1+1+c,1+1+1+0的形式。 

int my_strlen(char* str)
{
	if (*str != '\0')
		return 1 + my_strlen(str + 1);
	else
		return 0;
}

注意这里最好不要用前置++,它改变了数组的地址。 

n的阶乘

阶乘公式 :

  • n<=1,1
  • n>1,Fac(n-1) * n 

一般形式

int Fac(int n)
{
	int i = 0, ret = 1;
	for (i = 1;i <= n; i++)
	{
		ret = ret * i;
	}
	return ret;
}

递归

int Fac(int n)
{
	if (n <= 1)
	{
		return 1;
	}
	else
		return Fac(n - 1) * n;
}

斐波那契数

1 1 2 3 5 8 13 .... 像这样前两个数加起来等于后一个数的数列叫做斐波那契数列。

递归

公式:

n<=2, n = 1
n>2, Fib(n-1) + Fib(n-2)

int Fib(int n)
{

	if (n <= 2)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}

测试: 

测试发现计算一个稍微大点的数据半天计算不出来结果,可以得知递归的层次已经很深了,就像一张很深的数 一样。

 

正常做法

在数字超出两个时,我们可以用两个变量求和计算第三个变量,依次更新,达到想要的效果。

int Fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 0;
	if (n <= 2)
	{
		return 1;
	}
	if (n > 2)
	{
		while(n>2)
		{
			c = a + b;
			a = b;
			b = c;
			n--;
		}
		return c;
	}
}

用这种方法几乎是一瞬间得出了结果,不过注意数据太大可能会超出范围。 

总之,递归的使用需要我们多去总结和感悟,并选择最合适的方法 。

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

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

相关文章

医疗知识图谱问答——文本分类解析

前言 Neo4j的数据库构建完成后&#xff0c;现在就是要实现医疗知识的解答功能了。因为是初版&#xff0c;这里的问题解答不会涉及深度学习&#xff0c;目前只是一个条件查询的过程。而这个过程包括对问题的关键词拆解分类&#xff0c;然后提取词语和类型去图数据库查询&#xf…

pytorch学习——如何构建一个神经网络——以手写数字识别为例

目录 一.概念介绍 1.1神经网络核心组件 1.2神经网络结构示意图 1.3使用pytorch构建神经网络的主要工具 二、实现手写数字识别 2.1环境 2.2主要步骤 2.3神经网络结构 2.4准备数据 2.4.1导入模块 2.4.2定义一些超参数 2.4.3下载数据并对数据进行预处理 2.4.4可视化数…

TSINGSEE青犀视频智能视频监控EasyCVR如何将实时监控视频流分享出去?

开源EasyDarwin视频监控平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;…

【深度学习】Vision Transformer论文,ViT的一些见解《 一幅图像抵得上16x16个词:用于大规模图像识别的Transformer模型》

必看文章&#xff1a;https://blog.csdn.net/qq_37541097/article/details/118242600 论文名称&#xff1a; An Image Is Worth 16x16 Words: Transformers For Image Recognition At Scale 论文下载&#xff1a;https://arxiv.org/abs/2010.11929 官方代码&#xff1a;https:…

【微信小程序】保存多张图片到本地相册

<template><view class"container"><u-swiper :list"list" circular radius0 indicator indicatorModedot height950rpx></u-swiper><view class"btn btn2" click"saveFun">保存到相册</view><…

【MySQL】当前读和快照读

文章目录 当前读快照读 在学习 MVCC 多版本并发控制之前&#xff0c;必须先了解一下&#xff0c;什么是 MySQL InnoDB 下的 当前读和 快照读? 当前读 读取的是记录的最新版本&#xff0c;读取时还要保证其他并发事务不能修改当前记录&#xff0c;会对读取的记录进行加锁。对…

Rocky(centos) jar 注册成服务,能开机自启动

概述 涉及&#xff1a;1&#xff09;sh 无法直接运行java命令&#xff0c;可以软连&#xff0c;此处是直接路径 2&#xff09;sh脚本报一堆空格换行错误&#xff1a;需将转成unix标准格式&#xff1b; #切换到上传的脚本路径 dos2unix 脚本文件名.sh 2&#xff09;SELINUX …

Ubuntu18.04安装ROS

ROS 安装前的准备 &#xff08;1&#xff09;为了安装顺利使用国内下载源&#xff0c;&#xff08;我个人linux使用了代理&#xff09; 清华大学源 sudo sh -c ‘. /etc/lsb-release && echo “deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ $DISTRIB_CODENA…

第四讲:利用ADO方式连接Access数据库

【分享成果&#xff0c;随喜正能量】最值得信赖的&#xff0c;其实是自己从孤独中得来的东西&#xff0c;而不是别人给予自己的东西。每个人都是一座孤岛&#xff0c;有些人一生都在想要逃离这座岛&#xff0c;有些人一生都在创造并丰富自己这座岛。。 《VBA数据库解决方案》教…

水环境地质3D可视化综合管理软件提高运维效率

谈起数字孪生技术&#xff0c;总让人兴奋不已&#xff0c;这种将物理实体的数字化模型与实际物理实体相结合、以虚控实的技术&#xff0c;是数字化转型和第四次工业革命的重要载体&#xff0c;那么在地质行业中&#xff0c;数字孪生有哪些应用场景? 在地质勘探中&#xff0c; …

潜在客户生成最实用指南,你还在等什么?

潜在客户是指对您的产品或服务表现出兴趣的人&#xff0c;它们提供个人识别信息&#xff0c;您的团队可以使用这些信息来跟进他们。随着越来越多的营销渠道涌现&#xff0c;接触新客户和开展有效的潜在客户生成活动变得越来越困难。赢得新的潜在客户听起来很困难&#xff0c;但…

【B/S手术麻醉系统源码】手术麻醉管理系统在临床中的应用

手术麻醉管理系统是临床麻醉工作中一个不容忽视的环节&#xff0c;麻醉医生必须对病人在麻醉手术过程中的情况与体征变化&#xff0c;采取的处理措施及术后随访等全过程作出及时、真实、确切的记录。麻醉记录不仅有助于确保临床麻醉准确&#xff0c;总结经验教训&#xff0c;提…

kcc呼叫中心语音转写功能

呼叫中心是客户和企业之间沟通的一个桥梁&#xff0c;也是客户服务和客户关系的一个重要组成部分。通过呼叫中心&#xff0c;企业可以建立起一个以客户为中心的服务模式&#xff0c;为客户提供高质量、高效率的服务&#xff0c;对于塑造企业形象&#xff0c;提高客户满意度&…

txt替换字符为换行

txt替换字符为换行 txt如何批量将同一个符号替换成换行符 2023-01-26 03:16:03 有时候看到网页有些排列的很整齐的文本想复制使用&#xff0c;可是复制下来放到txt后不分行&#xff0c;要么就是中间隔着一些公用的符号。那么我们怎么才能快速的让文本按原来的形式分行显示在…

一百三十九、Kettle——Linux安装Kettle8.2

一、目的 为了方便海豚调度kettle任务&#xff0c;在Linux上安装kettle 二、kettle版本与前提 版本&#xff1a;kettle8.2 pdi-ce-8.2.0.0-342 前提&#xff1a;Linux已经安装好jdk 三、安装步骤 &#xff08;一&#xff09;打开安装包所在地 [roothurys22 ~]# cd …

让SpringBoot不再需要Controller、Service、DAO、Mapper,卧槽!这款工具绝了

Dataway 是基于 DataQL 服务聚合能力&#xff0c;为应用提供的一个接口配置工具&#xff0c;使得使用者无需开发任何代码就配置一个满足需求的接口。整个接口配置、测试、冒烟、发布&#xff0c;一站式都通过 Dataway 提供的 UI 界面完成。UI 会以 Jar 包方式提供并集成到应用中…

小鹏遭遇“动荡”,自动驾驶副总裁吴新宙离职,现已完成团队过渡

根据最新消息&#xff0c;小鹏汽车的自动驾驶副总裁吴新宙宣布将加入全球GPU芯片巨头英伟达。吴新宙将成为该公司全球副总裁&#xff0c;直接向英伟达全球CEO黄仁勋汇报。小鹏汽车董事长何小鹏和吴新宙本人已在微博上确认该消息&#xff0c;并解释离职原因涉及家庭和多方面因素…

拿捏--->逻辑推断问题(猜凶手+猜名次)

文章目录 猜凶手问题题目描述算法思路代码实现 猜名次问题题目描述算法思路代码实现 猜凶手问题 题目描述 算法思路 代码实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {char killer 0;for (killer A; killer < D; killer){if ((killer ! …

Rpc异步日志模块

Rpc异步日志模块作用 在一个大型分布式系统中&#xff0c;任何部署的分布式节点都可能发生崩溃&#xff0c;试想如果用普通的办法&#xff0c;即先排查哪个节点down掉了&#xff0c;找到down掉的节点后采取调试工具gdb调试该节点&#xff0c;进而排查宕机的原因。这中排查方法…

Redis的缓存、消息队列、计数器应用

目录 一、redis的应用场景 二、redis如何用于缓存 三、redis如何用于消息队列 四、redis如何用于计数器 一、redis的应用场景 Redis在实际应用中有广泛的应用场景&#xff0c;以下是一些常见的Redis应用场景&#xff1a; 缓存&#xff1a;Redis可以用作缓存层&#xff0c;…