Arrays 字符串到长度小于1字节的超长序列

Arrays 字符串到长度小于1字节的超长序列,arrays,algorithm,Arrays,Algorithm,我猜不出如何解决下面的问题。假设我有一个字符串或整数类型的变量数组(uchar、char、integer等等)。这些数据类型中的每一种都有1字节或更长 我想从这样的数组中读取数据,但要读取小于1字节的数据,例如3位(值0-7)。我试着做一个像这样的循环 cout << ( (tab[index] >> lshift & lmask) | (tab[index+offset] >> rshift & rmask) ); cout>lshift

我猜不出如何解决下面的问题。假设我有一个字符串或整数类型的变量数组(uchar、char、integer等等)。这些数据类型中的每一种都有1字节或更长

我想从这样的数组中读取数据,但要读取小于1字节的数据,例如3位(值0-7)。我试着做一个像这样的循环

cout << ( (tab[index] >> lshift & lmask) | (tab[index+offset] >> rshift & rmask)  );
cout>lshift&lmask)|(选项卡[索引+偏移]>>rshift&rmask);
但是我无法猜测如何设置这些变量。解决这个问题的方法是什么


抱歉,如果有人问过这个问题,但搜索不会给出答案。

简而言之,数据在内存中的排列方式严格取决于:

  • 用于计算/表示的标准(通常是
  • 给定变量的类型
现在,如果不破坏数据结构本身的含义,就不能使用这种原理“反汇编”数据结构,简单地说,如果要在“位域”中细分变量,那么您只是在描绘一个未定义的值

在计算机科学中,有些数据结构或信息是以块的形式构造的,就像许多散列算法/散列结果一样,但是一个数值不是这样存储的,你应该知道你在做什么来防止任何数据丢失


另一件需要注意的事情是,您对“小于1字节的片段”的定义没有多大意义,它也是高度侵入性的,您正在失去这里的抽象性,您也可以做一些不好的事情。

简而言之,数据在内存中的排列方式严格取决于:

  • 用于计算/表示的标准(通常是
  • 给定变量的类型
现在,如果不破坏数据结构本身的含义,就不能使用这种原理“反汇编”数据结构,简单地说,如果要在“位域”中细分变量,那么您只是在描绘一个未定义的值

在计算机科学中,有些数据结构或信息是以块的形式构造的,就像许多散列算法/散列结果一样,但是一个数值不是这样存储的,你应该知道你在做什么来防止任何数据丢失


另一件需要注意的事情是,你对“小于1字节的片段”的定义没有多大意义,它也是高度侵入性的,你在这里失去了抽象性,你也可以做一些不好的事情。

下面是我能想到的设置变量单个位的最佳方法: 假设我们需要将variable1(字符或其他字节长的变量)的前四位设置为1010

这可以扩展到任何需要的位,方法是将零放在与您希望设置的位对应的第一个数字中(示例中的前四个),并将零放在与您希望在第二个数字中保持中性的位对应的第二个数字中(示例中的最后四个)。第二个数字也可以通过将所需值移位适当的位数(在本例中为4位)来推导

根据您的意见,可对其进行如下修改,以适应增加的可变性:

对于此操作,假设您希望能够修改非起始位和非结束位,我们将需要两个移位。在这种情况下,有两组位:第一组(从左起)未受影响位和第二组。如果您希望修改四位,跳过左边的第一位(1这四位111代表一个字节),第一个移位将是7,第二个移位将是5

variable1 &= ( ( 0b11111111 << shift1 ) | 0b11111111 >> shift2 );

下面是我能想到的设置变量各个位的最佳方法: 假设我们需要将variable1(字符或其他字节长的变量)的前四位设置为1010

这可以扩展到任何需要的位,方法是将零放在与您希望设置的位对应的第一个数字中(示例中的前四个),并将零放在与您希望在第二个数字中保持中性的位对应的第二个数字中(示例中的最后四个)。第二个数字也可以通过将所需值移位适当的位数(在本例中为4位)来推导

根据您的意见,可对其进行如下修改,以适应增加的可变性:

对于此操作,假设您希望能够修改非起始位和非结束位,我们将需要两个移位。在这种情况下,有两组位:第一组(从左起)未受影响位和第二组。如果您希望修改四位,跳过左边的第一位(1这四位111代表一个字节),第一个移位将是7,第二个移位将是5

variable1 &= ( ( 0b11111111 << shift1 ) | 0b11111111 >> shift2 );

我确信这不是最好的解决方案,因为代码中存在一些可以消除的低效,但我认为这个想法是可行的。我只是简单地测试了一下:

void bits(uint8_t * src, int arrayLength, int nBitCount) {
   int idxByte = 0;      // byte index
   int idxBitsShift = 7; // bit index: start at the high bit
   // walk through the array, computing bit sets
   while (idxByte < arrayLength) {
       // compute a single bit set
       int nValue = 0;
       for (int i=2; i>=0; i--) {
        nValue += (src[idxByte] & (1<<idxBitsShift)) >> (idxBitsShift-i);
        if ((--idxBitsShift) < 0) {
            idxBitsShift=8;
            if (++idxByte >= arrayLength) 
                break;
        }
       }
       // print it
       printf("%d ", nValue);
   }

}

int main() {
    uint8_t a[] = {0xFF, 0x80, 0x04};
    bits(a, 3, 3);
}
void位(uint8_t*src,int-arraylelength,int-nBitCount){
int idxByte=0;//字节索引
int idxbitshift=7;//位索引:从高位开始
//遍历数组,计算位集
while(idxByte<阵列长度){
//计算单个位集
int nValue=0;
对于(int i=2;i>=0;i--){
nValue+=(src[idxByte]&(1(idxbitshift-i);
如果((-idxbitshift)<0){
idxbitshift=8;
if(++idxByte>=阵列长度)
打破
}
}
//打印出来
printf(“%d”,nValue);
}
}
int main(){
uint8_t a[]={0xFF,0x80,0x04};
位(a,3,3);
}
跨字节边界收集位有点像PITA,所以我一次收集一点,然后在
nValue
中收集位,从而避免了所有这些
void bits(uint8_t * src, int arrayLength, int nBitCount) {
   int idxByte = 0;      // byte index
   int idxBitsShift = 7; // bit index: start at the high bit
   // walk through the array, computing bit sets
   while (idxByte < arrayLength) {
       // compute a single bit set
       int nValue = 0;
       for (int i=2; i>=0; i--) {
        nValue += (src[idxByte] & (1<<idxBitsShift)) >> (idxBitsShift-i);
        if ((--idxBitsShift) < 0) {
            idxBitsShift=8;
            if (++idxByte >= arrayLength) 
                break;
        }
       }
       // print it
       printf("%d ", nValue);
   }

}

int main() {
    uint8_t a[] = {0xFF, 0x80, 0x04};
    bits(a, 3, 3);
}