C语言递归Dec转Bin函数并将结果保存为字符串

Recursive Dec to Bin Function and saving the results in a string in C language

我有以下练习:

Write a recursive function recDecToBin that takes 2 arguments as input. The first is a natural number that needs to be converted into a binary number system. The second is a string where the result should be saved.

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

#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;           
}

你真的不需要全局变量。此外,全局变量在某种程度上欺骗了参数的数量,并使该函数只能使用一次。所以你不喜欢那个是有道理的。

没有它,您的解决方案可以浓缩为

void recDecToBin(int n, char* result){
    if(n<2){
        strcpy(result, n?"1":"0");
    } else {
        recDecToBin(n/2, result); // recursive call
        strncat(result, n%2?"1":"0", 1);      // adding the results
    }
}

(else分支等同于你的,重点是if (n<2))

Is there a better method to deal with the memory and keep tracking of the storing location?

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

虽然在这种情况下,您知道输出的最大大小。它将是 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] = '[=10=]';
puts(bin_str);

可选择删除前导零:

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

这也去掉了一些不必要的分支。