【问题标题】:Using typedef and struct to create bitfield使用 typedef 和 struct 创建位域
【发布时间】:2013-03-24 04:00:39
【问题描述】:

嘿,这一切都是为了 C 编程。

这是向我提出的问题,有人能告诉我如何正确地用 C 语言编写以下语句的代码吗?仅供参考,我已经回答了这个测验,但我的教授不会自己发布答案。当他给它评分时我做得很差,但是为了帮助理解这一点,我会提供我的答案(尽管它们是不正确的)

1:创建一个结构,该结构将包含表示以下内容的位:

  • count:一个 4 位 BCD 数
  • 红色 LED:1 位
  • 绿色 LED:1 位
  • 电机方向:2位

将结构命名为motorStatus

使用 typedef 来命名这个新的数据类型:mtrStatus_t

typedef unsigned char mtrStatus_t;

struct motorStatus mtrStatus_t {
    mtrStatus_t count: 4;
    mtrStatus_t redLED: 1;
    mtrStatus_t greenLED: 1;
    mtrStatus_t motorDirection: 2;
};

2:创建结构的新实例并将其命名为motor1Status

motorStatus = motor1Status;

3:编写语句初始化新的结构成员如下:

  • 计数:9 BCD
  • 红色 LED:1
  • 绿色 LED:0
  • 电机方向:10

    计数:0x09; 红灯:0x01; 绿色LED:0x00 电机方向:0x0A

【问题讨论】:

    标签: c structure bit-fields


    【解决方案1】:

    对于第一个,我会这样做:

    typedef struct motorStatus  
    {
        int count: 4;
        int redLED: 1;
        int greenLED: 1;
        int motorDirection: 2;
    } mtrStatus_t;
    

    第二个更像:

    mtrStatus_t motor1status;
    

    最后:

    motor1status.count = 0x9;
    motor1status.redLED = 1;
    motor1status.greenLED = 0;
    motor1status.motorDirection = 0x02;
    

    Count 是一个十六进制数,因为它是 BCD(二进制编码的十进制)http://en.wikipedia.org/wiki/Binary-coded_decimal 在 BCD 中,您使用 4 位来表示数字 0-9,有一些未使用的位模式,因此使用它的简单方法是仅使用十六进制(也使用 4 位来表示数字 0x0-0xf),但在 BCD 中,您只是不使用数字 0xa-0xf。

    motorDirection 是 0x02 的原因是因为他想要 10 的电机方向,但它是一个 2 位字段,所以我假设他的意思是 10 二进制,即 0x02 hex。

    【讨论】:

    • 嘿克里斯这是如何工作的............我明白你是如何把它放在一起的,但我不明白 typedef 的意义是什么......跨度>
    • motorStatus 是结构的名称,但 mtrStatus_t 是该结构的 typedef 的名称...有关此古老语法的更多详细信息,请参阅此问题:stackoverflow.com/questions/612328/…
    • 嘿,克里斯,一切看起来都很棒,感谢您对 motorDirection 作为 2 位的解释。还有一件事......为什么在结构成员的初始化中将计数写为十六进制?
    • 更新了关于 BCD 的帖子
    【解决方案2】:

    考虑按照指定的顺序满足这些要求。请注意,某些要求合并为一个。这通常是分配的情况;讲师并不总是完美的语言学家或逻辑学家,尤其是 IT 讲师。

    1:创建一个结构,该结构将包含以下表示的位:
    
    count:一个 4 位 BCD 数
    红色 LED:1 位
    绿色 LED:1 位
    电机方向:2位
    
    将结构命名为 motorStatus

    首先响应这个,不要使用 typedef。位域使用int 类型。下一个要求:

    使用 typedef 来命名这个新的数据类型:mtrStatus_t

    您已经展示了编写基本类型定义的能力。 typedef unsigned char mtrStatus_t; 表示“我将 mtrStatus_t 定义为别名 unsigned char”。现在,编写一个像这样的基本 typedef,意思是“我将 mtrStatus_t 定义为别名 struct motorStatus”。将其放在struct motorStatus 定义之后,以便编译器可以看到它的别名。

    2:创建结构的新实例并将其命名为motor1Status

    为了澄清,您的讲师要求您声明一个名为 motor1Status 的变量,其类型为 mtrStatus_tstruct motorStatus。我认为您可以声明变量,但如果我错了,请纠正我。

    3:编写语句来初始化新的结构成员,如下所示:
    
    计数:9 BCD
    红色 LED:1
    绿色 LED:0
    电机方向:10
    
    计数:0x09;红灯:0x01;绿色LED:0x00电机方向:0x0A

    您的讲师要求初始化,不是分配。在char str[] = "fubar";char str[] = {'h','e','l','l','o','\0'}; 中,str 被声明并初始化为存储一个对应于“fubar”的字符串。在char str[6]; strcpy(str, "fubar"); 中,str 是在没有初始化的情况下声明的,并且“fubar”中的每个字节都被复制(分配)到 str 中的相应位置。你如何初始化一个结构?与第二次 str 初始化非常相似。

    struct length_prefixed_string {
        size_t length;
        int zero;
        char string[];
    };
    
    /* Initialisation here: */
    struct length_prefixed_string hello = { .length = 5,
                                            .string = "hello" };
    

    这个例子使用了一个灵活的数组成员,它只能在结构体的末尾声明:char string[];。它传达了一个位于结构末尾的未知长度数组,不计入sizeof (struct length_prefix_string)。因此,该示例将 unknown length 存储在 length 参数中。这有点离题,但您可以在上面看到一个初始化(而不是赋值)。这个例子区分了初始化和赋值;您不能将此结构的.string 成员分配给hello.string = "hello";

    另一个区别是:初始化未提及的任何成员都将被分配一个值(但仅在存在初始化时),因此@987654335的值上面示例中的@ 将为0。因此,您可以声明一个数组并用一条语句将其填零:int array[size] = { 0 };(赋值和初始化之间的另一个区别:int array[size]; array = { 0 }; 无效)。话虽如此,为了您的任务目的而忽略这一事实是个好主意,并明确初始化 greenLED 以便您的评分考官不会误解。

    希望我能帮到你,在这里...

    【讨论】:

    • 你是一个可修改的左值向导,非常感谢你的帖子。我确实有很多问题,但我会自己做一些研究,看看我是否可以解决它们......如果不能......你可以确定你会收到我的来信很快 :) 再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多