【问题标题】:Array of structure: Structure members are Enum Variables结构数组:结构成员是枚举变量
【发布时间】:2019-03-02 01:57:31
【问题描述】:

我正在尝试理解作为可重用固件开发指南一部分的代码。这本书对我来说太难了,但我仍然在努力理解代码。

在本书附带的示例代码中,有一个类似于下面的语法

typedef enum 
{

   DIO_MAX_MODE 
}DioMode_t;


typedef enum 
{
   DIO_PULLUP_DISABLED,     /*< Used to disable the internal pull-ups */
   DIO_PULLUP_ENABLED,      /*< Used to enable the internal pull-ups */
   DIO_MAX_RESISTOR         /*< Resistor states should be below this value */
}DioResistor_t;

typedef enum
{
    DIO_OUTPUT,
    DIO_INPUT
}DioDirection_t;



typedef struct 
{
    DioResistor_t Resistor;              /**< Pullup/Pulldown Resistor - ENABLED or DISABLED    */
    DioDirection_t Direction;      /**< Data Direction      - OUTPUT or INPUT           */
    DioMode_t Function;            /**< Mux Function        - Dio_Peri_Select           */
}DioConfig_t;

如果我理解正确,结构的成员是枚举变量。

并且在代码的一部分中,开发人员以下面的方式为其分配了一个值(不准确,我试图通过对其进行类似的语法来理解整个事情是如何工作的)

 DioConfig_t config[] = {    {1, 2, 3}, 
                                {4, 5, 6}
 };

这里发生了什么?这可能吗??

如上初始化时,会不会影响枚举的值,哪些值在变化,如何访问?

编辑:

如果我创建一个这样的结构

#include <stdio.h>

struct test {
    int a;
    int b;
};

int main()
{
    struct test var[] = { {1, 2}, {3, 4} }; 

    /* 
    struct test var[0] = {1, 2}
    struct test var[1] = {3, 4}
    */

    printf("%d %d\n", var[0].a, var[1].a);

    return 0;

根据我用来调用它们的结构变量,我知道为a 和b 分配了哪些值 例如:var[0].a = 1 和 var1.a = 3

但是我首先展示的代码有 enum 变量作为结构成员 所以分配给结构成员的值是

config[0].Resistor = 1
config[0].Direction = 2
config[0].Function = 3

既然这些是enum 变量,它会改变enum 的值吗?如何???

PS:我开始学习C才几个月,我用它来开发小型嵌入式项目,我阅读了一些在线教程和视频,了解了结构和指针,但是当我打开这个
code ,这对我来说没有多大意义。这正常吗??

【问题讨论】:

  • 究竟是什么让您感到困惑?这个例子不是很好的风格,但我不确定这是否是由于你的“(不准确,...)”真实代码的副本。枚举可以用数字吗?
  • 令人困惑的是,{4,5,6} 的值不在枚举的有效值范围内,还是其他原因?
  • 整个代码可以在我提供的驱动链接上找到。 Dio_cfg.c 和 Dio_cfg.h。令人困惑的部分是当我如上所述初始化时,如何将值分配给 struct 和 enum
  • 好的,那么超出范围的枚举值不是问题。但目前还不清楚哪一部分让你感到困惑。
  • @Gerhardh 我已经编辑了这个问题。你说的超出范围是什么意思??

标签: c struct enums


【解决方案1】:

这里发生了什么?这可能吗??

内部大括号({1, 2, 3} 和 {4, 5, 6})分别初始化一个 DioConfig_t。外大括号用内大括号定义的两个DioConfig_t 初始化数组config[]。相当于这样:

DioConfig_t a = {1, 2, 3};
DioConfig_t b = {4, 5, 6};
DioConfig_t config[] = {a, b};

令人困惑的是,大括号在这里做了两个不同的事情。一个是初始化结构体,一个是初始化数组。

注意:我不确定我的术语是否 100% 正确,当我说“它们是等效的”时,我并没有考虑到性能可能会因编译器优化级别而异。

这对我来说没有多大意义。这正常吗?

你是在问被一些C代码混淆是否正常?绝对地。该语言中有很多技巧、陷阱和晦涩难懂的东西,即使是使用它多年的人也会学到一些新东西,并时不时地被一些棘手的 C 代码弄糊涂/困惑。不要让这让你灰心。

【讨论】:

  • 但是如果创建一个普通的strcut test 变量int a int b 并创建结构变量为struct test var[] = { {1, 2}, {3, 4}} 然后根据你的解释printf("%d %d\n", var[0].a, var[1].a); 应该给出1和2,但分配的值是1, 3 还有enum 值如何受到影响?
  • 本应如此。在您的示例中,var[0] 是 {1, 2} 并且 var[1] 是 {3, 4},并且您正在分别打印它们的第一个值。
  • 由于struct成员是枚举,这如何改变enum的值??
  • 它不会修改底层枚举值。 struct DioConfig_t 中的那些枚举,它们基本上是具有更多类型安全性的整数。如您提供的代码所示,您可以将6 分配给DioMode_t Function,就好像Function 是int。最后,无论如何它只是(可能)4个字节的空间。我会说将6 分配给DioMode_t Function 是不好的设计,但这是完全合法的。
【解决方案2】:

基本上枚举是定义整数常量的另一种方法,因此枚举变量必须占用与整数变量相同的内存,因此基本上它可以保存任何整数值。在您的情况下,DioResistor_t 类型的枚举变量可以保存 0(DIO_PULLUP_DISABLED)、1(DIO_PULLUP_ENABLED) 和 2(DIO_MAX_RESISTOR) 以外的值。所以初始化枚举结构元素的其他值是可以的(但它可能导致无效的输出)。

我们现在将讨论将结构元素定义为枚举的原因。为此,请考虑以下两种情况。

案例 1:DioConfig_t 结构定义如下:

typedef struct
{
    unsigned int Resistor;
    unsigned int Direction;
    unsigned int Function;
}DioConfig_t;

案例 2:DioConfig_t 结构在您的代码中定义。

现在,如果开发人员想要将引脚配置为带拉电阻并处于最大模式的输出引脚。

在第一种情况下,他需要找到配置结构DioConfig_t 的电阻、方向和功能变量的值,这将根据需要配置引脚,但在第二种情况下,他可以轻松地将其配置为所有需要的值变量在枚举中定义。

以上2种情况下的配置如下:

案例一:

    Dio_Config_t dio_configuration;
    dio_configuration.Resistor = 1;
    dio_configuration.Direction = 0;
    dio_configuration.Function = 0;

案例 2:

    Dio_Config_t dio_configuration;
    dio_configuration.Resistor = DIO_PULLUP_ENABLED;
    dio_configuration.Direction = DIO_OUTPUT;
    dio_configuration.Function = DIO_MAX_MODE;

如您所见,第二种情况的代码更容易理解,也更安全,因为不会轻易更改值。

【讨论】:

    【解决方案3】:

    enum 是整数类型的特例。在 C 中,将值分配给超出该范围的 enum 变量是合法的。

    为enum 变量分配一个超出范围的值也不会影响任何已定义的enum 常量。另请注意,所讨论的变量是结构的成员这一事实不会改变任何事情。

    例如:

    #include <stdio.h>
    
    typedef enum f {
        F1,
        F2,
        F3
    } f;
    
    int main()
    {
        f x = 4;
        printf("F1=%d\n", F1);
        printf("F2=%d\n", F2);
        printf("F3=%d\n", F3);
        printf("x=%d\n", x);
        return 0;
    }
    

    输出:

    F1=0
    F2=1
    F3=2
    x=4
    

    在此示例中,值 4 分配给类型为 f 的变量,即使关联的 enum 的值是 0、1 和 2。

    【讨论】:

      猜你喜欢
      • 2021-09-26
      • 2013-12-30
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多