【问题标题】:modifying arrays in C在 C 中修改数组
【发布时间】:2021-11-18 19:07:59
【问题描述】:

背景故事(如果有兴趣):

最近,我学会了用二进制写数字。所以,我想看看我是否可以为 32 位编写每一种可能性。所以,我开始了,在成功完成了 10 位之后,我查找了 32 位的解决方案总数。事实证明,这比我想象的要多得多(远远超过 40 亿)。所以我认为一个有趣的挑战是编写一个自定义程序(用 C 语言)来计算 32 位的每一个可能的答案。

为此,我使用了一个包含 32 个项目的数组。然后,我检查第 32 个值是否等于 0。如果是,那么我只需将其更改为 1。如果是 1,我将其更改为 0,然后更改之后的每个项目(等于 1)回到零,直到我打到 0。 这是我的代码:

#include <stdlib.h>

#include <stdio.h>

int main(int argc, char const *argv[])
{
    int bits[32] = {1, 0};
    
    for (int i=0;i<3000;i++)
    {

        for (int j=0;i<32;i++)
        {
            if (bits[32] == 0)
            {
                bits[32] = 1;
            }
            else if (bits[32] == 1)
            {   
                int k = 0;
                
                for (k = 0;k<32;k++)
                {
                    int position = 32-k;
                    while(bits[position] != 0)
                    {
                        bits[position] = 0;
                    }
                    bits[position+1] = 1;
                }
            }
        }
        for (int i=0;i<32;i++)
        {
            printf("%d", bits[i]);
        }
        printf("\n");
    }
    getchar();
    return 0;
}

然后我遇到了一个主要障碍。它根本不起作用(只需插入任何 IDE,运行它,您就会自己看到它)。在我看来,这似乎完全合乎逻辑,但显然它不是那样工作的,我承认我完全迷路了。 有谁知道(没有给我整个代码,我仍然想自己做)为什么这不起作用,以及如何解决它? 非常感谢。

【问题讨论】:

  • bits[32] 超出范围。您可以通过bits[31] 索引bits[0]。同样,int position = 32-k; 将在 bits[position] 中相差一个。
  • C 和 C++ 是两种非常不同的语言,请不要同时标记。仅标记您实际编写程序所用的语言。
  • 您应该解释问题所在,而不是让 Stack Overflow 读者编译并运行您的代码,然后再尝试找出问题所在。
  • 这样做的方法非常复杂:)。不过,(int j=0;i&lt;32;i++) 不应该是j 吗?一个好主意是为for 索引使用不同的名称。第二个嵌套的for 也使用i,我不认为这是有意的。
  • 另外,检查设置 j=0 的循环。结束条件基于“i”,即外部循环变量。

标签: arrays c


【解决方案1】:

嗯,您要求的内容已经在 cmets 中,但是如果您想检查您的编码是否产生正确的结果,这里有一个更简单的解决方案。

请记住,long 也是32 位变量(或x64 上的64)。您所要做的就是打印变量中的每一位。试试这个:

#include <stdio.h>
void PrintBin(unsigned long uNumber)
{
    for(unsigned long i = 0; i < 32; i++)
        printf("%lu", (uNumber & (0x80000000 >> i)) >> (31-i));
    printf("\n");
}

int main()
{
    unsigned long i = 0;
    do
    {
        printf("%lu --- ", i);
        PrintBin(i);
        i++;
    }while(i != 0);

    return 0;
}

所有数字都已经是二进制的,您只需打印它们。如果我们不是在谈论将数字读取为字符串然后转换它,那么 ofc。那是另一个故事。

【讨论】:

  • 非常感谢!!它基本上完全按照我设想自己的程序工作的方式工作。我不得不承认,我真的不明白它是如何工作的,所以我会研究它以供将来进一步使用。
  • @Lalaryk 阅读geeksforgeeks.org/bitwise-operators-in-c-cpp 了解如何进行位操作。懂位运算的你也懂(uNumber &amp; (0x80000000 &gt;&gt; i)) &gt;&gt; (31-i)
  • @Lalaryk meh 忘了那个链接我认为维基百科更适合开始这个en.wikipedia.org/wiki/Bitwise_operations_in_C
  • 这非常有帮助,非常感谢:)
【解决方案2】:

二进制数学就像十进制数学一样。增加一个数字与加 1 相同。正如您可能在学校学到的那样,您只需添加第一个数字,如果大于 9,您将 1 带到下一个数字并以相同的方式添加。继续前进,直到你没有更多的东西可以结转为止。

二进制的区别在于你只有 0 和 1,所以加 1 + 1 会得到 0 和 1 来结转。

要查看循环如何执行此操作,您通常会将 00...001 添加到您的位,并有一个循环来跟踪进位(最初为 0)并将其添加到下一位,但您可以从进位 1 开始简化事情(它取代了您添加的初始 00...001)。它看起来像这样:

    uint8_t carry = 1;
    for (int bit_idx = 0; bit_idx < 32; bit_idx++) {
        const uint8_t bit = bits[bit_idx];
        /*
            carry  bit    carry bit
              1  +  1   =   1    0
              1  +  0   =   0    1
              0  +  1   =   0    1
              0  +  0   =   0    0
         */
        if ((1 == bit && 1 == carry) || (0 == bit && 0 == carry)) {
            bits[bit_idx] = 0;
            // keep carry to the next digit.
        } else {
            bits[bit_idx] = 1;
            // If you wanted, you could 'break' here instead.
            carry = 0;
        }
    }
    // Print most significant first to look normal.
    for (int bit_idx = 31; bit_idx >= 0; bit_idx--) {
        printf("[%d]", bits[bit_idx]);
    }
    printf("\n");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-18
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2012-04-25
    • 1970-01-01
    相关资源
    最近更新 更多