访问数组中的每个第 n 个元素(汉明代码)

accessing every nth element in array (hamming code)

所以基本上我正在创建一个程序,提示用户输入像 'A' 这样的字符,它 returns 它们根据 ASCII 图表的二进制值,在这种情况下是 01000001。什么应该输出的是一个12位的汉明码序列,有8个数据位和4个奇偶校验位。我遇到的问题是想出一种方法将正确的数据位插入到基本上不是 2 的幂的每个数组位置。我应该提到数组的类型是 char。

所以它应该打印出来:_ _ 0 _ 1 0 0 _ 0 0 0 1 空格代表奇偶校验位的位置。现在我的代码只打印出 000001000001(到目前为止还没有确定奇偶校验值)但我想不出一种方法将 8 个数据位中的每一个都定位到非奇偶校验位位置。

我假设我必须编辑我的 for 循环,它目前涉及 for(int i = 12; i >= 0; i--) 但我似乎无法找出我可以使用的数学模式。我不确定我目前的方法是否可行。任何提示或帮助将不胜感激。

下面基本上只是我正在努力处理的代码部分的粗略概述:

for (int i=12; i>=0; i--) {
    if ((int)(n/pow(2,i)) > 0) {
        //index = 1
        n = n - pow(2,i);
    }
    else
        //index = 0
 }

您需要熟悉的操作是掩码和移位。 不要使用pow进行位操作。这是一个大型的重量级函数,用于数值计算。

有几种方法可以生成您寻求的 _ _ 0 _ 1 0 0 _ 0 0 0 1 模式。一种是先清除最右边的space。如果 x 保留原始值 0100001,则第一步是屏蔽除最后 4 位以外的所有位。这是x & 0xfu& 是合乎逻辑的 "and." 所有其他位都可以用 x & ~0xfu 屏蔽掉。 ~ 是按位 "not." 现在你想将这些其他位左移一位并使用 "or" 将它们与低位 4 位组合。所以我们总共有:

unsigned x = 'A';
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);

要将最上面的位向左移动一位,遵循相同的步骤,只是现在您希望最右边的 8 位保持原位,而第 9 位和更高位移动一个在左边。你需要的面具是0xffu。所以我们最终得到

unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);

现在您可以 "or" 在奇偶校验位中,然后用类似的东西打印出按位表示:

for (unsigned m = 0x800; m; m >>= 1) printf("%d", (m & result) != 0);

同样,0x800 是第 11 位的掩码。您可以使用它来检查 (m & result) != 0 结果的第 11 位。如果设置了 result 的相应位,则此值为 1,否则为 0,正是您要打印的内容。 for 循环的每次连续迭代都会将掩码向右移动一位。当位完全移出时,循环停止。这发生在 12 次迭代之后,所以你打印 12 位,这似乎是你想要的。

注意我一直使用无符号类型。这在这里不是绝对必要的,但使用无符号类型进行位操作通常不太容易出错,因为符号扩展会导致意外结果。

总而言之,您可以使用 0xff 作为输入进行测试,以查看奇偶校验位所属的 "holes":

#include <stdio.h>
int main(void)
{
    unsigned x = 0xffu;
    unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
    unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
    for (unsigned m = 0x800; m; m >>= 1) 
      printf("%d", (m & result) != 0);
    return 0;
}

如您所愿打印 001011101111

有很多有趣的细节需要解决。我让给你。