初始化后立即更改变量?

时间:2017-10-23 10:17:55

标签: c struct initialization

我正在使用Nordic Semiconductor的nRF51芯片编写蓝牙网格应用程序,在查看一些示例时,我偶然发现了这些代码:

nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_INVALID, 0, NULL};
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;

当我读到这个片段address时,首先定义了一些立即再次更改的变量。 这个双重定义不是不必要的吗?

nrf_mesh_addrees_t的定义如下:

typedef struct
{
    nrf_mesh_address_type_t type;
    uint16_t value;
    const uint8_t* p_virtual_uuid;
} nrf_mesh_address_t;

我的第一个想法是p_virtual_uuid被声明为const所以在定义之后无法更改,但是在将代码更改为此时我没有收到编译错误:

nrf_mesh_address_t address;
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;
                   address.p_virtual_uuid = NULL;

使用不同的变量定义变量两次有什么好处吗?

3 个答案:

答案 0 :(得分:6)

是的,这似乎非常多余。

如果你正在使用C99,我建议:

nrf_mesh_address_t address = { .type = NRF_MESH_ADDRESS_TYPE_GROUP,
                               .value = GROUP_ADDRESS,
                               .p_virtual_uuid = NULL };

const指的是指向的数据,而不是指针本身。后者将是uint8_t * const p_virtual_uuid

答案 1 :(得分:2)

数据成员

const uint8_t* p_virtual_uuid;

不是常量数据成员。它是一个指向常量对象的非常量指针。

指向常量对象的常量指针的声明将类似于

const uint8_t * const p_virtual_uuid;

在这种情况下,当定义了结构类型的对象时,你的indead会初始化数据成员。

此代码段中声明后面的表达式语句

nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_GROUP, 0, NULL};
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;

是多余的。

你可以写

nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_INVALID, GROUP_ADDRESS, NULL};

或者您可以在初始化列表中使用指示符。例如

nrf_mesh_address_t address = 
{ 
    .type = NRF_MESH_ADDRESS_TYPE_INVALID, 
    .value = GROUP_ADDRESS, 
    .p_virtual_uuid = NULL
};

与C ++相反,C中的支撑列表初始化器存在一个问题。初始化表达式的评估未被排序。因此,如果一个initioalizer的值取决于另一个初始化程序的值,那么确实你需要使用赋值而不是在括号括起的列表中初始化表达式。

从C标准(6.7.8初始化)

  

23其中任何副作用发生的顺序   初始化列表表达式未指定。

答案 2 :(得分:1)

你是正确的,因为它们是多余的,它等同于你的最后一段代码片段。

但是我确实看到了第一次使用的潜在价值。例如,如果要强制执行始终初始化变量的策略。您可以进行默认初始化

nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_INVALID, 0, NULL};

可用并准备复制粘贴。

这可以避免这样的情况:

nrf_mesh_address_t address;
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;

我想设置typevalue并将p_virtual_uuid保留为默认值。但是我忘了初始化它,所以现在我的代码中有bug。

然而,这种做法的价值是值得商榷的。我只想展示一种可能的有效动机。