c制作常量结构数组的副本
我有一个结构数组,其中一些结构成员是常量 我想制作阵列的深度副本。 副本还将具有与结构be常量相同的成员。 如何在不违反const指令的情况下将值初始化到新数组中 下面是我的代码摘录。实际的程序相当长,但我想我已经包含了所有相关的代码。在这个例子中,keys被声明为一个全局变量,我想从中创建新的实例。我把它当作一个有预设值的模板 当我尝试使用gcc在Debian中编译此代码时,我得到以下错误:c制作常量结构数组的副本,c,arrays,struct,copy,constants,C,Arrays,Struct,Copy,Constants,我有一个结构数组,其中一些结构成员是常量 我想制作阵列的深度副本。 副本还将具有与结构be常量相同的成员。 如何在不违反const指令的情况下将值初始化到新数组中 下面是我的代码摘录。实际的程序相当长,但我想我已经包含了所有相关的代码。在这个例子中,keys被声明为一个全局变量,我想从中创建新的实例。我把它当作一个有预设值的模板 当我尝试使用gcc在Debian中编译此代码时,我得到以下错误: main.c:216:9: error: assignment of read-only locati
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[-std=GNU99]设置了Xcode,我也可以在Xcode中编译相同的代码,而不会出现错误或警告
我只需去掉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
变量。创建一个包含const
成员的数组,将其发送到一个函数,然后尝试分配给这些成员,这意味着您一开始并不是指const
。除了第一个赋值,C中没有“const
的语法”
一种合理的替代方法是创建不透明类型,将定义封装在单独的翻译单元中,然后纯粹通过函数接口访问所有成员。这样,即使事物可能不是const
,它们仍然无法更改(除非通过故意颠覆,这至少不比不首先调用事物const
要好),因为使用它们的代码都无法访问结构的定义,也无法访问成员
编辑:在回答评论中的问题“是否有方法创建一个复杂常量变量并将其初始化为同一类型的另一个现有常量变量的值?”时,确实有-只需正常初始化即可:
struct mystruct {
const int a;
const int b;
};
static const struct mystruct m = {1, 2};
int main(void) {
struct mystruct n = m;
return 0;
}
显然,您的结构越复杂,它可能变得越复杂。第二组\u键”是一个结构,它应该是一个静态数组(或者可以是指针和动态保留内存),“new\u键”参数也会出现同样的问题。
尽管有点奇怪,但您可以使用memcpy()将数据复制到常量变量(覆盖常量验证)。我认为在我的结构定义中放置const
的位置会使结构常量的成员不是整个结构本身。所以当我赋值时,new_keys[index]=keys[index]代码>我以为我是在制作一个包含一些常量成员的非常量结构的副本,并将其放置在数组的非常量成员中。我在gcc中遇到的错误是否意味着我违反了const
属性?错误的540u部分是什么?问题是在创建整个struct
时会创建struct
成员(他们必须这样做,否则“创建struct
”实际上没有任何意义),所以一旦创建struct
成员,您就已经拥有了const
成员,如果您在创建时没有初始化它们,那么您就失去了这样做的机会。540u
只是一个等于540的无符号整数,它只是gcc在数组上进行指针运算。是的,这里的问题是违反const
@TimothyVann错误消息很奇怪,但错误肯定是您试图写入const位置。因此,当我进行赋值=keys[index]
(其计算结果为一个结构)时,我正在从keys[index]处的现有结构复制值在new_keys[index]处的另一个现有结构中,当我使用keys_descriptor_t第二组_keys创建数组时,该结构被初始化代码>?这是正确的吗?为什么使用gnu99的Xcode允许这样做,而gcc不允许这样做?
int main(int argc, const char * argv[]){
keys_descriptor_t 2nd_set_of_keys;
initialize_new_keys(2nd_set_of_keys);
}
struct mystruct {
const int a;
const int b;
};
static const struct mystruct m = {1, 2};
int main(void) {
struct mystruct n = m;
return 0;
}