Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 分配给结构成员的值不正确_C_Struct_Enums_Bit Fields - Fatal编程技术网

C 分配给结构成员的值不正确

C 分配给结构成员的值不正确,c,struct,enums,bit-fields,C,Struct,Enums,Bit Fields,我完全不知道这里发生了什么,我真的很想知道 我有一个枚举: typedef enum { TAxCLK = 0, ACLK, SMCLK, INCLK } TIMER_A_CLOCK_E; 和一个结构: typedef struct { BYTE byTimerSelection :2; TIMER_A_CLOCK_E eClockSource :2; INPUT_DIV_E eInputDivider

我完全不知道这里发生了什么,我真的很想知道

我有一个枚举:

typedef enum
{
    TAxCLK = 0,
    ACLK,
    SMCLK,
    INCLK

} TIMER_A_CLOCK_E;
和一个结构:

typedef struct
{
    BYTE byTimerSelection           :2;
    TIMER_A_CLOCK_E eClockSource    :2;
    INPUT_DIV_E eInputDivider       :2;
    TIMER_MODE_E eTimerMode         :2;

} TIMER_A_S;
其中,最后两个成员是与另一个成员类似的枚举,第一个成员只是一个
无符号字符
。这个
struct
用于初始化微控制器上的寄存器,因此我将每个字段限制为2位

我分配
结构的成员,如下所示:

 TIMER_A_S stTimerInfo;

 // Setup Timer A
 stTimerInfo.byTimerSelection = 0;
 stTimerInfo.eClockSource = SMCLK;
 stTimerInfo.eInputDivider = INPUT_DIV_1;
 stTimerInfo.eTimerMode = UP;

然而,
eClockSource
成员的行为异常。Code Composer调试器将字段显示为32位而不是2位,最后分配给它的值是-2而不是2。经过一些实验,我发现写0导致它读0,写5导致它读2。。。发生什么事?其他成员表现得很好。它是一个用于32位控制器的TI ARM编译器。

如果位字段的类型不是
\u Bool
有符号int
int
无符号int
,则不可移植

大小为
:2
的有符号位字段可以保存
-2、-1、0、1
的值。由于您似乎正在获取这些值,这意味着您的实现正在对这些位字段进行签名

听起来您需要的是无符号位字段,所以我建议使用
无符号int


注意。在位字段中,它的实现定义了
int
是指
signed int
还是
unsigned int
。因此,如果您使用纯
int
,它仍然可能根据编译器或设置提供不同的范围。

该标准允许编译器扩展位字段。许多人这样做是为了更好的表现。编译器实现这一点非常常见

     unsigned somefield: 2 ;

作为32位。我不鼓励完全使用位字段。它们不便于携带。如果需要特定宽度的位字段,最好的方法是使用按位运算符插入和提取。

Re。调试问题,可能是调试器不知道位字段,也可能是调试器在显示它之前升级了结果Timer_A_CLOCK_E是问题顶部定义的枚举。从我所读到的/听说的,你不能强迫枚举不签名,所以这是一个糟糕的哈哈。我想我会重新定义一些东西。@Swarlesbarkley我只需要写
unsigned int eClockSource:2
等。在你的结构定义中,没有必要在其中重复枚举名。“有一个不是_Bool、signed int、int或unsigned int类型的位字段是不可移植的。”--枚举将属于此类型,因为它们被视为
有符号int
对吗?@swarlesbarkley枚举将属于此类型,因为它们是
enum
。名称
enumfoo
实际上是它自己的一种类型,尽管在C中,enum的元素实际上并不采用这种类型!C标准要求大小为
2
的位字段实际上表现为一个2位整数(例如,如果它是无符号的,并且保持值
3
,并且您将其递增,它将导致
0
)。但是,字段周围可能有未使用的填充位。