C 在一个字节中存储4个不同的值

C 在一个字节中存储4个不同的值,c,hex,byte,C,Hex,Byte,我有一个任务要做,但我不知道从哪里开始。我并不期待,也绝对不希望得到代码中的答案。我想在做什么方面得到一些指导,因为我觉得有点迷茫 将变量打包并解包为一个字节。您需要在一个字节中存储4个不同的值。这些数值是: NAME RANGE BITS engine_on 0-1 1 gear_pos 0-4 3 key_pos 0-2 2 brake1 0-1 1 brake2 0-1 1 名称范围位 发动机在0-1

我有一个任务要做,但我不知道从哪里开始。我并不期待,也绝对不希望得到代码中的答案。我想在做什么方面得到一些指导,因为我觉得有点迷茫

将变量打包并解包为一个字节。您需要在一个字节中存储4个不同的值。这些数值是:

NAME RANGE BITS engine_on 0-1 1 gear_pos 0-4 3 key_pos 0-2 2 brake1 0-1 1 brake2 0-1 1 名称范围位 发动机在0-1上1 档位0-4 3 钥匙位置0-2 2 刹车10-11 刹车2 0-1 1 (LSB,最低有效位)

编写一个包含5个参数的程序bytess.c(少或多应视为错误)。参数应与上述值/变量相对应。 例子: bytess 1 2 1

上述情况应视为: 名称值 发动机在1上 档位2 钥匙位置2 制动器1 制动器2 1

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

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

你读过关于位域的内容吗

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;
};

这是另一种方法

    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);
无符号整数i=0;
发动机开启=1;
齿轮位置=2;
按键位置=2;
制动器1=1;
制动器2=1;
i |=s1.制动器2;

i |=(s1.brake1让我们调用一个字节b,如果将b设置为0,则最终得到(二进制)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设置为brake2的值,就可以得到0000 0000或0000 0001,这取决于它是0还是1

现在我们想将刹车1设置为b。我们可以通过使用a或/等于和数字本身来实现这一点,但位移到正确的位置。我们最终得到以下结果:

b |= (brake1 << 1) 

b |=(brake1你可能想读一些关于,也许还有联合的内容。如果这些内容不适合使用,那么就介绍位运算符和
&
,或者
&
而不是
~
。我已经读过它们,但我不知道在哪里可以使用它们。移位运算符(
和/或code>
)可能会有帮助:您可以获取字段的一个值,并对其进行移位,使其占据所需的位范围。可以使用按位或(
|
)将各个字段值组合到所需的组合中。查看格式
%02x”
以十六进制打印。
AB
是一个十六进制数,通常由C程序员编写为
0xAB
。十六进制数
a
具有位模式
1010
,而
B
1011
,因此它们一起是
10101011
。如果您在该位模式中分离不同的项,则是
1 010 10 1是十进制的
1 2 1
。位域排序和打包依赖于实现。此外,位域成员应该声明为unsignedOk,我现在已经了解了。我知道它使我的结构精确为8位。如何将这些值放入整数中?您只需将结构成员设置为值?然后可能是将结构memcpy转换为整数?@Ship在这个赋值中不太可能使用位字段。您真正需要的是左移位运算符

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 = b | (brake1 << 1) // which can also be written as:
b |= (brake1 << 1)