C 编程:结构体初始化方式的区别

问题描述 投票:0回答:1

我有以下有效代码

wifi_config_t wifi_config = {
    .sta = {
        .ssid = EXAMPLE_ESP_WIFI_SSID,
        .password = EXAMPLE_ESP_WIFI_PASS,
        .threshold.authmode = WIFI_AUTH_WPA2_PSK,
        .pmf_cfg = {
            .capable = true,
            .required = false
        },
    },
};

这个失败了

wifi_config_t wifi_config;
memcpy(wifi_config.sta.ssid, ssid, strlen((const char*) ssid));
memcpy(wifi_config.sta.password, password, strlen((const char*) password));
wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK,
wifi_config.sta.pmf_cfg.capable = true;
wifi_config.sta.pmf_cfg.required = false;

但是,如果我改成这种方式,它就会起作用

wifi_config_t wifi_config = {
    .sta = {
        .threshold.authmode = WIFI_AUTH_WPA2_PSK,
        .pmf_cfg = {
            .capable = true,
            .required = false
        },
    },
};

memcpy(wifi_config.sta.ssid, ssid, strlen((const char*) ssid));
memcpy(wifi_config.sta.password, password, strlen((const char*) password));

使用 {...} 初始化和先声明变量,然后逐个赋值其字段有什么区别?

c initialization structure
1个回答
3
投票

您的第一个

memcpy
失败有两个原因:

  1. strlen
    不计算字符串 nul 终止。所以如果你的字符串是
    "abc"
    ,它只返回3,这不足以复制完整的字符串。您需要将
    +1
    添加到您的
    strlen
    结果中。

  2. wifi_config
    未初始化,这意味着您的字符串数组包含随机字符,在您的情况下,这些字符没有零值
    0
    可以充当 null。

原因 2 也是您的最后一个示例按预期工作的原因。 当您使用初始化程序时,您没有特别提到的字段将使用默认值进行初始化。对于整数类型数组,它们用零初始化。因此,即使您的

memcpy
无法复制 nul 终止符,也已经有零字节可以用于相同的目的。

我建议您始终至少将变量初始化为零:

wifi_config_t wifi_config = {0}; // Set all fields to 0 or NULL.
© www.soinside.com 2019 - 2024. All rights reserved.