Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从dec转换为bin的函数,由3行组成,需要解释_C - Fatal编程技术网

从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,则重复
假设给定一个以10为基数的数字,我们可以除以10。余数和被除数分别是最低有效位和移位一位的数字。这也适用于二进制:然而,我们不是除以10,而是除以2

基本上,算法是这样的:

  • 打印最低有效数字
  • 将数字移到一位数以上
  • 如果数字大于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.               |
                 |                           |
                 |                           |
                 +------>------>------>------+