[英]“use of undeclared identifier” when typecasting void pointer to struct pointer
I am new to C and as a (classic) exercise I am trying to implement some operations on linked lists. 我是C语言的新手,作为(经典)练习,我试图在链接列表上实现一些操作。 I haven't gotten very far yet, though... When I am trying to declare and initialize the root node as follows:
但是,我还没有走的很远...当我尝试如下声明和初始化根节点时:
#include <stdlib.h>
struct intNode_t {
int data;
struct intNode_t* next;
};
int main() {
struct intNode_t* root = ( intNode_t* ) malloc( sizeof( struct intNode_t ) );
return 0;
}
the compiler (clang) is giving me the error "use of undeclared identifier" at the place where I am trying to typecast the void pointer returned by malloc to a pointer to intNode_t. 编译器(clang)在尝试将malloc返回的void指针转换为指向intNode_t的指针的地方,给我错误“使用未声明的标识符”。 I realise this is a noob question, but I couldn't find the answer elsewhere.
我意识到这是一个菜鸟问题,但我找不到其他答案。 Any suggestions?
有什么建议么?
The names of structs in C occupy a separate namespace from the space of names of fundamental types and typedefs (see this question for details). C中的结构名称与基本类型名称和typedef的名称空间无关(请参阅此问题以获取详细信息)。 Therefore, the name of your struct type is
struct intNode_t
; 因此,您的结构类型的名称为
struct intNode_t
; there is no type called intNode_t
. 没有称为
intNode_t
类型。
You can either always spell out the name as struct intNode_t
, or you can create a type alias for it. 您可以始终将名称拼写为
struct intNode_t
,也可以为其创建类型别名。 There are many different patterns of this in real code: 实际代码中有许多不同的模式:
Separate tag name, separate declaration: 单独的标签名称,单独的声明:
typedef struct foo_t_ foo_t;
struct foo_t_ { /* ... */ };
This allows you to put the type alias in a header and publish it as an opaque API type without ever revealing the actual type definition. 这样,您就可以将类型别名放在标头中,并将其发布为不透明的API类型,而无需透露实际的类型定义。
Separate tag name, typedef in struct definition: 单独的标记名称,结构定义中的typedef:
typedef struct foo_t_ { /* ... */ } foo_t;
Reuse name: 重用名称:
typedef struct foo_t { /* ... */ } foo_t;
This style allows users to be careless about spelling foo_t
or struct foo_t
. 这种样式使用户
foo_t
担心拼写foo_t
或struct foo_t
。
Don't name the struct: 不要命名结构:
typedef struct { /* ... */ } foo_t;
However, in your code you don't actually need to repeat the name, since you should not cast the result of malloc
and instead rely on the built-in implicit conversion from void pointer to object pointer. 但是,在代码中,您实际上不需要重复名称,因为您不应该
malloc
转换malloc
的结果,而是依靠从void指针到对象指针的内置隐式转换。 You also shouldn't repeat the type that's already known, and use the expression form of sizeof
instead. 您也不应重复已知的类型,而应使用
sizeof
的表达式形式。 So you want: 所以你要:
int main()
{
struct intNode_t* root = malloc(sizeof *root);
}
(Also note that return 0
is implied from main
.) (还要注意,从
main
隐含return 0
)
No need to repeat yourself. 无需重复自己。 If you don't repeat yourself you can make fewer errors.
如果您不重复自己,则可以减少错误。
struct intNode_t *root;
root = malloc( sizeof *root );
malloc()
returns a void*
, which is exchangeable with every (non-function) pointer type. malloc()
返回一个void*
,它可以与每种(非函数)指针类型互换。 sizeof(type)
and sizeof expression
The first one needs ()
, the second one does not. sizeof(type)
和sizeof expression
第一个需要()
,第二个不需要。 Most people prefer the second form, because the expression (in your case *root
) always will yield the correct type, and thus: size. *root
)总是会产生正确的类型,因此:size。 And, the definition + assignment above can be combined into a definition + initialiser, all fitting on one line: 并且,上面的定义+赋值可以组合为一个定义+初始化程序,所有这些都适合于一行:
struct intNode_t *root = malloc( sizeof *root );
Name intNode_t
was not declared in the program. intNode_t
中未声明名称intNode_t
。 There is declared structure tag name intNode_t
. 声明了结构标签名称
intNode_t
。
So you need to write 所以你需要写
struct intNode_t* root = ( struct intNode_t* ) malloc( sizeof( struct intNode_t ) );
Or you could introduce identifier name intNode_t
the following way 或者您可以通过以下方式引入标识符名称
intNode_t
typedef struct intNode_t {
int data;
struct intNode_t* next;
} intNode_t;
In this case you may write 在这种情况下,您可以写
struct intNode_t* root = ( intNode_t* ) malloc( sizeof( struct intNode_t ) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.