如何在按位运算符中保存内存空间?

时间:2015-07-16 19:36:22

标签: c bit-manipulation operator-keyword

我想知道如何通过在C中使用按位运算符来节省内存空间,即如果对于一个TRUE / FALSE值的位串,如何使用bitoperation节省内存空间?

4 个答案:

答案 0 :(得分:3)

我将重新解释您的问题,因为您似乎在询问是否将位用作数据,并使用逐位运算符来操作这些数据位。如果这是你要问的那么答案很简单:

单个字节可以容纳8个布尔值的数据。为了比较,在使用布尔数据类型的C#中,相同的8个布尔值将至少需要8个字节来存储。

在C中,存储各种状态的常见做法是执行以下操作:

/* Define distinct states (or booleans, flags, etc. */
const unsigned char state1 = 0x01; // hex for 0000 0001
const unsigned char state2 = 0x02; // hex for 0000 0010
const unsigned char state3 = 0x04; // hex for 0000 0100
const unsigned char state4 = 0x08; // hex for 0000 1000


unsigned char mystate = 0;

/* Use bitwise operators to manipulate */
mystate |= state1; /* turn state 1 on. */

/* test state */
if (mystate & state1)
     printf("State1 set\n");

/* clear state */
mystate &= ~state1; /* turn state 1 off. */

答案 1 :(得分:0)

按位运算符本身并不是内存运算符,但它们可以在某些情况下帮助节省空间。

例如,为了节省空间,可以使用每个位来表示真/假值,将多个布尔变量存储在单个8位int变量中。然后,您可以通过屏蔽或移位运算符提取位。

另一个例子可能是编程SIMD单位,其中省略了一些指令,例如减法,因为减法可以通过添加两个值来模拟,其中一个被否定(通过两个'补充)。例如,取7-12 = -570000 1111,而120000 1010。两个补码告诉我们,为了表示负数,我们否定正值的二进制并添加1,因此-121111 0100,后续添加得到我们1111 1011,即-5。我们知道它的负数是因为最重要的位(即最左边的位是1),所以我们可以像之前那样找到1111 1011的值。您可以看到这样的变通方法在架构和低级语言(例如汇编)中做了很多工作,以节省空间,降低成本并加快速度。

答案 2 :(得分:0)

一个字节有8位。 int中至少有32位。等等。如果您不需要所有这些位用于某些值,例如一个布尔值或一个小数字,您可以通过将多个值打包到单个变量中来避免浪费位。

但请注意,打包和提取这些数据的行为要求运行时计算成本,因此通常需要权衡空间效率与计算速度。

大多数为现代通用系统编写的人都不担心打包数据,因为与写入和后来读取所需的时间相比,CPU速度相比便宜,所以人类的时间往往更多比CPU时间重要。

基本上,除非您知道有充分的理由,否则不要担心打包/位域。

答案 3 :(得分:0)

按位运算符本身并不能节省内存空间"。按位运算符是一种低级工具,可用于解决实现许多不同目标,并且“节省存储空间”#34;只是其中一个目标。 按位运算符可用于我称之为位字段的手动实现。通过使用按位运算符,可以将几个小位宽值分组到一个32位或64位宽的机器字中。 例如,当需要存储3位值,10位值和20位值时,可以将所有这些值填充到单个32位对象(unsigned int等)中。因此,不是声明三个不同的无符号int变量,而是仅使用一个就可以获得,从而减少这些数据消耗的内存三次。 也许一个更好的例子是bool类型的32个变量,它通常占用32个字节的内存。但是通过使用按位运算符,可以将所有这些布尔值存储在一个32位整数变量中,从而将内存消耗减少8倍。 这实际上就是一个典型的编译器在使用位字段时所做的工作。如果出于某种原因,人们不想使用位字段(并且某些上下文有很好的理由不使用它们),可以通过逐位运算实现相同的值封装功能。