函数递归VS操作符深入?

1>>前言

函数递归函数递归,当小白听到这样的词会感到无比陌生,请不要惊慌,这是正常的,以至于都不是很经常用到,但是它的算法,它的思想是值得我们深入思考的 。还有一些复杂操作符,如按位与按位或等等,今天一并说说,希望大家能学到东西

2>>函数递归

函数的递归分为递推与回归,就是将一个重复的事情逐渐化小 ,这就叫递推,类似于高等数学的微分,回归就是将缩小的事情再放大,这就是回归,类似于积分。这里我们给出一个题目,输入一个数,使用函数递归求出该数阶乘。我们借助题目能更好理解递归的概念。

2.1>>附:阶乘概念

首先我们需要知道,阶乘是从1开始逐步乘到需要的数,如5的阶乘就是1*2*3*4*5。 3的阶乘就是1*2*3,用3!表示,6的阶乘就用6!表示。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。1808年,基斯顿·卡曼引进这个表示法。亦即n!=1×2×3×...×(n-1)×n。

2.2>>递推

在我们了解了阶乘的概念后,我们就可以引入递推了,将大事化小,如5的阶乘可以写作5*4!而4的阶乘可以写作4*3!这里以此类推,可以发现n!=n*n(-1)!那么我们将它代入函数就可以做到递推,这边看代码,然后我放一张图具体解释同学们就懂了。

cpp 复制代码
#include<stdio.h>
//题目:输入一个数,使用函数递归求出该数的阶乘。 

int Fact(a)
{
	if (a<=0) 
		return 1;
	else
		return a*Fact(a-1);
}

int main()
{
	int a=0;
	scanf("%d",&a);
	int c=Fact(a);
	printf("%d\n",c);
	return 0;
}

这里我们计算5的阶乘为例子,a=5进入Fact函数,因为a>0所以进入else语句

​这里5进来又遇到了函数Fact,此时把4代入以此类推,直到a=0开始返回数值。

2.3>>回归

开始返回值时并不是一下子返回到主函数,而是像前面的递推一样,一步步回归

先从1返回到上一步执行的函数,相当于1*0!,而0的阶乘又是1,所以相当于1*1

接下来又返回1,而此时a是2,相当于2*1的阶乘,以此类推我们可以得到

5的阶乘为120,这就是函数的递归。

2.4>>个人感觉

函数的递归在C语言中并不是很常用,主要还是使用迭代,也就是循环,当然递归我也感觉很神奇,很多题目我都想尝试使用递归去做,但我现在能力还不够,也可能是递归只有在一些特定场景下才能使用,才能发挥它的无穷力量!

3>>操作符的深入

操作符这边会讲到按位与&,按位或|,按位异或^,还有按位取反~的用法。

3.1>>补充:进制转换

首先我们需要知道十进制如何转换为二进制的,十进制整数转换为二进制整数采用"除2取余,逆序排列 "法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数。如此进行,直到商为小于1时为止 ,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。如13,我们除2得到6余1 ,6除2得到3余0 ,3除2得到1余1 ,最后余1 ,然后将余数逆序排列得到1101这就是13的二进制数。

要进行转换也很简单二进制数1111每个代表的分别是8421,每往左边一个1就乘2,若10000这个1就代表16。而1101就是对应十进制数相加,就是8+4+1=13.

3.2>>补充:原码、反码、补码的概念

知道了进制转换现在我们就可以知道13的原码(这边注意正数原码反码补码三者相同 ,负数反码按位取反但是符号位不变(取反的意思就是0为1,1为0),补码则为反码+1)13的原码为:0000 0000 0000 0000 0000 0000 0000 1101,这里要32位二进制数,代表整形四个字节,那么再举一个例子(这里注意正负数的二进制位第一位为符号位,1为负数,0为正数

-1的原码为:1000 0000 0000 0000 0000 0000 0000 0001

-1的反码为:0111 1111 1111 1111 1111 1111 1111 1110

-1的补码为:1111 1111 1111 1111 1111 1111 1111 1111

到这里,大家对原码反码补码的概念应该清楚一点了。接下来讲解操作符。

3.3>>按位与&,按位或|,按位异或^,按位取反~

按位与&的用法就是两1为1,其余情况为0 ,如101 & 111 结果就是 101,可以理解为:多选题,全选对了则是对。

按位或|的用法就是有一个1就是1,两0才为0 ,如100 | 001 结果就是101,可以理解为:我现在是个渣男/渣女,需要买一个金戒指,不管备胎一号出钱还是备胎二号出钱,只要有一个出钱我都能买到,哈哈哈这就是按位或。

按位异或^的用法就是相同则0,不同则1 ,如111 ^ 001 结果就是110,可以理解为:抄作业,你抄我的我两答案都一样,OMG的雷同卷,判0分,我们一起g了,所以相同为0,不同为1。

按位取反比较简单,~111 结果就是000。

3.4>>巩固知识

理清了它们的概念我们就来做一下题目巩固一下知识:输入一个数,计算该数转换为二进制后有多少个1。

cpp 复制代码
#include<stdio.h>
//输入一个数,计算该数转换为二进制后有多少个1
int main()
{
	int a=0;
	int count=0;
	scanf("%d",&a);
	while(a)
	{
		a=a & (a-1);
		count++; 
	}
	printf("%d\n",count);
	return 0;
}

这里来解析一下代码(注意运算都是用该数的补码运算):假设我们的a是13它的原码反码补码相同为0000 0000 0000 0000 0000 0000 0000 1101,a-1为0000 0000 0000 0000 0000 0000 0000 1100,此处省略前面的0,来对比1101和1100,这两个逻辑与结果就是1100,在循环,1100和1100-1即1011逻辑与又得到1000,这样每次逻辑与完都去掉最右边的一个1,简直妙哉,最终a为0退出循环,打印结果。

这时就有人说了,例子都是正数,能不能来个负数,好的安排!

这里可以看到结果为32个1,为什么呢?不急我们先来看看-1的原码反码补码:

-1的原码为:1000 0000 0000 0000 0000 0000 0000 0001

-1的反码为:0111 1111 1111 1111 1111 1111 1111 1110

-1的补码为:1111 1111 1111 1111 1111 1111 1111 1111

注意:补码取反加一也能得到原码

使用补码进行计算,-1的结果为:1111 1111 1111 1111 1111 1111 1111 1110逻辑与完就是0111 1111 1111 1111 1111 1111 1111 1111,以此类推我们能得到32次运算,是不是很神奇!

4>>结语

今天带来的是递归和操作符部分的深入讲解,函数递归在未来学算法估计会经常用到,原码反码补码对于未来学单片机和嵌入式的同学也很有帮助 ,另外:把自己所学的知识分享给大家,可以说是非常的舒服,感觉心灵受到了浇灌。小编要学习的地方还有很多,请大家多多指教,谢谢大家!

相关推荐
To_OC7 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
Scott9999HH7 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
2401_841495648 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海8 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨10 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a11177611 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao11 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest