我需要对以下代码进行一些解释:
用于将十进制数转换为二进制数代码: 它来自一个教程,但它让我很困惑。
void binary(int);
void main(void) {
int number;
cout << "Please enter a positive integer: ";
cin >> number;
if (number < 0)
cout << "That is not a positive integer.\n";
else {
cout << number << " converted to binary is: ";
binary(number);
cout << endl;
//cin.get();
}
}
void binary(int number) {
int remainder;
if(number <= 1) {
cout << number;
return;
}
remainder = number%2;
binary(number >> 1);
cout << remainder;
//cin.get();
}
我使用断点来观察数据通过程序,但最后我无法遵循它。
我所看到的:
需要一个数字,如果数字&lt; = 1,则打印该数字(0或1)。
但在此之前,它首先计算该数字的模数并将其置于余数中。 然后它向数字右侧移动一点或相同,直到数字小于或等于1.
但是它会多次保持“cout rest”(取决于计算的0/1) 但这怎么可能呢? 余数是缓冲区吗? (我认为它会被覆盖(因为它是int),但它看起来像是不断添加位然后再打印几次)???
有人能慢慢向我解释这个吗?
答案 0 :(得分:1)
不会覆盖int,因为它[int]会在每次递归调用函数binary()
时被重新分配为自动变量,所以如果你调用它{{递归1}}次,实际为n
分配n
个int
个。{/ p>
因此,它被“记住”,因为它们是不同的局部变量。分配通常在调用堆栈上进行
工作原理:让我们看看一个例子的堆栈:remainder
:
binary(5)
现在,您使用|number=5, remainder = 1|
-------------------------
binary()
number = 5/2=2
再次使用|number=2, remainder = 0|
|number=5, remainder = 1|
-------------------------
现在,您使用number = 2/2 = 1
重新加注binary()
,然后获取:
number = 5/2=2
现在,停止条件为真,因为|number=1, remainder = 1|
|number=2, remainder = 0|
|number=5, remainder = 1|
-------------------------
- ,所以你打印number <= 1
[这是1]并弹出调用堆栈中的第一个元素:
number
并打印0,因为它是调用堆栈顶部的余数。
并对调用堆栈中的下一个“元素”执行相同的操作:
|number=2, remainder = 0|
|number=5, remainder = 1|
-------------------------
并打印最后一个余数,1。
答案 1 :(得分:0)
任何数字都可以写为sum(ai*2^i)
和sum(bi*10^i)
。
我将解释小数,因为它更清楚。鉴于12345,
要检索数字,你可以
12345 % 10 = 5 (op1)
12345 / 10 = 1234.5 = 1234 in a int (op2)
1234 % 10 = 4 (restart)
1234 / 10 = 123.4 = 123 in a int
等...
在这种情况下
op1 is equivalent to remainder = number%2; (modulo by the base)
op2 is equivalent to number >> 1; (division by the base. bitshifting is division by 2)
restart
表示重新启动除法结果。这就是为什么我们有一个递归
使用binary(number >> 1);
调用假设我在基数2中使用abcdef
调用此函数。
binary(abcdef)
binary(abcde)
binary(abcd)
binary(abc)
binary(ab)
binary(a)
cout << number;//a
cout << remainer;//b
cout << remainer;//c
cout << remainer;//d
cout << remainer;//e
cout << remainer;//f
答案 2 :(得分:0)
由于binary
是一个递归函数,你会发生类似这样的事情(每个缩进都是一个额外的递归级别):
binary call #0
calculate remainder0
recursive binary call #1
calculate remainder #1
recursive binary call #2
calculate remainder #2
recursive binary call #3
print number
print remainder #2
print remainder #1
print remainder #0
递归仅使用 以相反的计算顺序打印剩余部分,如上所示。不要与number
参数混淆 - 无论是否在每次递归调用中复制它都无关紧要。你也可以使用一个全局变量,并且它可以工作(然后,它将被“就地修改”,这就是你所说的“覆盖”)。
重要的一点是,对于每次递归调用,原始数字向右移一位,这就是number
参数的所有内容。
这是无等效的递归:
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
string binary(int);
int main(void) {
int number;
cout << "Please enter a positive integer: ";
cin >> number;
if (number < 0)
cout << "That is not a positive integer.\n";
else {
cout << number << " converted to binary is: ";
cout << binary(number) << endl;
}
return 0;
}
string binary(int number) {
stringstream ss;
do {
ss << number % 2;
number >>= 1;
} while (number >= 1);
string s = ss.str();
reverse(s.begin(), s.end());
return s;
}