我是C新手,我想按照下面的步骤将输入位存储到输出数组中。

input           MSB                  LSB MSB                  LSB MSB
[169,48,0] =     1  0  1  0  1  0  0  1   0  0  1  1  0  0  0  0   0  0  0  0  0  0  0  0

程序应该在输入数据上循环,以找到开始索引所在的字节,并从开始索引中提取到结束索引的位,并将其存储在输出[]中。例如,我的开始索引是4,它出现在输入[0]中,我的结束索引是13。所以我需要从4位到13位提取,并将其放入输出[]。
当我说位位置4到13时,我的意思是-我需要输入[0]的位[4-7]={0 1 0 0 1}和输入[1]的位[8-13]={1 1 0 0 0 0}
expected
output
[9, 48,0] =     0  0  0  0  1  0  0  1   0  0  1  1  0  0  0  0   0  0  0  0  0  0  0  0

我试图用C语言编程,但不幸的是我没有成功,循环位是通过LSB到MSB的。我需要循环第一个字节,然后继续循环到下一个字节,并重复直到出现结束位置的字节索引。
#include<stdio.h>
int main()
{
    unsigned char input[3] = {169,48,0};
    unsigned char output[3]= {0};
    int i, start = 4, end = 13;
    for(i=0; i<3; i++)
    {
        output[i] = (input[i] >> (start)) & ((1u << (end)) -1u);
        printf("%u\n",output[i]);
    }
    return 0;
}

程序循环所有3个输入字节,并从位索引4存储到该特定字节(即7)的结束索引。
output
[10, 3, 0] =     0  0  0  0  1  0  1  0   0  0  0  0  0  0  1  1   0  0  0  0  0  0  0  0

我想检查输入[0]或输入[1]中是否存在起始索引,或者。. . 输入[n],按照开头所示的预期输出,从开始索引复制并存储到结束索引(可能存在于任何字节位置)。
如果你能纠正程序逻辑,我将是伟大的,因为我是新的C。

最佳答案

欢迎来到论坛。
如果你能纠正程序逻辑,我将是伟大的,因为我是新的C。
这是一个尝试性的尝试。你的主要逻辑如下:

output[i] = (input[i] >> (start)) & ((1u << (end)) -1u);

通过将其简化为以下内容(并使用临时unsigned char变量tmp)可以更容易地进行分析:
tmp = input[i] >> start; // (1)
tmp &= (1u << end) - 1u; // (2)
// etc.

我不清楚你到底想在这里做什么。我认为您应该尝试从8-start中提取input[i]位和start位,并将这些值的逻辑或(适当移位)放在临时变量中。如果是这样,那么我的建议如下。
在第一行(1)中,你的方向错了:应该是
tmp = input[i] << start;

下一行(2)没有完成任何事情。(有效且为零)此外,应该使用|而不是&,第二个操作数应该是从下一个字节中选择的位(适当移位)。
tmp |= input[i+1] >> (8-start);

那么,这就是提取阶段。接下来是输出流中的插入阶段。上面没有讨论更多的细微差别,但这给出了总体思路。(有关处理更多详细信息的实现,请参见下文。)
我想检查输入[0]或输入[1]中是否存在起始索引,或者。. . 输入[n]
为了这个目的
int idx = start / 8; // byte index
int offset = start % 8; // bit position within byte

P.S.您最初的问题表明,在输出流中提取的比特的偏移量可能与在输入流中不同。您的编辑隐藏了这一事实,但下面的实现允许这种可能性(换位)。
可能的实施
void transpose_bits(unsigned char *a, unsigned char *b, int start, int end, int dest, size_t array_len) {
    unsigned char tmp = '\0', tmp2 = '\0';
    int offset = 0, idx = 0, len = 0, next_bits = 0;
    char bitmask = 0x80;

    len = end - start;
    while (len > 0) {
        // Single pass - transpose up to 8 bits ...
        tmp = tmp2 = '\0';

        // Determine the byte index and offset in the input byte array.
        idx = start / 8;
        offset = start % 8;
        tmp = a[idx] << offset;
        next_bits = offset + len - 8;
        if (next_bits < 0) {
            // Don't even need all of current byte  => remove trailing bits ...
            tmp &= bitmask >> (len - 1);
        } else if (next_bits > 0) {
            // Need to include part of next byte ...
            tmp2 = a[idx + 1] & (bitmask >> (next_bits - 1));
            tmp |= tmp2 >> (8 - offset);
        }

        // Determine byte index and offset in output byte array
        idx = dest / 8;
        offset = dest % 8;
        b[idx] |= tmp >> offset;
        b[idx + 1] |= tmp << (8 - offset);
        // Update start position and length for next pass ...
        if (len > 8) {
            len -= 8;
            dest += 8;
            start += 8;
        } else
            len -= len;
    }
}

示例用法:
// Extract bits: 'start' and 'dest' are the same.
transpose_bits(input, output, 4, 13, 4, 3); // Assume arrays are of length '3'

// Transpose bits: 'start' and 'dest' not the same.
transpose_bits(input, output, 4, 13, 10, 3);

笔记:
input[i+1]数组必须是无符号的(正如您正确选择的那样),因为右移位运算符对有符号值的处理方式不同。
你应该检查数组的边界(比较char[]idx);为了简洁起见,我跳过了这里
array_len函数的while()循环中的每个迭代最多可处理8位。通过使用多个过程,它可以处理任意数字。

关于c - 遍历C中的位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50898380/

10-12 15:04