【问题标题】:Error when defining a struct定义结构时出错
【发布时间】:2013-08-31 05:07:24
【问题描述】:

我试图写一个简单的链表只是为了练习和一点点记忆,但我遇到了麻烦。我在 C 方面非常缺乏经验,我不明白为什么这不起作用。我正在尝试定义一个 Node 和一个 LinkedList 结构,但是每次我尝试编译时都会收到一个错误消息,指出 Node 是未知类型。我确定我错过了一些东西,但我无法弄清楚。谢谢大家!

这是我的 ll.h 文件

  1 #ifndef ll_h
  2 #define ll_h
  3 
  4 #include <stdio.h>
  5 
  6 typedef struct {
  7     void *data;
  8     Node *next;
  9     Node *prev;
 10 } Node;
 11 
 12 
 13 typedef struct {
 14     Node *first;
 15     Node *last;
 16     int size;
 17 } LinkedList;
 18 
 19 
 20 void *getData(LinkedList list, int index);
 21 int getSize(LinkedList list);
 22 void *deleteNode(LinkedList, int index);
 23 void add(LinkedList list, void *data);
 24 void freeList(LinkedList list);
 25 
 26 #endif           

我收到的错误

cc -Wall -g   -c -o ll.o ll.c
In file included from ll.c:3:0:
ll.h:8:5: error: unknown type name ‘Node’
ll.h:9:5: error: unknown type name ‘Node’
ll.c: In function ‘getData’:
ll.c:8:18: error: expected expression before ‘LinkedList’
ll.c:12:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c: In function ‘getSize’:
ll.c:21:12: error: expected expression before ‘LinkedList’
ll.c: In function ‘deleteNode’:
ll.c:26:18: error: expected expression before ‘LinkedList’
ll.c:32:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c:37:12: error: request for member ‘next’ in something not a structure or union
ll.c:38:12: warning: assignment from incompatible pointer type [enabled by default]
ll.c:40:12: error: request for member ‘next’ in something not a structure or union
ll.c: In function ‘add’:
ll.c:52:16: warning: assignment from incompatible pointer type [enabled by default]
ll.c:54:21: warning: assignment from incompatible pointer type [enabled by default]
ll.c: In function ‘freeList’:
ll.c:61:18: error: expected expression before ‘LinkedList’
ll.c:62:18: warning: initialization from incompatible pointer type [enabled by default]
ll.c:65:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c:67:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c:62:11: warning: variable ‘next’ set but not used [-Wunused-but-set-variable]
ll.c:60:9: warning: unused variable ‘i’ [-Wunused-variable]
ll.c: In function ‘main’:
ll.c:85:6: error: ‘LinkedList’ has no member named ‘add’
ll.c:91:10: warning: dereferencing ‘void *’ pointer [enabled by default]
ll.c:91:10: error: void value not ignored as it ought to be
ll.c: In function ‘getSize’:
ll.c:22:1: warning: control reaches end of non-void function [-Wreturn-type]
make: *** [ll.o] Error 1

【问题讨论】:

  • 如果你使用的是 C++,杀掉所有的typedefs。
  • How to properly define a function pointer in struct, which takes struct as a pointer? 的可能重复项。问题的第二部分是关于递归结构,就像这个问题中的一样。可能还有其他重复项。
  • 由于代码是用 C 编译器编译的并且看起来像 C,因此我删除了 C++ 标记。在一个问题上同时包含两个标签很少是正确的——它们是不同的语言。

标签: c struct typedef


【解决方案1】:

使用这个:

typedef struct Node{
     void *data;
     struct Node *next; // note here
     struct Node *prev;
} Node;

【讨论】:

  • 在您的代码中,“typedef”不会为“struct Node”类型创建一个名为“Node”的别名吗?如果是这样,在结构节点定义的主体中引用节点(当我们指的是结构节点时)是否合法?
【解决方案2】:

您要么需要前向声明,要么需要删除 typedef。你也可以使用 typedef 来让节点两次。

前向声明

typedef struct Node Node; // Necessary in C, harmless (but non-idiomatic) in C++

typedef struct {
    void *data;
    Node *next;
    Node *prev;
} Node;

无 typedef(仅适用于 C++,不适用于 C)

struct Node {
    void *data;
    Node *next;
    Node *prev;
};

使用带有标签的 typedef

适用于 C 和 C++,但不适用于 C++。

typedef struct Node {
    void *data;
    struct Node *next;
    struct Node *prev;
} Node;

【讨论】:

  • @Jonathan:很好,我以为我们会在这里讨论 C++,但既然你删除了那个标签,我按照你的意愿更新了我的帖子!
【解决方案3】:

为谷歌搜索带来的下一位读者发布答案:
error: void value not ignored as it ought to be

请记住,在尝试实现伪代码时,函数指针会使用函数名称进行初始化,而无需任何括号。菜鸟失误?也许吧,但我并不完全是菜鸟(90 年代中期在大学教过 C/C++ 实验室),这让我受益匪浅。如果我输入它而不是剪切粘贴,我可能会发现错误,因为我知道不要创建该代码......

为完整性而提供的声明示例:

//  Static menu manager
#define MAX_SELECTIONS 4
#define MAX_PROMPT_LEN 20
typedef struct _selection {
    char prompt[MAX_PROMPT_LEN];
    void(*function) ( void );
    int fn_arg;
} SELECTION ;

typedef struct _menu {
    int id;
    int num_selections;
    SELECTION selection[MAX_SELECTIONS];
} MENU;

enum _menu_ids { MAIN_MENU, DEPOSIT_MENU, WITHDRAWL_MENU, BALANCE_MENU };
enum _menu_keys { DEPOSIT, WITHDRAWL, BALANCE, CHECKING, SAVINGS };



错误:

//  WRONG
static MENU menu[] = {
    { MAIN_MENU, 4,
        {"Perform A Deposit", goto_menu(), DEPOSIT_MENU},
        {"Perform a Withdrawl", goto_menu(), WITHDRAWL_MENU },
        {"Get Balance", goto_menu(), BALANCE_MENU },
        {"Hide Menu", menu_hide(), 0}
    }
}



正确:

//  Correct
static MENU menu[] = {
    { MAIN_MENU, 4, {
        {"Perform A Deposit", goto_menu, DEPOSIT_MENU},
        {"Perform a Withdrawl", goto_menu, WITHDRAWL_MENU },
        {"Get Balance", goto_menu, BALANCE_MENU },
        {"Hide Menu", menu_hide, 0} }
    }
}

特别细心的读者可能会注意到伪代码中缺少初始化structarray 成员所需的额外大括号。 gcc 编译器提供了一个有用的错误:
MENU: improper number of initializers

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    相关资源
    最近更新 更多