C 定义自定义时间结构

C 定义自定义时间结构,c,linux,C,Linux,议定书是: (four byte hour/minute/second field, for example (12:13:56 110)) bit00~bit01: 00 bit02~bit11: millisecond (110) bit12~bit15: second-1s (6) bit16~bit18: second-10s (5) bit19~bit22: minute-1s (3) bit23~bit25: minute-10s (1) bit26~bit29: hou

议定书是:

(four byte hour/minute/second field, for example (12:13:56 110))
bit00~bit01: 00
bit02~bit11: millisecond (110)
bit12~bit15: second-1s   (6)
bit16~bit18: second-10s  (5)
bit19~bit22: minute-1s   (3)
bit23~bit25: minute-10s  (1)
bit26~bit29: hour-1s     (2)
bit30~bit31: hour-10s    (1)
我应该如何定义上层结构

我试着定义一下:

struct xxx_time 
{
    unsigned int pad:2;
    unsigned int second0:4;
    unsigned int second1:3;
    unsigned int minute0:4;
    unsigned int minute1:3;
    unsigned int hour:4;
    unsigned int hour1:2;
};

这样定义对吗?有没有更好的方法?

我想这取决于你想用这些数据做什么。 数据结构的一个目标是更好或有效地存储和访问数据以服务于系统处理

例如,如果你想知道和处理小时,分钟,你写的是确定的。如果您只关心整个时间,那么一个时间变量就可以了


如何使用这些数据取决于您的要求。

我认为没问题,只是您忘记了毫秒字段

struct xxx_time 
{
    unsigned int pad:2;
    unsigned int milisecond:10;
    unsigned int second0:4;
    unsigned int second1:3;
    unsigned int minute0:4;
    unsigned int minute1:3;
    unsigned int hour:4;
    unsigned int hour1:2;
};
此外,如果
pad
字段实际上只是用于填充(您不会操纵它们),则可以使用未命名字段:

struct xxx_time 
{
    unsigned int :2;
    unsigned int milisecond:10;
    //...
}

请记住,几乎所有关于位字段的内容都依赖于实现

结构中位字段的内存布局由编译器定义。不能保证编译器会按照列出的顺序布局结构字段。例如,pad字段可能不是结构中的前两位。见和


因此,不能使用带有位字段的结构来映射已定义的底层内存布局。您必须使用位移位和掩码来读取和写入具有给定内存布局的缓冲区。

您的布局将与最新的gcc编译器(以及兼容程序,如icc)配合使用

此外,对于big-endian机器,您需要“反转”结构:

struct xxx_time {
#ifdef WORDS_BIGENDIAN
    unsigned int hour1:2;
    unsigned int hour:4;
    unsigned int minute1:3;
    unsigned int minute0:4;
    unsigned int second1:3;
    unsigned int second0:4;
    unsigned int milisecond:10;
    unsigned int:2;
#else
    ...
#endif
};
关于实现定义行为的注释仍然适用,因此您可能应该检查编译器生成的内容

考虑到C11(以及gnu99)允许匿名结构,这可以通过联合轻松完成,无需更改代码(只需更改结构类型的声明):


“:2;”无法编译,应为“unsigned int:2;”???@user2585549对,该类型仍然是必需的,已修复它。
union xxx_time_u {
    uint32_t ival;
    struct {
#ifdef WORDS_BIGENDIAN
        unsigned int hour1:2;
        ...
#else
        unsigned int:2
        ...
#endif
    };
};