首页 > 解决方案 > 递归 Dec 到 Bin 函数并将结果保存在 C 语言中的字符串中

问题描述

我有以下练习:

编写一个递归函数 recDecToBin,它接受 2 个参数作为输入。第一个是自然数,需要转换成二进制数系统。第二个是应保存结果的字符串。

我写了以下解决方案,但我不喜欢它。有没有更好的方法来处理内存并跟踪存储位置?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int Global = 0;  // this global variable helps with case of input 0

void recDecToBin(int n, char* result){
    Global++;
    if(Global == 1 && n == 0){    // if input 0 , results will be 0
        result[0] = '0';    
    } else {
        if (n > 0){
            int dig;
            char *a;
            dig = n % 2;    // 0 or 1 to be written
            if (dig == 1){
                a = "1";
            } else {
                a = "0";
            }
            recDecToBin(n/2, result); // recursive call
            strncat(result,a,1);      // adding the results
        }
    }
}

int main(){
    int n;                // user input
    char result[30]="";   // storing string
    scanf("%d", &n);      // reading input 
    recDecToBin(n, result); // calling the function
    printf("%s", result);  // printing resutls
    return 0;           
}

标签: cstringrecursionbinarydecimal

解决方案


有没有更好的方法来处理内存并跟踪存储位置?

调用者分配是理想的,应该在可行的情况下使用,因为这将两个不相关的函数内存分配和实际算法分开。

但是,在这种情况下,您知道输出的最大大小。8 * sizeof(int)对于空终止符,它将是字符 + 1 个额外的字符。(迂腐CHAR_BIT * sizeof(int)。)所以你可以把函数写成:

void recDecToBin(int n, char result[8*sizeof(int)+1])

这只是自我记录的代码,与char*.

在实现方面,您应该能够摆脱全局变量和缓慢而危险的递归。在一些主流编译器中查看您的代码的反汇编,它们都无法内联您的代码。这是非常低效的,递归主要是罪魁祸首。还要反复strcat来电。

你应该用一个简单易读的循环来编写所有这些:

const size_t size = 8*sizeof(int);
char bin_str [size+1];
unsigned int val = 123456;  

for(size_t i=0; i<size; i++)
{
  bin_str[size-i-1] = (val & 1) + '0';
  val >>= 1;
}  
bin_str[size] = '\0';
puts(bin_str);

可选择删除前导零:

const char* str = strchr(bin_str, '1');
puts(str?str:"0");

这也摆脱了一些不必要的分支。


推荐阅读