令人惊讶的是,即使是最小的程序也会在C中造成如此多的麻烦。
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
tree* tree = (tree*) malloc(sizeof(tree));
node *node = (node*) malloc(sizeof(node));
tree->nodes[0] = node;
return tree;
}
int main() {
return 0;
}
编译器说:
main.c: In function 'initTree':
main.c:17: error: expected expression before ')' token
main.c:18: error: expected expression before ')' token
你能帮忙吗?
答案 0 :(得分:13)
您使用了两个名为tree
和node
的变量,但您还将typedef
编辑为tree
和node
。
更改变量名称:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode;
return atree;
}
int main() {
return 0;
}
答案 1 :(得分:5)
tree
和node
是您的案例类型名称,不应在以后用作变量名称。
tree *initTree() {
tree *myTree = (tree*) malloc(sizeof(tree));
node *myNode = (node*) malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
}
答案 2 :(得分:3)
将(tree*)
和(node*)
更改为(struct tree*)
和(struct node*)
。你不能只说tree
,因为那也是一个变量。
答案 3 :(得分:2)
按如下方式更改initTree的主体:
tree* myTree = (tree *)malloc(sizeof(tree));
node *myNode = (node *)malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
答案 4 :(得分:1)
不要将typedef
'ed名称用作变量名,并且不需要在C中强制转换malloc();
。
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
tree->nodes[0] = malloc(sizeof(node));
return malloc(sizeof(tree));
}
int main() {
return 0;
}
答案 5 :(得分:0)
我认为Mehrdad的解释非常重要。
在C代码中,您定义一个与结构名称相同的变量(例如“node node;”)并不罕见。也许这不是一个好的风格;它常见于,例如, linux内核,代码。
原始代码中的真正问题是编译器不知道如何解释“(tree *)malloc”中的“tree”。根据编译错误,它显然被解释为变量。
答案 6 :(得分:0)
除了原始问题之外,这段代码,即使是正确的形式也不会起作用,这仅仅是因为tree::nodes
(对于C ++表示法而言)作为指针的指针不会指向任何东西在tree
已经被malloced之后立即使用。所以tree->nodes[0]
在普通指针的情况下基本上与*(tree->nodes)
相同,不能被解除引用。无论如何,这对于树来说是一个非常奇怪的头,但是你应该至少分配一个node*
来初始化指向指针的指针:
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(struct tree)); /* different names for variables */
/* ... */
/* allocate space for numNodes node*, yet numNodes needs to be set to something beforehand */
atree->nodes = malloc(sizeof(struct node*) * atree->numNodes);
node* anode = malloc(sizeof(struct node));
atree->nodes[0] = anode;
return atree;
}
答案 7 :(得分:0)
有趣的是,如果您只是将分配编写为:
,它会干净地编译tree *tree = malloc( sizeof *tree );
使用“sizeof variable”通常被认为是更好的风格 而不是“sizeof(type)”,在这种情况下是风格 约定解决了语法错误。我个人认为 这个例子是一个很好的案例,展示了为什么要进行类型转换 通常是一个坏主意,因为如果代码更少混淆 写成:
struct tree *tree = malloc( sizeof *tree );