可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
It's amazing how even the littlest program can cause so much trouble in 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;
}
The compiler says:
main.c: In function 'initTree':
main.c:17: error: expected expression before ')' token
main.c:18: error: expected expression before ')' token
Can you please help?
回答1:
You're using two variables named tree
and node
, but you also have structs typedef
ed as tree
and node
.
Change your variable names:
#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;
}
回答2:
tree
and node
is your case are type names and should not be used as variable names later on.
tree *initTree() {
tree *myTree = (tree*) malloc(sizeof(tree));
node *myNode = (node*) malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
}
回答3:
Change (tree*)
and (node*)
to (struct tree*)
and (struct node*)
. You can't just say tree
because that's also a variable.
回答4:
Change the body of initTree as follows:
tree* myTree = (tree *)malloc(sizeof(tree));
node *myNode = (node *)malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
回答5:
Don't use typedef
'ed names as variable names, and there is not need to cast malloc();
in 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->nodes[0] = malloc(sizeof(node));
return malloc(sizeof(tree));
}
int main() {
return 0;
}
回答6:
I second that Mehrdad's explanation is to the point.
It's not uncommon that in C code you define a variable with the same name as the struct name for instance "node node;". Maybe it is not a good style; it is common in, e.g. linux kernel, code.
The real problem in the original code is that the compiler doesn't know how to interpret "tree" in "(tree*) malloc". According to the compiling error, it is obviously interpreted as a variable.
回答7:
Apart from the original question, this code, even in it's correct forms will not work, simply due to the fact that tree::nodes
(sorry for the C++ notation) as a pointer to a pointer will not point to anything usefull right after a tree
as been malloced. So tree->nodes[0]
which in the case of ordinary pointers is essentially the same like *(tree->nodes)
, can't be dereferenced. This is a very strange head for a tree anyway, but you should at least allocate a single node*
to initialize that pointer to pointer:
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;
}
回答8:
Interestingly, it does compile cleanly if you simply write the allocations as:
tree *tree = malloc( sizeof *tree );
It is often considered better style to use "sizeof variable"
rather than "sizeof( type )", and in this case the stylistic
convention resolves the syntax error. Personally, I think
this example is a good case demonstrating why typecasts are
generally a bad idea, as the code is much less obfuscated if
written:
struct tree *tree = malloc( sizeof *tree );