【问题标题】:Implementation of bit field in cc中位域的实现
【发布时间】:2020-04-23 09:52:04
【问题描述】:

我们被分配了一个任务来创建一个汇编器的虚构版本(没有确切的汇编推荐)

我们被指示要有效地使用内存(不是大 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]
 }
 ^

这些错误似乎没有任何意义。我的设置和休息位的方法应该有效。那么为什么它会产生这么多错误呢?

【问题讨论】:

  • 1. “错误似乎没有任何意义”。这绝对是有道理的。它非常清楚地告诉您该函数被定义为接受一个参数,但是您在没有参数的情况下调用它。 2..头文件不应该直接传递给编译器。您将它们包含在.c 文件中并编译.c。 3. 缺少#include &lt;stdio.h&gt;
  • "bit_field bits = init_bit_field();" “函数‘init_bit_field’的参数太少”和void init_bit_field(bit_field *);。什么在这里没有意义?您的调用与此处的函数签名不匹配。
  • @Eraklon 这个错误确实有意义,我已经修复了它们。没有意义的错误是按位运算符的错误
  • 当你定义类似#define BYTES BITS / BITS_IN_BYTE use () else 运算符优先级可能会使你在公式中的期望无效,所以#define BYTES (BITS / BITS_IN_BYTE)
  • @kaylum mayby 甚至 *destination[location / BITS_IN_BYTE]?

标签: c memory bitwise-operators bit bit-fields


【解决方案1】:

在这里定义

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 * 作为函数的参数。然后在函数中不要使用与号(&amp;)作为:

destination[location / BITS_IN_BYTE]

【讨论】:

  • 为什么会出现问题?我应该使用烧焦的字符吗?还是应该使用*destination 而不是destination
  • 但是如果我不通过指针来做,原始数组将不会被更新
  • 它是一个数组,所以它会被很好地更新(例如更新数组int)。我不明白你想在你的代码中做什么。所以我只提出一个例子如何使用这个声明。
猜你喜欢
  • 2012-09-14
  • 1970-01-01
  • 2012-07-02
  • 2017-04-16
  • 2023-01-31
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 2023-03-10
相关资源
最近更新 更多