我是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/