c中位域的实现
Implementation of bit field in c
我们接到了一项任务,要求我们创建一个汇编程序的编造版本(不包含确切的汇编推荐)
我们被指示要有效地使用内存(不是大 O 符号类型的内存效率,而是有效地使用数据结构)
由于每个命令都被翻译成 24 位机器码,我认为存储命令机器码的最有效方法是使用位字段,所以我实现了以下位字段:
(在bit_field.c)
#include "bit_field.h"
int set_bit(bit_field *destination, int location, enum bit_values value)
{
if(location >= BITS)
return 0;
if(value == ONE)
(destination)[location / BITS_IN_BYTE] |= 1UL << location % BITS_IN_BYTE;
else
(destination)[location / BITS_IN_BYTE] &= ~(1UL << location % BITS_IN_BYTE);
return 1;
}
enum bit_values get_bit(bit_field *destination, int location)
{
return ((destination)[location / BITS_IN_BYTE] >> location % BITS_IN_BYTE) & 1U;
}
void init_bit_field(bit_field *new_bit_field)
{
int i;
for(i = 0; i < BITS; i++)
set_bit(new_bit_field, i, ZERO);
}
void init_bit_field_by_str(bit_field *new_bit_field, char *string)
{
int i;
for(i = 0; i < BITS; i++)
set_bit(new_bit_field, i, *string++ - '0');
}
(在bit_field.h)
#define BITS 24
#define BITS_IN_BYTE 8
#define BYTES BITS / BITS_IN_BYTE
enum bit_values {ZERO = 0, ONE = 1}bit_values;
typedef unsigned char byte;
typedef byte bit_field [BYTES];
int set_bit(bit_field *, int , enum bit_values);
enum bit_values get_bit(bit_field *, int);
void init_bit_field(bit_field *);
void init_bit_field_by_str(bit_field *, char *);;
(在 input.c 测试)
#include "bit_field.h"
#include <stdio.h>
int main()
{
int i;
bit_field bits;
init_bit_field(&bits);
set_bit(&bits, 22, ONE);
for(i = 0; i < BITS; i++)
printf("%d, ", get_bit(&bits, i));
return 0;
}
当我尝试编译以下代码 (gcc C90) 时,出现以下错误:
bit_field.c:14:53: error: invalid operands to binary >> (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘int’)
return ((&destination)[location / BITS_IN_BYTE] >> location % BITS_IN_BYTE) & 1U;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~
bit_field.c:15:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
avivgood@ubuntuVM:~/CLionProjects/Maman14$ gcc -Wall -ansi -pedantic input.c bit_field.c bit_field.h -o example.out
bit_field.c: In function ‘set_bit’:
bit_field.c:7:49: error: invalid operands to binary | (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘long unsigned int’)
(&destination)[location / BITS_IN_BYTE] |= 1UL << location % BITS_IN_BYTE;
^~
bit_field.c:9:49: error: invalid operands to binary & (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘long unsigned int’)
(&destination)[location / BITS_IN_BYTE] &= ~(1UL << location % BITS_IN_BYTE);
^~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bit_field.c: In function ‘get_bit’:
bit_field.c:14:53: error: invalid operands to binary >> (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘int’)
return ((&destination)[location / BITS_IN_BYTE] >> location % BITS_IN_BYTE) & 1U;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~
bit_field.c:15:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
这些错误似乎没有任何意义。我设置和固定钻头的方法应该有效。那么为什么它会产生这么多错误呢?
这里你定义
typedef unsigned char byte;
typedef byte bit_field [BYTES];
所以 bit_field
是一个包含 BYTES
个元素的数组。但是,当您定义函数时,您使用指向 bit_field
:
的指针
int set_bit(bit_field *, int , enum bit_values);
enum bit_values get_bit(bit_field *, int);
void init_bit_field(bit_field *);
void init_bit_field_by_str(bit_field *, char *);
这就是程序引发位运算符错误的原因。当您使用:
destination[location / BITS_IN_BYTE]
它的类型是 unsigned char *
。这就是我们出现错误的原因:
invalid operands to binary
因此,您可以只使用 bit_field
而不是 bit_field *
作为函数的参数。然后在函数中不要使用符号 (&
) as:
destination[location / BITS_IN_BYTE]
我们接到了一项任务,要求我们创建一个汇编程序的编造版本(不包含确切的汇编推荐)
我们被指示要有效地使用内存(不是大 O 符号类型的内存效率,而是有效地使用数据结构)
由于每个命令都被翻译成 24 位机器码,我认为存储命令机器码的最有效方法是使用位字段,所以我实现了以下位字段:
(在bit_field.c)
#include "bit_field.h"
int set_bit(bit_field *destination, int location, enum bit_values value)
{
if(location >= BITS)
return 0;
if(value == ONE)
(destination)[location / BITS_IN_BYTE] |= 1UL << location % BITS_IN_BYTE;
else
(destination)[location / BITS_IN_BYTE] &= ~(1UL << location % BITS_IN_BYTE);
return 1;
}
enum bit_values get_bit(bit_field *destination, int location)
{
return ((destination)[location / BITS_IN_BYTE] >> location % BITS_IN_BYTE) & 1U;
}
void init_bit_field(bit_field *new_bit_field)
{
int i;
for(i = 0; i < BITS; i++)
set_bit(new_bit_field, i, ZERO);
}
void init_bit_field_by_str(bit_field *new_bit_field, char *string)
{
int i;
for(i = 0; i < BITS; i++)
set_bit(new_bit_field, i, *string++ - '0');
}
(在bit_field.h)
#define BITS 24
#define BITS_IN_BYTE 8
#define BYTES BITS / BITS_IN_BYTE
enum bit_values {ZERO = 0, ONE = 1}bit_values;
typedef unsigned char byte;
typedef byte bit_field [BYTES];
int set_bit(bit_field *, int , enum bit_values);
enum bit_values get_bit(bit_field *, int);
void init_bit_field(bit_field *);
void init_bit_field_by_str(bit_field *, char *);;
(在 input.c 测试)
#include "bit_field.h"
#include <stdio.h>
int main()
{
int i;
bit_field bits;
init_bit_field(&bits);
set_bit(&bits, 22, ONE);
for(i = 0; i < BITS; i++)
printf("%d, ", get_bit(&bits, i));
return 0;
}
当我尝试编译以下代码 (gcc C90) 时,出现以下错误:
bit_field.c:14:53: error: invalid operands to binary >> (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘int’)
return ((&destination)[location / BITS_IN_BYTE] >> location % BITS_IN_BYTE) & 1U;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~
bit_field.c:15:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
avivgood@ubuntuVM:~/CLionProjects/Maman14$ gcc -Wall -ansi -pedantic input.c bit_field.c bit_field.h -o example.out
bit_field.c: In function ‘set_bit’:
bit_field.c:7:49: error: invalid operands to binary | (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘long unsigned int’)
(&destination)[location / BITS_IN_BYTE] |= 1UL << location % BITS_IN_BYTE;
^~
bit_field.c:9:49: error: invalid operands to binary & (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘long unsigned int’)
(&destination)[location / BITS_IN_BYTE] &= ~(1UL << location % BITS_IN_BYTE);
^~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bit_field.c: In function ‘get_bit’:
bit_field.c:14:53: error: invalid operands to binary >> (have ‘byte (*)[3] {aka unsigned char (*)[3]}’ and ‘int’)
return ((&destination)[location / BITS_IN_BYTE] >> location % BITS_IN_BYTE) & 1U;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~
bit_field.c:15:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
这些错误似乎没有任何意义。我设置和固定钻头的方法应该有效。那么为什么它会产生这么多错误呢?
这里你定义
typedef unsigned char byte;
typedef byte bit_field [BYTES];
所以 bit_field
是一个包含 BYTES
个元素的数组。但是,当您定义函数时,您使用指向 bit_field
:
int set_bit(bit_field *, int , enum bit_values);
enum bit_values get_bit(bit_field *, int);
void init_bit_field(bit_field *);
void init_bit_field_by_str(bit_field *, char *);
这就是程序引发位运算符错误的原因。当您使用:
destination[location / BITS_IN_BYTE]
它的类型是 unsigned char *
。这就是我们出现错误的原因:
invalid operands to binary
因此,您可以只使用 bit_field
而不是 bit_field *
作为函数的参数。然后在函数中不要使用符号 (&
) as:
destination[location / BITS_IN_BYTE]