返回模数的解释

时间:2012-03-17 09:18:12

标签: c++ if-statement modulo

我需要对以下代码进行一些解释:

用于将十进制数转换为二进制数代码: 它来自一个教程,但它让我很困惑。

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),但它看起来像是不断添加位然后再打印几次)???

有人能慢慢向我解释这个吗?

3 个答案:

答案 0 :(得分:1)

不会覆盖int,因为它[int]会在每次递归调用函数binary() 时被重新分配为自动变量,所以如果你调用它{{递归1}}次,实际为n分配nint个。{/ 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;
}