c 制作一个 const 结构数组的副本

标签 c arrays struct copy constants

我有一个结构数组,其中一些结构成员是常量 我想对数组进行深拷贝。 该副本还将具有与结构相同的成员 be 常量。 如何在不违反 const 指令的情况下将值初始化到新数组中。

下面是我的代码的摘录。实际程序很长,但我想我已经包含了所有相关代码。在此示例中,keys 被声明为全局变量,我想从中创建新实例。我将其视为具有预设值的模板。

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

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

有趣的是。我可以在 Xcode 中编译相同的代码而不会出现错误或警告,即使 Xcode 设置为 C 语言方言 GNU99[-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);
}

最佳答案

您只能在定义变量时初始化 const 变量。创建一个包含 const 成员的数组,将其发送给一个函数,然后尝试分配给这些成员意味着您一开始并不是真的想要 const。 C 语言中没有“const 除了第一个赋值”的语法。

一个合理的替代方案是制作一个不透明类型,将定义封装在一个单独的翻译单元中,然后完全通过函数接口(interface)访问所有成员。这样,即使事物可能不是 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 越复杂,它就会变得越复杂。

关于c 制作一个 const 结构数组的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25902711/

相关文章:

c - 如何连接数组中的整数和字符串

scala - Scala案例类-它们只是结构吗?

c - scanf 在第一个 [C] 后停止工作

c++ - 用 "pointers"在 C 中定义数据 block

用于 10000 的数组乘法的 c++ 内联函数

arrays - 将 VBA 数组传递给公式

struct - 如何在结构定义中初始化数组?

c - 在开始时使用 "\r"更新进度条字符串,跳过或错过迭代

c - 用 Bloodshed 在 C 语言中为文本添加颜色

c - LAPACKs dsyevr 函数(用于特征值和特征向量)不应该是线程安全的吗?