【问题标题】:expected declaration specifiers or '...' before 'record_t' in header files c头文件 c 中“record_t”之前的预期声明说明符或“...”
【发布时间】:2018-09-03 12:38:21
【问题描述】:

我是 C 中这个头文件的新手。

我正在尝试使用 makefile 将我的代码文件一起编译。每个头文件有 2 个头文件和 2 个 c 文件,还有 1 个 main.c 文件。

我有 main.c 这是我的主要功能,它有“#include”dict2.h“”。 dict1 和 dict2 标头有些相同。不同的是dict2有额外的链表功能。

-bash-4.1$ make dict1
gcc -Wall -c main.c -o main.o -g
In file included from main.c:6:
dict2.h:1: warning: useless storage class specifier in empty declaration
dict2.h:8: warning: useless storage class specifier in empty declaration
dict2.h:21: error: expected declaration specifiers or '...' before 'record_t'
dict2.h:24: error: expected declaration specifiers or '...' before 'record_t'
dict2.h:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
dict2.h:45: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
dict2.h:48: error: expected ')' before '*' token
make: *** [main.o] Error 1

我的 dict2.h 函数看起来像这样:

typedef struct record_t;

typedef struct node_list node_list_t;

struct node_list;

typedef struct list_t;

typedef struct node node_t;

struct node;

node_t* transform_input(FILE *finput, node_t *root);

//line 21
node_t* bst_insert(node_t *root, record_t* data);

//line 24
node_t* bst_create_node(node_t* root, record_t* data);

node_t* bst_search(node_t* root, char* name_keyword, int* numcomparison);

void search_then_print(char* keyword, node_t* root, FILE* foutput, \
   int* numcomparison);

void freeTree(node_t *root);

void print_record(FILE* foutput, node_t* targetnode, char* keyword,\
  int* numcomparison);

//line 42
list_t *insert_at_foot(list_t *list, record_t *datarecord);

//line 45
list_t *create_empty_list(void);

//line 48
void free_list(list_t* list);

我查看了网上的讨论,但并试图修复它,但我在头文件中找不到错误。

感谢您的帮助。

【问题讨论】:

  • typedef struct record_t;?你是不是错过了什么?
  • 关于头文件的一些事情。首先,您应该在每个头文件中都有一个包含保护。其次,头文件应该只包含您希望在其他模块中导出和使用的函数的声明。如果dict.c 是一个模块,它应该只有dict.h 的符号,它导出用于例如。 main.c.
  • 哦,我得到了“typedef struct record_t;”在 dict2.h 的顶部,我忘了把它复制到我的问题中
  • 是的,编译器正在抱怨该行。查看下一行,看看您的 typedef 应该是什么样子。
  • 我为每个标题和 typedef struct record_t 添加了包含保护;但后来我仍然得到错误

标签: c makefile header-files


【解决方案1】:

声明:

typedef struct record_t;
typedef struct list_t;

错过了类型名称。

应该是:

typedef struct record record_t;
typedef struct list list_t;

【讨论】:

    【解决方案2】:

    在下面,我使用 struct tagtype identifier。我用谷歌搜索了一下,在Wikipedia 上找到了一个(恕我直言)非常容易理解的解释。


    一些程序员老兄提到了这一点,但您似乎没有理解他的意思。所以,我稍微详细说明一下:

    这是有效的:

    struct Node {
      struct Node *pNext;
    };
    

    并且可以和struct一起使用:

    void insert_after(struct Node *pNode);
    

    对于那些懒得输入struct 总是typedef 的人可以提供帮助:

    struct Node {
      struct Node *pNext;
    };
    typedef struct Node Node;
    

    它可能看起来令人困惑,但编译器将struct 标记和类型分隔在单独的列表中。因此,第一个和第二个Node 不是标识符“碰撞”。

    两者都可以同时完成:

    typedef struct Node {
        struct Node *pNext;
    } Node;
    

    假设没有“递归”使用类型的另一种情况,struct 标记甚至可以省略:

    typedef struct {
      int year, month, day;
    } Date;
    

    这是一个struct 类型,可以在没有struct 关键字的情况下独占使用。

    我认为这是写作时的意图

    typedef struct record_t;
    

    但是编译器不会按照作者的意图解释它。编译器将其读取为struct,带有标签record_t,并且缺少类型标识符。

    这就是我的阅读方式

    warning: useless storage class specifier in empty declaration
    

    (知道typedef 在编译器中像staticextern 一样在语法上处理,因此被视为存储类,尽管这对每个人来说似乎都不是很明显。)

    我必须承认我不知道如何解释

    error: expected declaration specifiers or '...' before 'record_t'
    

    但我会忽略这一点,只修复typedef 中的弱点(并将错误计为后续错误。)

    我还必须承认,我不知道如何使用匿名 struct 解决这个问题,并采用带有“重复使用”作为类型标识符的标签的 struct 的想法:

    #include <stdio.h>
    
    /* typedef for an incomplete struct */
    typedef struct Date Date;
    
    /* use incomplete struct type for prototype of function */
    void printDate(Date *pDate);
    
    /* define the complete struct */
    typedef struct Date {
      int year, month, day;
    } Date;
    
    /* implementation of function */
    void printDate(Date *pDate)
    {
      printf("%04d/%02d/%02d", pDate->year, pDate->month, pDate->day);
    }
    
    /* check this out */
    int main(void)
    {
      Date date = { 2018, 9, 3 };
      printDate(&date);
      return 0;
    }
    

    输出:

    2018/09/03
    

    Live Demo on ideone

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 2014-06-08
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多