首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >变量在初始化后立即更改?

变量在初始化后立即更改?
EN

Stack Overflow用户
提问于 2017-10-23 10:17:54
回答 3查看 112关注 0票数 1

我正在使用北欧半导体公司的nRF51芯片编写蓝牙Mesh应用程序,在查看一些示例时,我偶然发现了以下代码:

代码语言:javascript
复制
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的定义如下所示:

代码语言:javascript
复制
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,因此在定义之后不能更改它,但是在将代码更改为以下代码时,没有得到编译错误:

代码语言:javascript
复制
nrf_mesh_address_t address;
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;
                   address.p_virtual_uuid = NULL;

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-23 10:20:44

是的,这似乎是多余的。

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

代码语言:javascript
复制
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

票数 6
EN

Stack Overflow用户

发布于 2017-10-23 11:49:52

数据成员

代码语言:javascript
复制
const uint8_t* p_virtual_uuid;

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

指向常量对象的常量指针的声明如下

代码语言:javascript
复制
const uint8_t * const p_virtual_uuid;

在这种情况下,在定义了结构类型的对象时,索引已经对数据成员进行了ro初始化。

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

代码语言:javascript
复制
nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_GROUP, 0, NULL};
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;

是多余的。

你可以直接写

代码语言:javascript
复制
nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_INVALID, GROUP_ADDRESS, NULL};

或者可以在初始化程序列表中使用指示符。令人恼火

代码语言:javascript
复制
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初始化列表表达式中出现任何副作用的顺序未指定。

票数 2
EN

Stack Overflow用户

发布于 2017-10-23 10:25:58

您是正确的,因为它们是多余的,它相当于您的最后一个代码片段。

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

代码语言:javascript
复制
nrf_mesh_address_t address = {NRF_MESH_ADDRESS_TYPE_INVALID, 0, NULL};

可用,随时可复制粘贴。

这样可以避免出现这样的情况:

代码语言:javascript
复制
nrf_mesh_address_t address;
                   address.type = NRF_MESH_ADDRESS_TYPE_GROUP;
                   address.value = GROUP_ADDRESS;

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46886972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档