Binary 更改为不带数组的二进制文件

Binary 更改为不带数组的二进制文件,binary,bit-manipulation,Binary,Bit Manipulation,我正在尝试在不使用数组的情况下将数字更改为二进制。例如: 当x为7时 打印00000111 我编写的这段代码输出11100000。我很难把它倒过来 int x=7; for (int i = 0; i < 8; i++) { printf("%d", x % 2); x = x / 2; } 由于您不想存储每个数字的临时结果,事实上,您得到的第一个数字将最后打印,这是后进先出。您可以使用递归来模拟类似堆栈的控制流 #include &l

我正在尝试在不使用数组的情况下将数字更改为二进制。例如:

当x为7时 打印00000111

我编写的这段代码输出11100000。我很难把它倒过来

   int x=7;
   for (int i = 0; i < 8; i++) {
        printf("%d", x % 2);
        x = x / 2;
    }

由于您不想存储每个数字的临时结果,事实上,您得到的第一个数字将最后打印,这是后进先出。您可以使用递归来模拟类似堆栈的控制流

#include <stdio.h>


int print_binary(unsigned char x, int num) {
  if ( num == 0) {
    printf("%d",x);  
    return 0;
  }
  print_binary(x/2, num-1);
  printf("%d",x%2);         /* print this digital only after finding other ones */ 
  return 0;
}


int main() {
  char x;
  scanf("%d",&x);
  print_binary(x,7);   /* iteration takes up to 8 times */
}


您可以首先反转初始数字,使其第i位位于位置7-i

这可以通过以下代码完成:

int bit_reverse(char x)
{
   int r=0;
   for (int i=0; i<8; i++){
      r=2*r + x%2;
      x=x/2;
   }
   return r;
}
实际上,该函数使用整数r作为堆栈。通过连续乘以2,将第一个提取的位推向更高的位置

然后,您只需将初始代码应用于返回bit_reverse函数的内容

int main(){
  int x;
  scanf("%d", &x);
  int r=bit_reverse(x);
  int i;
  for(i=0;i<8;i++){
    printf("%d",r%2);
    r=r/2;
  }
  return 0;
}

您的代码中存在多个问题:

您的输入方法中有未定义的行为:scanf格式%d要求地址为int,而x定义为char

您不应该使用char来存储字节值。更好的选择是无符号字符或整数i

您应该测试scanf是否提供了有效的输入

您应该从最高到最低顺序输出位

以下是更正的版本:

#include <stdio.h>

int main() {
    int x;
    if (scanf("%d", &x) == 1) {
        for (int mask = 128; mask != 0; mask = mask / 2) {
            printf("%d", (x & mask) != 0);
        }
        printf("\n");
    }
    return 0;
}

注意:扫描%d,&x;%d格式需要一个指向int的指针作为参数。x是一个字符。您应该查看。您的系统似乎是一个小的endian系统,您需要颠倒扫描循环中变量的顺序。@SimonDoppler:C实现中的endian与此问题无关。如果不使用数组->请注意,代码使用%d,一个字符串文字,这是一个数组。对于像-1或1234567这样的输入,应该有什么输出?或者是a不在乎。负输入导致输出中的“-”,但OP的目标不明确。在这种情况下,是的,我猜范围将是无符号int,并且从定义x为char开始小于256,因此硬编码8步递归,scanf在这种情况下不应使用%d,或者检测到***堆栈破坏***:terminatedchar x;扫描%d,&x;->int x;扫描%d,&x;请考虑启用编译器警告,测试您的代码反向位完全是B0RKEN。事实上,它从来没有结束过。并且%d需要指向int.Right的指针。我纠正了它。我以前应该检查过,没有检查就不能复制过去的OP函数。感谢您报告此问题。我们在2019年,我认为您可以为int mask=128;编写@星门:的确可以。我刚刚编辑了OP的代码,对scanf的成功进行了额外的测试…而你只是为了触发我而做了多重声明;好吧,你的答案是肯定的,但我仍然认为你应该更新你的风格,使之更现代、更安全。@Stargateur:我会为此让步的。但我不喜欢for初始值设定项声明范围:我认为它不扩展到语句末尾是不一致的,就像任何其他块范围定义一样。@chqrlie它实际上是相当一致的-即使、while etc启动它们自己的范围,但它们只是不允许声明。与C++不同,可以在语句块内隐藏变量名称,其中有自己的作用域。