掩盖最重要的一点

我写了这个函数来删除每个字节中最重要的位。 但是这个function似乎并没有像我希望的那样工作。

输出文件大小始终为“0”,我不明白为什么没有写入输出文件。 是否有更好,更简单的方法来删除每个字节中最重要的位?

关于class次操作员,C标准第6.5.7节说:

如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。

首先,删除nBuffer << 8; 。 即使它被很好地定义,它也不会是赋值运算符。

正如人们所提到的,你最好使用CHAR_BIT不是8.我很确定,而不是0x7f你的意思是UCHAR_MAX >> 1而不是7你的意思是CHAR_BIT - 1

我们这里只关注nBuffer和bit_count。 我将评论任何不使用其中任何一个的东西。

  bit_count += 7; if (bit_count == 7*8) { *out_buf++ = nBuffer; /*if((write(out_fd, bit_buf, sizeof(char))) == -1) oops("Cannot write on the file", "");*/ nBuffer << 8; bit_count -= 8; } nBuffer = 0; bit_count = 0; 

在这段代码的最后,nBuffer的价值是多少? bit_count怎么样? 这会对你的第二个循环产生什么影响? while (bit_count > 0)

现在让我们关注注释掉的代码:

  if((write(out_fd, bit_buf, sizeof(char))) == -1) oops("Cannot write on the file", ""); 

你在哪里为bit_buf赋值? 使用未初始化的变量是未定义的行为。

不是通过所有的位来找到高位,而是仅通过1位。 high()返回参数的高位,如果参数为零,则返回零。

 inline int high(int n) { int k; do { k = n ^ (n - 1); n &= ~k; } while (n); return (k + 1) >> 1; } inline int drop_high(int n) { return n ^ high(n); } 
 unsigned char remove_most_significant_bit(unsigned char b) { int bit; for(bit = 0; bit < 8; bit++) { unsigned char mask = (0x80 >> bit); if( mask & b) return b & ~mask; } return b; } void remove_most_significant_bit_from_buffer(unsigned char* b, int length) { int i; for(i=0; i 

我不会通过您的整个答案来提供您重新编写的代码,但删除最重要的代码很容易。 这是因为通过使用转换为整数的log base 2可以很容易地找到最重要的位。

 #include  #include  int RemoveMSB(int a) { return a ^ (1 << (int)log2(a)); } int main(int argc, char const *argv[]) { int a = 4387; printf("MSB of %d is %d\n", a, (int)log2(a)); a = RemoveMSB(a); printf("MSB of %d is %d\n", a, (int)log2(a)); return 0; } 

输出:

 MSB of 4387 is 12 MSB of 291 is 8 

因此,二进制4387为1000100100011,最高位为12。

同样,二进制291为0000100100011,最高有效位为8。