简体   繁体   English

当将void指针类型转换为结构指针时,“使用未声明的标识符”

[英]“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_tstruct 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 );
  • the cast is not needed; 不需要演员表; malloc() returns a void* , which is exchangeable with every (non-function) pointer type. malloc()返回一个void* ,它可以与每种(非函数)指针类型互换。
  • there are two syntax variants for sizeof: sizeof(type) and sizeof expression The first one needs () , the second one does not. sizeof有两种语法变体: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM