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");
这也去掉了一些不必要的分支。
我有以下练习:
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");
这也去掉了一些不必要的分支。