C 位屏蔽是否可与“位屏蔽”相比;“访问阵列”;零零碎碎的?

C 位屏蔽是否可与“位屏蔽”相比;“访问阵列”;零零碎碎的?,c,bit-manipulation,terminology,masking,bitmask,C,Bit Manipulation,Terminology,Masking,Bitmask,对于我所看到的所有关于位屏蔽的定义,它们都只是直接深入到如何位屏蔽、按位使用等等,而没有解释其中任何一个的用例。更新所有要保留的位和所有要清除的位以“访问阵列”的位的目的是什么 更新所有要保留的位和所有要清除的位以“访问阵列”的位的目的是什么 我会说答案是否定的 当您访问int数组时,您将执行以下操作: int_array[index] = 42; // Write access int x = int_array[42]; // Read access 如果您想编写类似的函数,以“类似数

对于我所看到的所有关于位屏蔽的定义,它们都只是直接深入到如何位屏蔽、按位使用等等,而没有解释其中任何一个的用例。更新所有要保留的位和所有要清除的位以“访问阵列”的位的目的是什么

更新所有要保留的位和所有要清除的位以“访问阵列”的位的目的是什么

我会说答案是否定的

当您访问
int
数组时,您将执行以下操作:

int_array[index] = 42;  // Write access
int x = int_array[42];  // Read access
如果您想编写类似的函数,以“类似数组的方式”读取/写入
无符号int
中的特定位,它可能如下所示:

unsigned a = 0;
set_bit(a, 4);   // Set bit number 4
unsigned x = get_bit(a, 4); // Get bit number 4
set_bit
get_bit
的实现将需要(除其他外)一些位掩码操作

因此,-要以“类似数组的方式”访问位,您需要屏蔽,但是…

位级掩蔽还有许多其他用途

例如:

int buffer[64];
unsigned index = 0;

void add_to_cyclic_buffer(int n)
{
    buffer[index] = n;
    ++index;
    index &= 0x3f;  // Masking by 0x3f ensures index is always in the range 0..63
}
unsigned a = some_func();

a |= 1;  // Make sure a is odd
a &= ~1; // Make sure a is even
unsigned a = some_func();

a &= ~0xf;  // Make sure a is a multiple of 16
例如:

int buffer[64];
unsigned index = 0;

void add_to_cyclic_buffer(int n)
{
    buffer[index] = n;
    ++index;
    index &= 0x3f;  // Masking by 0x3f ensures index is always in the range 0..63
}
unsigned a = some_func();

a |= 1;  // Make sure a is odd
a &= ~1; // Make sure a is even
unsigned a = some_func();

a &= ~0xf;  // Make sure a is a multiple of 16
例如:

int buffer[64];
unsigned index = 0;

void add_to_cyclic_buffer(int n)
{
    buffer[index] = n;
    ++index;
    index &= 0x3f;  // Masking by 0x3f ensures index is always in the range 0..63
}
unsigned a = some_func();

a |= 1;  // Make sure a is odd
a &= ~1; // Make sure a is even
unsigned a = some_func();

a &= ~0xf;  // Make sure a is a multiple of 16
这只是使用“掩蔽”的几个例子,它与作为数组访问位无关。可以举出许多其他例子

因此,总结如下:

掩蔽可以用来编写以类似数组的方式访问位的函数,但掩蔽也可以用于许多其他用途。

因此有3(或4)种主要用途

正如您所说,其中之一是将单词用作一组真/假标志,其中每个标志只是以对称方式编制索引。我在这里使用“word”来表示在单个操作中访问的离散内存块。所以一个字节包含8位值,“long-long”包含64位。再努力一点,就可以将一个字数组用作一个更紧凑的标志数组

第二个是你对价值的操纵,但仍然认为这个词保持一个值。有许多技巧,如设置或清除底部位以确保对齐,或清除顶部位以获得模数,移位以除以或乘以2的幂

第三个用途是将大量较小范围的值打包到一个单词中。每个值在上下文中都具有特定的含义。这可能是因为您需要与已将其定义为协议的设备通信,或者因为您需要创建太多的对象,以至于每个对象中节省的空间超过了代码大小和代码速度成本的增加(尽管这可能与缓存未命中的增加形成对比,如果对象更大,则会导致速度减慢)


作为区别,第四种情况是,这些字段是不同的1位标志,在代码上下文中具有特定含义。数据对象倾向于收集大量此类标志,有时将它们作为位存储在单个位置比为每个标志使用单独的字节更方便。通常测试一个特定的ar固定索引位或固定掩码位在代码大小或速度方面并不比测试整个字节更昂贵,尽管写入可能更复杂。节省的存储量是显而易见的,因此程序员在结构中创建大量标志或编写函数时,通常会默认声明位掩码枚举。

像无符号a;…a |=1;这样的e在概念上并不一定是访问一个位数组。该代码只是确保
a
是奇数。“访问数组”是什么意思关于位?请给出一个代码示例。目前这个问题还不清楚。在某些情况下,我认为操作数可以被视为只是一系列位。还有其他方法可以查看某些特定的屏蔽操作,例如将其舍入为二的幂的倍数或余数乘以二的幂。当然,您可以始终将其视为位数组manip我也是。