c复制一个const结构数组

 聆听最遥远的歌声 发布于 2022-12-20 19:06

我有一个结构数组,一些结构成员是常量我想做一个数组的深层副本.该副本也将具有与常量相同的结构成员.如何在不违反const指令的情况下将值初始化为新数组.

下面是我的代码的摘录.实际的程序很长,但我想我已经包含了所有相关的代码.在这个例子中,被声明为一个全局变量,我想从中创建新的实例.我认为它有点像带预设值的模板.

当我尝试使用gcc在Debian中编译它时,我收到以下错误:

main.c:216:9: error: assignment of read-only location ‘*(new_keys + (unsigned int)((unsigned int)index * 540u))’make: *** [main.o] Error 1

makefile使用以下限定符:

CFLAGS=-c -g -std=gnu99 -D_XOPEN_SOURCE=700

有趣的是.即使为C语言方言GNU99设置了Xcode,我也可以在Xcode中编译相同的代码而不会出现错误或警告[-std = gnu99]

我可以简单地通过去除const关键字来使我的代码工作.但这些价值确实应该是常数.一旦这些数组初始化,它们将永远不会改变.我想了解如何正确地做到这一点,并且我想知道为什么这在Xcode而不是gcc中有效.

头文件

typedef struct {
    char * name;
    char * alias;
    int number;
} pair_int_t;

typedef struct {
    const char * const name;
    const kind_t kind; // kind is enum type
    const pair_int_t * const enum_array; 
    bool received; 
    const char * const alias; 
} key_descriptor_t;

typedef key_descriptor_t keys_descriptor_t[_END_OF_KEYS+1];

main()之前的.c程序体

const pair_int_t command_list[] = {
    {.name = "numeric data response",        .alias = "num",         .number = RES_NUMERIC_DATA},
    {.name = "read attribute",               .alias = "readat",      .number = CMD_READ_ATTR},
    //..
}

// declare a global variable *keys* with constants assigned to it
key_descriptor_t keys[] = {
    [_COMMAND]          = {.name = "command",           .kind = ENUMERATED, .alias = "com",    .enum_array = command_list},
    [_RESPONSE]         = {.name = "response",          .kind = ENUMERATED, .alias = "res",    .enum_array = command_list},
    [_UNIT]             = {.name = "unit number",       .kind = NUMBER,     .alias = "uni",    .enum_array = NULL},
//..
}

int initialize_new_keys(keys_descriptor_t new_keys) {
    int index;
    for (index = _FIRST_KEY; index <= _END_OF_KEYS; index++){
        new_keys[index] = keys[index];      // line 216, keys is a global variable  
    }
    return index;
}

主程序

int main(int argc, const char * argv[]){
    keys_descriptor_t 2nd_set_of_keys;
    initialize_new_keys(2nd_set_of_keys);
}

Crowman.. 5

您只能const在定义变量时初始化变量.创建一个包含const成员的数组,将其发送到函数,然后尝试分配给这些成员,这意味着您const首先并不是真正的意思.C中没有" const除第一次分配外"的语法.

一个合理的替代方法是创建一个opaque类型,将定义封装在一个单独的转换单元中,然后纯粹通过函数接口访问所有成员.这样,即使事情可能不存在const,它们仍然无法更改(除非通过故意的颠覆,这至少不比不首先调用事物const好),因为没有使用它们的代码可以访问定义的struct,或因此给会员.

编辑:在回答评论中的问题时,"有没有办法创建一个复杂的常量变量并将其初始化为另一个现有的同一类型常量变量的值?",确实存在 - 只需正常初始化它:

struct mystruct {
    const int a;
    const int b;
};

static const struct mystruct m = {1, 2};

int main(void) {
    struct mystruct n = m;
    return 0;
}

显然,你越复杂struct,它就越复杂.

1 个回答
  • 您只能const在定义变量时初始化变量.创建一个包含const成员的数组,将其发送到函数,然后尝试分配给这些成员,这意味着您const首先并不是真正的意思.C中没有" const除第一次分配外"的语法.

    一个合理的替代方法是创建一个opaque类型,将定义封装在一个单独的转换单元中,然后纯粹通过函数接口访问所有成员.这样,即使事情可能不存在const,它们仍然无法更改(除非通过故意的颠覆,这至少不比不首先调用事物const好),因为没有使用它们的代码可以访问定义的struct,或因此给会员.

    编辑:在回答评论中的问题时,"有没有办法创建一个复杂的常量变量并将其初始化为另一个现有的同一类型常量变量的值?",确实存在 - 只需正常初始化它:

    struct mystruct {
        const int a;
        const int b;
    };
    
    static const struct mystruct m = {1, 2};
    
    int main(void) {
        struct mystruct n = m;
        return 0;
    }
    

    显然,你越复杂struct,它就越复杂.

    2022-12-20 19:11 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有