C 中的结构数组参数
Structure Array arguments in C
我是 C 的新手,现在正在参加 class 并且在项目中遇到困难。我们在这个项目中有一个称为 Symbol 的结构。我们在这个项目中还有一个称为节点的结构。节点有一个符号数组。我要做的就是将 属性 Node.symbols 设置为另一个符号数组,如下所示:
int max = 256;
Symbol symbols[max];
Node node1;
node1.syms = symbols;
错误:比较 'struct Symbol[256]' 与类型 'Struct Symbol *'
时的类型不兼容
我真的不明白为什么它认为 symbols 是一个指针,而它对我来说似乎是一个符号数组。这可能真的很明显,但我无法修复它。
不能对数组使用赋值运算符 =
。您要么必须使用循环:
for (int i = 0; i < max; ++i)
{
node1.syms[i] = symbols[i];
}
或使用 memcpy:
memcpy(node1.syms, symbols, max * sizeof(symbols[0]));
顺便说一句,max
不适合用于数组维度(或与此相关的任何其他内容),因为它与 max()
function/macro 的名称冲突。
symbols 是一个指针。它是数组 symbols[256] 的头部,类型为 Symbol*。通过 [] 取消引用然后为每个增量添加 sizeof(Symbol),例如symbols[3] 在地址 symbols+3*sizeof(Symbols)
引用数组中的第 4 个元素
使用指针的 [] 比进行显式指针运算更安全
您没有 post Node
和 Symbol
的定义,但我认为 Node.syms
是一个数组。在这种情况下,问题是在 node1.syms = symbols;
行中,您尝试更改 Node
结构的 sysm
成员,但它是一个常量变量(每个数组都是常量,您不能更改其位置)。
你必须有多种可能性。
1.) 您将目标数组中的元素复制到 syms
数组:
int numelem = 256;
for (int i = 0; i < numelem; i++)
{
node1.syms[i] = symbols[i];
}
但是找出numelem
变量的完美值非常重要。也就是说,无处检查 node1.syms
和 symbols
数组是否具有相同数量的元素。如果它们的长度不相等,您可以在其中一个寻址非法内存区域时溢出。另一个可能的缺点是,在所有 Node
元素中, syms
数组将具有相同数量的元素,您只能在编译时更改它。
2.) 你改变定义 if Node
structure:
struct Node {
//...
struct Symbol *syms;
//...
}
在这种情况下,您的代码将被编译并且数组 node1.syms
将指向数组 symbol
,您不必关心数组的长度。但重要的是,在这种情况下,内存中只有一个数组!因此,您必须考虑到数组通常是在堆栈上分配的,这意味着在退出创建数组的方法后,数组的内存 space 也将被释放。如果你创建 node1
也是它的方法(如你的例子)就没问题。但是,如果您将 node1
创建为全局变量,那么 symbols
数组也必须是全局变量。一般来说,我们可以说两个变量都必须在同一范围内创建。
我是 C 的新手,现在正在参加 class 并且在项目中遇到困难。我们在这个项目中有一个称为 Symbol 的结构。我们在这个项目中还有一个称为节点的结构。节点有一个符号数组。我要做的就是将 属性 Node.symbols 设置为另一个符号数组,如下所示:
int max = 256;
Symbol symbols[max];
Node node1;
node1.syms = symbols;
错误:比较 'struct Symbol[256]' 与类型 'Struct Symbol *'
时的类型不兼容我真的不明白为什么它认为 symbols 是一个指针,而它对我来说似乎是一个符号数组。这可能真的很明显,但我无法修复它。
不能对数组使用赋值运算符 =
。您要么必须使用循环:
for (int i = 0; i < max; ++i)
{
node1.syms[i] = symbols[i];
}
或使用 memcpy:
memcpy(node1.syms, symbols, max * sizeof(symbols[0]));
顺便说一句,max
不适合用于数组维度(或与此相关的任何其他内容),因为它与 max()
function/macro 的名称冲突。
symbols 是一个指针。它是数组 symbols[256] 的头部,类型为 Symbol*。通过 [] 取消引用然后为每个增量添加 sizeof(Symbol),例如symbols[3] 在地址 symbols+3*sizeof(Symbols)
引用数组中的第 4 个元素使用指针的 [] 比进行显式指针运算更安全
您没有 post Node
和 Symbol
的定义,但我认为 Node.syms
是一个数组。在这种情况下,问题是在 node1.syms = symbols;
行中,您尝试更改 Node
结构的 sysm
成员,但它是一个常量变量(每个数组都是常量,您不能更改其位置)。
你必须有多种可能性。
1.) 您将目标数组中的元素复制到 syms
数组:
int numelem = 256;
for (int i = 0; i < numelem; i++)
{
node1.syms[i] = symbols[i];
}
但是找出numelem
变量的完美值非常重要。也就是说,无处检查 node1.syms
和 symbols
数组是否具有相同数量的元素。如果它们的长度不相等,您可以在其中一个寻址非法内存区域时溢出。另一个可能的缺点是,在所有 Node
元素中, syms
数组将具有相同数量的元素,您只能在编译时更改它。
2.) 你改变定义 if Node
structure:
struct Node {
//...
struct Symbol *syms;
//...
}
在这种情况下,您的代码将被编译并且数组 node1.syms
将指向数组 symbol
,您不必关心数组的长度。但重要的是,在这种情况下,内存中只有一个数组!因此,您必须考虑到数组通常是在堆栈上分配的,这意味着在退出创建数组的方法后,数组的内存 space 也将被释放。如果你创建 node1
也是它的方法(如你的例子)就没问题。但是,如果您将 node1
创建为全局变量,那么 symbols
数组也必须是全局变量。一般来说,我们可以说两个变量都必须在同一范围内创建。