【问题标题】:Program that inputs a number and then prints the set bits of that number with the bit integer displayed next to it输入一个数字,然后打印该数字的设置位,并在其旁边显示位整数的程序
【发布时间】:2022-11-01 11:19:54
【问题描述】:

例如,如果我输入 12,我想得到 81 41,因为 12 中的设置位是 1100

这就是我现在所拥有的,我认为我没有正确实现 for 循环

#include <stdio.h>
void bin(unsigned n)
{
    char list[6]; 
    int x = 0, y = 1;
    /* step 1 */
    if (n > 1)
        bin(n / 2);
 
    /* step 2 */
    list[x] = n % 2;
    x++;
    /*for(int i = 0; i < x; i++) {
        printf("%d\n",list[i]);
    }*/
    for(int i = 0; i < 5; i++) {
          if(list[i] == 1 && i == 5) {
           printf("32%i",y);
          }
          if(list[i] == 1 && i == 4) {
             printf("16%i",y);
          }
          if(list[i] == 1 && i == 3) {
             printf("8%i",y);
          }
          if(list[i] == 1 && i == 2) {
             printf("4%i",y);
          }
          if(list[i] == 1 && i == 1) {
             printf("2%i",y);
          }
          if(list[i] == 1 && i == 0) {
             printf("1%i",y);
          }
}
}

我检查了我是否正确地将字节存储在数组中,并且输出正确,但是当我尝试在循环中一次查找一个字节时,它似乎卡在 32 位整数上,所以对于 12,它将打印 321 321

【问题讨论】:

  • 您确定将list[i] = 1 作为条件吗?你的编译器没有抱怨吗?由于operator precedence list[i] = 1 &amp;&amp; i == 5 实际上是list[i] = (1 &amp;&amp; i == 5) 这不太可能是你想要的。
  • 我修好了...现在,例如,当我输入 12 时,我得到 11 11。似乎它没有解决问题
  • 我建议您使用debugger 逐行执行代码,同时监控变量及其值。

标签: c loops printing binary binary-search


【解决方案1】:

该程序有 Undefined Behaviour 访问未初始化的 list 值。我将重构这段代码,以便更容易谈论,但知道这段重构的代码仍然不正确。

x 始终是 0y 始终是 1x++ 无效。这个函数可以重写为:

void bin(unsigned n)
{
    char list[6];

    if (n > 1)
        bin(n / 2);

    list[0] = n % 2;

    for (int i = 0; i < 5; i++) {
        if (list[i] == 1) {
            switch (i) {
                case 5: printf("321"); break;
                case 4: printf("161"); break;
                case 3: printf("81"); break;
                case 2: printf("41"); break;
                case 1: printf("21"); break;
                case 0: printf("11"); break;
            }
        }
    }
}

这里有一些问题。

首先,list 不会在对bin 的调用之间共享,任何其他变量也不会共享。

在对bin 的每次调用中,只有list[0] 被分配了一个值——所有其他索引都包含未初始化的值。你很幸运,因为这些值似乎永远不会1

以您的 12 示例作为起始值:

当您最初致电bin(12) 时,会发生以下情况:

bin(12) 打电话给bin(6)bin(6) 打电话给bin(3)bin(3) 打电话给bin(1)

bin(1) 中从头开始并向后工作:

n = 1,所以list[0] = n % 2; 分配1。循环检查list 的每个元素的值1,当索引(i) 等于0 时找到它,并打印11

这在bin(3) 中重复,因为3 % 2 也是1,并且再次将此结果分配给list 的第一个元素。同样,我们打印11

bin(6) 中,6 % 20。循环在list 中找不到与1 相等的元素。什么都没有打印。

同样,这在bin(12) 中重复,因为12 % 20。什么都没有打印。

重申一下,这个程序纯属运气似乎工作.在每个函数调用中访问list[1]list[4]i &lt; 5 确保您永远不会访问最后一个元素)是Undefined Behaviour。一旦调用了 UB,通常不值得对程序进行推理。


在处理位时,最好使用一些bitwise operators

这是一个或多或少执行您所描述的程序。

它假定为 32 位 unsigned(更准确地说,考虑使用来自 &lt;stdint.h&gt; 的固定宽度类型)。

该程序通过重复将我们的初始值的位向右移动b 的位数并测试是否设置了最右边的位来工作。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    unsigned num = argc > 1 ? atoi(argv[1]) : 42;
    unsigned b = 32;

    while (b--)
        if ((num >> b) & 1)
            printf("%u1 ", 1 << b);

    putchar('
');
}
$ ./a.out 12
81 41

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2021-02-24
    • 2022-11-04
    • 2021-09-09
    • 1970-01-01
    • 2017-09-05
    • 2022-11-21
    相关资源
    最近更新 更多