函数递归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>>结语

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

相关推荐
凌肖战3 分钟前
力扣上刷题之C语言实现(数组)
c语言·算法·leetcode
编程版小新3 分钟前
C++初阶:STL详解(四)——vector迭代器失效问题
开发语言·c++·迭代器·vector·迭代器失效
c4fx23 分钟前
Delphi5利用DLL实现窗体的重用
开发语言·delphi·dll
秋夫人29 分钟前
B+树(B+TREE)索引
数据结构·算法
李小星同志32 分钟前
高级算法设计与分析 学习笔记6 B树
笔记·学习
霜晨月c43 分钟前
MFC 使用细节
笔记·学习·mfc
鸽芷咕1 小时前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
Jhxbdks1 小时前
C语言中的一些小知识(二)
c语言·开发语言·笔记
java6666688881 小时前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存1 小时前
源码分析:LinkedList
java·开发语言