我已经声明了结构
struct wnode {
char *word;
int lines[MAXLINES];
struct wnode *left;
struct wnode *right;
};
和指针
struct wnode *p;
将指针传递给函数。
在该函数中,我首先使用malloc为指针分配内存。然后我想将结构成员 lines 初始化为零将结构成员 lines 归零。
数组初始化方法将不起作用,因为它被解释为赋值:
p->lines[MAXLINES] = {0};
编译器抛出错误:
错误:“ {”令牌之前的预期表达式
最后,我只是使用for循环将 lines 数组归零:
for (i = 0; i < MAXLINES; i++)
p->lines[i] = 0;
有更好的方法吗?
答案 0 :(得分:6)
不能将数组直接分配给。您需要使用循环将所有字段设置为0,也可以使用memset
:
memset(p->lines, 0, sizeof(p->lines));
请注意,对于非字符类型,只能将所有成员设置为0。对于其他任何值,都需要循环。
答案 1 :(得分:5)
如果您想使用=
运算符,可以通过以下方式进行操作:
struct wnode wn, *p;
/* ........ */
wn = (struct wnode){.word = wn.word, .lines = {0,}, .left = wn.left, .right = wn.right};
*p = (struct wnode){.word = p ->word, .lines = {0,}, .left = p -> left, .right = p -> right};
答案 2 :(得分:4)
= {0}
仅适用于初始化。您不能将其与分配一起使用,这就是为什么您会收到错误消息。
您可以按照您所说的使用for
循环,也可以使用memset
将数组归零:
memset(p -> lines, 0, sizeof(p -> lines))
答案 3 :(得分:2)
只能以这种方式初始化数组变量:
int someInt[MAXLINES] = {0};
在声明中。
但是由于此特定变量int lines[MAXLINES];
是在struct
的范围内声明的,因此不允许初始化成员,因此该方法失去了机会,要求在事实发生后对其进行初始化,并使用其他方法。
在这种情况下,声明后初始化的最常见(也是首选)方法是使用:
//preferred
memset(p->lines, 0, sizeof(p->lines));
一种比较费力的方法,并且经常看到,它在循环中将每个元素设置为所需的值:
for(int i=0;i<MAXLINES;i++)
{
p->lines[i] = 0;
}
正如评论中所指出的,无论如何,一个好的优化编译器将把这种方法减少到相当于memset()
语句。
答案 4 :(得分:1)
void *memset(void *s, int c, size_t n)
memset()函数填充内存区域的前n个字节 指向s的常量字节c。
memset()函数返回一个指向存储区s的指针。
尽管(sizeof(int)*MAXLINES)
和sizeof(p->lines)
的字节结果相同,并且都是正确的 BUT ,但第二个选项(sizeof(p->lines)
)更好用,因为如果我们决定更改数组类型或数组大小,则无需更改szieof运算符内的表达式。我们只在一个地方改变。所以我们让编译器为我们完成工作!
#include <string.h> /*for the memset*/
memset(p->lines, 0x0, sizeof(p->lines));
答案 5 :(得分:1)
此指针声明
struct wnode *p;
如果指针具有静态存储持续时间,则将指针p
零初始化,或者如果指针具有自动存储持续时间,则使指针未初始化,因此将运算符->应用于指针会调用未定义的行为,因为指针确实没有指向有效的对象。
如果假设指针指向有效对象,例如
struct wnode w;
struct wnode *p = &w;
然后在函数中,您可以使用标准C函数memset
初始化对象w的数据成员行。例如
memset( p->lines, 0, MAXLINES * sizeof( int ) );
您可能不会只在函数中编写
p->lines = {0};
因为已创建了指向对象,并且在数组的声明中允许进行此类初始化。而且数组没有赋值运算符。
答案 6 :(得分:1)
这种初始化只能在声明时完成。注意,在p->lines[MAXLINES] = {0};
中,表达式p->lines[MAXLINES]
表示 p->行末尾的整数。
您可以写p->lines[MAXLINES] = 0;
。不正确,但可以编译。
您不再具有 array 的概念。您可以使用p->lines
(它是一个指向int的指针)或p->lines[index]
(它是一个int)。
是的,您已经分配了空间,仅此而已。 memset
可以解决问题。
顺便说一句,希望您的函数(或调用方)分配wnode元素...
答案 7 :(得分:1)
{0}
仅在初始化中起作用,而不在分配中起作用。
由于无法初始化指针目标,只能对其进行分配,因此可以通过分配刚初始化的复合文字来解决该问题。
编译器通常会优化复合文字并将其直接分配给目标。
{0}
初始化大型数组通常会编译为对memset
或等效程序集的调用,因此另一种选择是手动在memset
上直接调用p->lines
。 / p>
示例:
#define MAXLINES 100
struct wnode {
char *word;
int lines[MAXLINES];
struct wnode *left;
struct wnode *right;
};
//(hopefully) elided compound literal
void wnode__init(struct wnode *X)
{
*X = (struct wnode){"foo",{0},X,X};
}
//explicit memset
#include <string.h>
void wnode__init2(struct wnode *X)
{
X->word = "foo";
memset(X->lines,0,sizeof(X->lines));
X->left = X;
X->right = X;
}
答案 8 :(得分:0)
@ ikegami对原始问题的评论需要作为答案。
使用calloc()
而不是malloc()
struct wnode *p;
// presumably you have N as the number of elements and
p = malloc(N * sizeof *p);
// replace with
//p = calloc(N, sizeof *p);