从dec转换为bin的函数,由3行组成,需要解释
我想要一个能准确地解释下面的函数从dec转换为bin的函数,由3行组成,需要解释,c,C,我想要一个能准确地解释下面的函数 void ToBin(int n){ if (n>1) ToBin( n/2 ); printf( "%d", n%2 ); } 例如: 如果输入了7,将发生什么(函数行为)转换为二进制111 请我想一步一步的解释,我明白 编辑 相同的函数,但打印结果更清晰 void ToBin( int n ){ printf("%d/2= %d -> %d\n", n, n/2 ,n%2); if (n>1)
void ToBin(int n){
if (n>1)
ToBin( n/2 );
printf( "%d", n%2 );
}
例如:如果输入了
7
,将发生什么(函数行为)转换为二进制111
请我想一步一步的解释,我明白
编辑
相同的函数,但打印结果更清晰
void ToBin( int n ){
printf("%d/2= %d -> %d\n", n, n/2 ,n%2);
if (n>1)
ToBin( n/2 );
}
特别是第7条:
首先,n=7,所以n>1。因此,在n/2=3时再次调用托宾
现在,n=3,所以n>1。因此,在n/2=1时再次调用托宾
现在,n=1,所以n不大于1。因此,打印1%2=1,控件跳回上一帧
在这里,n=3,3%2=1被打印,控件再次跳回一帧
在这里,n=7,7%2=1被打印出来,当函数离开并且没有更多的托宾帧时,控制返回到最初称为托宾的函数
通常,此功能的工作原理如下:
一个数字的二进制表达式等于该数字一半的下限的二进制表达式,并附加原始数字的最低位
因此,函数会重复获取一半输入的下限的二进制表达式,直到该值为单个位为止。然后,打印该位,即数字的最高有效位,然后按重要性降序打印每个位。您输入7 so
call 1) 7>1 true ,call ToBin(7/2)=ToBin(3.5) , pending print(7%2)=1
call 2) 3>1 true ,call ToBin(3/2)=ToBin(1.5) , pending print(3%2)=1
call 3) 1>1 false ,dont call ToBin(1/2), print(1%2)=1
,
它的递归打印余数(%operation)按以下方式除以2
ToBin()
正在调用自身,直到输入参数n
大于1
2 | 7
------ remainder /|\
2 | 3 ---> 1 | down to top
------ |
| 1 ---> 1 |
-------------------->
如果n为7,则每个级别的递归调用为
1.ToBin(7)--> 2. ToBin(3) --> 3. ToBin(1)
现在返回值,在第一种情况下是1,因为7%2是1
1在第二种情况下为3%2为1,1在第三种情况下也为1%2为1 因此,111是输出
注意:每个递归调用在其堆栈中都有自己的n,因此在第一次调用中n为7,在第二次调用中为3,在第三次调用中为1。函数
ToBin
使用递归(函数调用本身)并使用:
要将一个10进制整数转换为其2进制(二进制)等价数字,该数字除以2,余数为最低有效位。(整数)结果再次除以2,其余数是下一个最低有效位。此过程重复,直到商变为零
递归可能会使其更难理解。首先,请注意,如果我们对语句重新排序:
void ToBin(int n){
printf( "%d", n%2 );
if (n>1)
ToBin( n/2 );
}
它现在将按相反的顺序打印数字。当然,这不是您想要的,但是现在递归调用已经结束,转换为迭代形式就更容易了:
void ToBin(int n) {
do {
printf( "%d", n%2 );
n = n/2;
} while(n > 1);
}
从这段代码中,您可以看到:
- 打印模2的数字
- 将数字除以二
- 如果数字大于1,则重复
- 打印最低有效数字
- 将数字移到一位数以上
- 如果数字大于1,请重复
ToBin(7)
n=7 if(7>1)
ToBin(7/2=3) call ToBin(3)
{
ToBin(3)
n=3 if(3>1)
ToBin(3/2=1) call ToBin(1)
{
ToBin(1)
n=1 if(1>1)
false
print n%2=> 1%2= 1
}
print n%2=> 3%2= 1
}
print n%2=> 7%2= 1
那是
也许你应该找到它的递归方程。要找到一个数字的基-2表示,我们寻找位
b0…bn
n = bn * 2^n + b_(n - 1) * 2^(n - 1) + ... + b1 * 2^1 + b0 * 2^0
现在,我们重点查找b0,b1,…,bn
。注意
(bn * 2^n + b_(n - 1) * 2^(n - 1) + ... + b1 * 2^1 + b0 * 2^0) % 2 = b0
因为b0*2^0%2=b0
和bj*2^j%2=0
当j>=1
时,因为2^j%2=0
如果j>=1
。所以
n = bn * 2^n + b_(n - 1) * 2^(n - 1) + ... + b1 * 2^1 + b0 * 2^0
=> n % 2 = (bn * 2^n + b_(n - 1) * 2^(n - 1) + ... + b1 * 2^1 + b0 * 2^0) % 2 = b0
我们发现b0=n%2
这一关键事实第一
现在,让我们除以2:
n / 2 = (bn * 2^n + b_(n - 1) * 2^(n - 1) + ... + b1 * 2^1 + b0 * 2^0)
= bn * 2^(n - 1) + b_(n - 1) * 2^(n - 2) + ... + b1 * 2^1
现在,我们就到此为止。让我们仔细看看<代码> N/2 的二进制表示。请注意,它与n
的二进制表示形式完全相同,只是最后一位被截断。就是
n = bn b_(n-1) ... b1 b0
n / 2 = b_n b_(n-1) ... b1
这是第二个关键事实
那么,让我们把我们学到的东西放在一起
n
的二进制表示是n/2
的二进制表示,并附加了n
二进制表示的最后一位这是第二个关键事实n%2
来计算n
的二进制表示的最后一位这是第一个关键事实n=0
时。在这种情况下,n
的二进制表示是0
。如果我们尝试使用除以2
的规则,我们永远不会停止除以2。因此,我们需要一个规则,它在n=0
时捕获
因此,要计算n
的二进制表示形式,首先计算n/2
的二进制表示形式,然后附加n%2
的结果,但一定要处理n=0
时的情况。让我们用代码来写:
// print binary representation of n
void ToBin(int n) {
if(n > 1) { // this is to handle zero!
ToBin(n / 2); // this will print the binary representation of n
}
print(n % 2); // this will print the the last digit
}
这是一个递归函数调用。
n%2
基本上只删除整数的最后一位(二进制表示)。(2因为二进制是基数2,所以有两个可能的基数)。n/2
删除最低有效位(通过整数除法),并将其传递到下一个递归级别
因此,每个递归级别都会删减传递的整数的最低有效位,直到在某个级别上整数不是1为止。如果为1,则If
fai
n = bn b_(n-1) ... b1 b0
n / 2 = b_n b_(n-1) ... b1
// print binary representation of n
void ToBin(int n) {
if(n > 1) { // this is to handle zero!
ToBin(n / 2); // this will print the binary representation of n
}
print(n % 2); // this will print the the last digit
}
ToBin (10 = 1010) print 10%2 = 0
| ^
call ToBin (10/2) |
| |
V |
ToBin (5 = 101) print 5%2 = 1
| ^
call ToBin (5/2) |
| |
V |
Tobin (2 = 10) print 2%2 = 0
| ^
call ToBin (2/2) |
| |
V |
ToBin (1 = 1) print 1%2 = 1
| ^
if condition fails, |
| roll back. |
| |
| |
+------>------>------>------+