2

在这里,我得到了一个以二进制表示形式打印整数的代码

#define BUF_SIZE 33
int main() {
    for (int count = 0; count <=25; count++){

        char buffer[BUF_SIZE];
        buffer[BUF_SIZE - 1] = '\0';

        int2bin(count, buffer, BUF_SIZE - 1);
        printf("%d = %s \n",count, buffer);
    }
}

char *int2bin(int a, char *buffer, int buf_size) {
    buffer += (buf_size - 1);

    for (int i = 31; i >= 0; i--) {
        buffer--;
        *buffer = (a & 1) + '0';
        a >>= 1;
    }

    return buffer;
}

它工作得很好,直到我试图挤压一些代码行替换

int2bin(count, buffer, BUF_SIZE - 1);
printf("%d = %s \n",count, buffer);

printf("%d = %s \n",count, int2bin(count, buffer, BUF_SIZE - 1));

这些日志完全破坏了我的输出:

805306368 = 00000000000000000000000000000000
805306369 = 00000000000000000000000000000001
805306370 = 00000000000000000000000000000010
805306371 = 00000000000000000000000000000011
805306372 = 00000000000000000000000000000100
805306373 = 00000000000000000000000000000101

等等...

你能解释一下为什么吗?

4

6 回答 6

4

乍一看,似乎-1不需要int2bin()第一个(因为循环以一个 -1 开始)

有关解释,请参阅 Scott Mermelstein 的答案

于 2013-04-12T14:04:42.920 回答
4

首先,可以肯定的是,问题不在于printf. 让我们假设 printf 工作正常。那么结论是你正在向它传递不同的输入。使用它,让我们详细看看你在做什么。

在您的两行示例中,它之所以有效,是因为您传入了缓冲区。可能是在您的单行示例中,您传递的地址不是缓冲区吗?

好吧,在 int2bin 中,您添加buf_size - 1,然后通过 32 个(从 31 到 0 包括在内)数字进行运算,因此应该返回buffer,对吗?

错误的。

你传入32。然后你BUF_SIZE - 1从中int2bin减去 1,所以你添加 31 而不是 32,因此,不返回缓冲区。

观察这一点的简单方法:在函数开始时打印缓冲区的地址,在函数结束时打印缓冲区的地址。

简单的修复:

  • 您可以将 int2bin 的第一行设置为buffer += BUF_SIZE - 1.
  • 您可以简单地保存buffers 原始值并将其返回
  • 您不能在 for 循环中使用看似任意的硬代码,而是设置i = buf_size.

基本上,epatel 的第一眼答案是正确的。我的回答只是提供了更多细节。

于 2013-04-12T14:11:55.257 回答
3

int2bin中,您用“0”覆盖缓冲区之前的字节。编译器在此位置放置了 printf 的参数“ count ”。

只需在通话中删除“-1”

printf("%d = %s \n",count, int2bin(count, buffer, BUF_SIZE));

由 805306368 是二进制

00110000 00000000 00000000 00000000

00110000 = 48 = '0'

您的代码中还有一个缺陷,循环计数取决于 buf_size!我建议以这种方式重写它。

#define BUF_SIZE sizeof(int)
int main() {
  for (int count = 0; count <=25; count++){

    char buffer[BUF_SIZE + 1];
    buffer[BUF_SIZE] = '\0';

    int2bin(count, buffer, BUF_SIZE);
    printf("%d = %s \n",count, buffer);
  }
}

char *int2bin(int a, char *pBuffer, int buf_size) {
   char *buffer = pBuffer + buf_size;

   for (int i = buf_size; i > 0; i--) { // loop count depends on buf_size!!!
     buffer--;
     *buffer = (a & 1) + '0';
     a >>= 1;
   }

   return pBuffer;
}
于 2013-04-12T14:16:33.370 回答
2

您必须将该函数称为

int2bin(count, buffer, BUF_SIZE)

否则该函数将从buffer minus 1byte(这是一个在内存中放置一些垃圾的下溢)写入位字符到buffer + 31 bytes

于 2013-04-12T14:12:43.430 回答
1

您的代码因向下计数循环和“试图变得聪明”而相当晦涩,例如 fishy *buffer = (a & 1) + '0';。位掩码与 ASCII 数字无关,因此不要将它们混合在同一个操作中。尽量让代码简单而不是复杂。这才是你问题的真正根源。

以更易读的方式重写代码,你的错误就会消失。

#include <stdio.h>
#include <stdint.h>

void int_to_bin (char bin[32+1], uint32_t val)
{
  for(int i=0; i<32; i++)
  {
    uint32_t mask = 1 << (32 - 1 - i); // -1 to compensate for zero indexing

    if( (val & mask) != 0)
    {
      bin[i] = '1';
    }
    else
    {
      bin[i] = '0';
    }
  }

  bin[32] = '\0';
}



int main()
{
  char buf[32+1]; 

  int_to_bin(buf, 0xAAAA);
  puts(buf);
  int_to_bin(buf, 0xCAFEBABE);
  puts(buf);
  int_to_bin(buf, 0x12345678);
  puts(buf);
}
于 2013-04-12T14:37:49.050 回答
0

除了任何可能有问题的地方buffer_size(其他答案已经详细解释了这一点)。最简单的解决方法是添加

#include <stdio.h>

char * int2bin(int a, char * buffer, int buf_size);

到代码的顶部。这确实使它编译并为我工作。两者都有

int2bin(count, buffer, BUF_SIZE - 1);
printf("%d = %s \n",count, buffer);

printf("%d = %s \n", count, int2bin(count, buffer, BUF_SIZE));
于 2013-04-12T14:18:26.500 回答