我正在使用北欧半导体公司的nRF51芯片编写蓝牙Mesh应用程序,在查看一些示例时,我偶然发现了以下代码:
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;用不同的变量两次定义变量有什么好处吗?
发布于 2017-10-23 10:20:44
是的,这似乎是多余的。
如果你在使用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。
发布于 2017-10-23 11:49:52
数据成员
const uint8_t* p_virtual_uuid;不是常量数据成员。它是一个指向常量对象的非常量指针.
指向常量对象的常量指针的声明如下
const uint8_t * const p_virtual_uuid;在这种情况下,在定义了结构类型的对象时,索引已经对数据成员进行了ro初始化。
此代码段中声明后面的表达式语句。
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中的大括号列表初始化器存在一个问题。初始化表达式的计算没有排序。因此,如果一个初始化器的值取决于另一个初始化器的值,那么实际上您需要使用赋值,而不是在大括号内的列表中初始化表达式。
来自C标准(6.7.8初始化)
23初始化列表表达式中出现任何副作用的顺序未指定。
发布于 2017-10-23 10:25:58
您是正确的,因为它们是多余的,它相当于您的最后一个代码片段。
不过,我确实看到了第一次使用的潜在价值。例如,如果要强制执行始终初始化变量的策略。您可以进行默认初始化。
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;我希望设置type和value,并将p_virtual_uuid保留为默认值。但是,我忘了初始化它,所以现在我的代码中有bug。
然而,这种做法的价值值得商榷。我只是想证明一个可能有效的动机。
https://stackoverflow.com/questions/46886972
复制相似问题