【问题标题】:Store 4 different values in a byte在一个字节中存储 4 个不同的值
【发布时间】:2015-04-14 23:16:42
【问题描述】:

我有一个任务要做,但我不知道从哪里开始。我不期待也绝对不想要代码中的答案。我想要一些指导,因为我觉得有点失落。

将变量打包和解包到一个字节中。您需要在一个字节中存储 4 个不同的值。值是:

名称范围位 engine_on 0-1 1 gear_pos 0-4 3 关键位置 0-2 2 刹车1 0-1 1 刹车2 0-1 1

(LSB,最低有效位)

编写一个带有 5 个参数的程序 bytess.c(更少或更多应视为错误)。参数应对应于上面的值/变量。 例子: 字节数 1 2 2 1 1

以上内容应视为: 名称 值 引擎开启 1 gear_pos 2 关键位置 2 刹车1 1 刹车2 1

将这些值打包成一个字节(无符号字符)作为整数,并以十六进制形式打印到标准输出,在本例中,它应该是对应于位“10101011”的“AB”。在此之后,您的程序应该返回 0。如果您的程序发现任何错误(参数太多/太少、输入值错误......),您的程序应该打印错误并返回一个非零值。

我知道如何检查这些是否是 5 个参数,但我不明白下一步该做什么。我已经阅读了很多关于换档的信息,但我的大脑无法处理整个画面。感觉这应该是一个非常简单的例子,但我在互联网上找不到任何类似的东西。 “AB”如何变成10101011?我刚刚检查了字符串到十六进制 -> 4142。十六进制到位 -> 1000000101110。

【问题讨论】:

  • 您可能想了解bit fields,也许还有工会。如果这些不能使用,那么关于按位运算符 AND &、OR & 和 NOT ~
  • 我已经阅读过它们,但我不知道我可以在哪里使用它们。
  • 移位运算符(<< 和/或>>)会很有帮助:您可以获取字段值之一,并将其​​移位以使其占据所需的位范围。使用按位或 (|) 将各个字段值组合成您想要的组合。
  • 查看"%02x" 格式以十六进制打印。
  • AB 是一个十六进制数,通常由 C 程序员编写为 0xAB。十六进制数A 有位模式1010B1011,所以它们加在一起是10101011。如果您在该位模式中分隔不同的项目,您将得到二进制的1 010 10 1 1,即十进制的1 2 2 1 1

标签: c hex byte


【解决方案1】:

让我们调用一个字节 b,如果你将 b 设置为 0,你最终会得到(二进制)0000 0000(可读性空间)

现在我们要将不同的部分打包到这个字节中

engine_on  0-1    1
gear_pos   0-4    3 
key_pos    0-2    2 
brake1     0-1    1
brake2     0-1    1

brake2 很简单。我们可以将 b 设置为制动器 2 的值,最终得到 0000 0000 或 0000 0001,具体取决于它是 0 还是 1。

现在我们要将制动器 1 设置为 b。我们可以通过使用 or/equal 和数字本身但位移到正确的位置来做到这一点。我们最终得到以下结果:

b |= (brake1 << 1) 

让我们解释一下我是怎么做到的:

brake1 = 0000 0001 //lets assume its a 1 not a 0)
(brake1 << 1) = 0000 0010
b = 0000 0001 //lets assume brake 2 was 1.

如果 b 中的位为 1 或 (brake1

b = b | (brake1 << 1) // which can also be written as:
b |= (brake1 << 1)

现在您还可以添加其他部分,它还可以同时处理更多位。我希望这会有所帮助

【讨论】:

    【解决方案2】:

    这是另一种方法。

        unsigned int i = 0;
    
        engine_on = 1;
        gear_pos =2;
        key_pos = 2;
        brake1 = 1;
        brake2 = 1;
    
        i |= s1.brake2;
        i |= (s1.brake1 << 1);
        i |= (s1.key_pos << 2);
        i |= (s1.gear_pos << 4);
        i |= (s1.engine_on << 7);
    

    【讨论】:

      【解决方案3】:

      你读过位域吗?

      struct s {
        unsigned char engine_on : 1;
        unsigned char gear_pos : 3;
        unsigned char key_pos : 2;
        unsigned char brake1 : 1;
        unsigned char brake2 : 1;
      };
      

      【讨论】:

      • 位域排序和打包取决于实现。
      • 位域成员也应声明为无符号
      • 好的,我现在读到了。我知道它使我的结构精确为 8 位。如何将这些值放入整数中?
      • 您只是将结构成员设置为值?然后可能将结构 memcpy 为整数?
      • @Ship 您不太可能在此分配中使用位域。您真正需要的只是左移运算符&lt;&lt; 和“或”运算符|
      猜你喜欢
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      • 2017-05-01
      • 2011-09-23
      • 2021-09-15
      • 1970-01-01
      相关资源
      最近更新 更多