作为练习的一部分,我必须重写一个递归函数,以便新函数不是递归的。这两个函数都需要将正十进制整数输入转换为其二进制等效项。
这是使用递归的代码:
void convert(int n) { //recursive
if (n > 0) {
convert(n/2);
printf("%d", n%2);
}
return;
}
这是我的代码:
void convert(int n) { //non-recursive
while (n > 0) {
printf("%d", n%2);
n/=2;
}
return;
}
我的代码的问题在于,可以理解的是,我的二进制转换被向后打印出来。例如,如果我输入数字 8,我的函数返回 0001,如果我输入 2,则返回 01,依此类推。
仅使用 stdio.h
库进行快速修复的任何建议?
下面是一个非递归版本,它产生与递归版本相同的结果,并且不需要数组:
void convert(int n) {
int s;
for (s = 1; n/s/2 > 0; s *= 2)
;
for (; s >= 1; s /= 2) {
printf("%d", (n/s) % 2);
}
}
此版本处理零和大数(但不能处理负数)。
您可以在一个循环中执行此操作:
if(num == 0) {
printf("0n"); // Check for num being 0.
return;
}
num = num < 0 ? num*-1 : num; // Make sure the number has no sign bit.
char first1Found = 0; // Create a check for the first 1 printed.
for (int i = sizeof(num)*8 - 1; i >= 0 ; --i) {
if (num & (1 << i)) { // If its a 1, print it and set the first1Found bool.
printf("1");
first1Found = 1;
} else if(first1Found) { // If its a 0 only print it if its not a leading 0.
printf("0");
}
}
printf("n");
这是一个活生生的例子。
注意:我通过假设 sizeof
返回类型中的字节来使用 8。并非所有系统和编译器都是如此(尽管应该如此)。一种更便携的方法可能是按照@chux的建议使用<limits.h>
中的CHAR_BIT
。
这是一个明确关于使用位掩码并将掩码的位置从上端向下移动的变体。 它的行为类似于您的递归版本,因为它不做负数或零。
void convert(int n) {
for(int mask = 1 << (8 * sizeof(n) - 2); mask > 0; mask >>= 1) {
if (mask <= n) {
putchar((n & mask) ? '1' : '0');
}
}
putchar('n');
}
@Tom Karzes 精细答案的 C99 变体,处理包括INT_MIN
在内的所有 + 和 - 值。
void convertm(int n) {
if (n < 0) {
putchar('-');
} else {
n = -n;
}
// Build up a negative power-of-2 that meets/exceeds `n`
int npow2;
for (npow2 = -1; n/2 <= npow2 ; npow2 *= 2)
;
// For each negative power-of-2 ...
while (npow2) {
putchar(n / npow2 + '0');
n %= npow2;
npow2 /= 2;
}
puts("");
}
打印无符号值的无填充二进制表示形式(任何能够适应long unsigned
的大小)的可靠方法是:
/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
if (!v) { putchar ('0'); return; };
size_t sz = sizeof v * CHAR_BIT;
unsigned long rem = 0;
while (sz--)
if ((rem = v >> sz))
putchar ((rem & 1) ? '1' : '0');
}
(CHAR_BIT
(通常8
)以limits.h
提供)。你不需要"使用limits.h
——这只是通常找到它CHAR_BIT
的地方。你所需要的只是一个常量,你可以随心所欲地称呼它。我通常只使用:
/* CHAR_BIT */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif