C未知类型名称堆栈

时间:2018-04-08 20:51:43

标签: c types compiler-errors linked-list header-files

我想将堆栈实现为链接列表,但每次我尝试编译main时都会说错误在"main.h" at "stack* head" ...

error: unknown type name ‘stack’
      unsigned long int inst_len, cell *d_tape, unsigned int dt_index, stack *head);

这是我的" main.h"头文件:

#include <stdlib.h>
#include <stdio.h>
#include "stack.h"

#define SUCCESS 0
#define FAIL -1
#define CELLMAX 255
#define CELLMIN 0
#define ARRJMP 10
#define DTMAXLEN 30000

typedef unsigned char cell;

int loop(cell *ins_tape, unsigned long int *inst_index,
         unsigned long int inst_len, cell *d_tape,
         unsigned int dt_index, stack *head);

它表示错误是函数循环的最后一个参数&#34; stack *head&#34;

这是文件&#34; stack.h&#34;:

#ifndef STACK_H
#define STACK_H

#include "main.h"

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);

#endif

我在loop()函数中使用这些函数,它并没有向我显示stack.h中的任何错误,但我认为这可能是因为它终止于loop()首先声明。

感谢您的帮助,对不起,如果已经在某处已经回答了。我已经看了几个问题,但他们遇到了不同的问题。

2 个答案:

答案 0 :(得分:1)

只要文件包含stack.h,#ifndef / #endif块就会禁止将stack.h中的所有内容放在main.h的内容之前。

为了完整地解释这个问题,我将逐步完成相关的预处理器步骤。下面将提供可能解决方案的摘要,但如果您有任何疑问,请务必仔细阅读整篇文章。

考虑以下测试文件。

<强> test.c的:

#include "stack.h"

int DoFoo(void)
{
    return;
}

预处理器将#include“stack.h”替换为stack.h的内容。

test.c扩展1:

#ifndef STACK_H
#define STACK_H

#include "main.h"

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);

#endif

int DoFoo(void)
{
    return;
}

接下来预处理器重新获得#ifndef STACK_H,它被评估为true,因此保留了#ifndef和#endif内的内容。

test.c扩展2:

#define STACK_H

#include "main.h"

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);


int DoFoo(void)
{
    return;
}

我现在暂时忽略#define STACK_H。下一个主要步骤是将#include "main.h"替换为main.h的内容

test.c扩展3:

#define STACK_H

#include <stdlib.h>
#include <stdio.h>
#include "stack.h"

#define SUCCESS 0
#define FAIL -1
#define CELLMAX 255
#define CELLMIN 0
#define ARRJMP 10
#define DTMAXLEN 30000

typedef unsigned char cell;

int loop(cell *ins_tape, unsigned long int *inst_index,
         unsigned long int inst_len, cell *d_tape,
         unsigned int dt_index, stack *head);

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);


int DoFoo(void)
{
    return;
}

我接下来要用stack.h的内容替换#include "stack.h",就像我们之前做的那样。

test.c扩展4:

#define STACK_H

#include <stdlib.h>
#include <stdio.h>
#ifndef STACK_H
#define STACK_H

#include "main.h"

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);

#endif

#define SUCCESS 0
#define FAIL -1
#define CELLMAX 255
#define CELLMIN 0
#define ARRJMP 10
#define DTMAXLEN 30000

typedef unsigned char cell;

int loop(cell *ins_tape, unsigned long int *inst_index,
         unsigned long int inst_len, cell *d_tape,
         unsigned int dt_index, stack *head);

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);


int DoFoo(void)
{
    return;
}

请注意#define STACK_H之前有一个#ifndef STACK_H,因此我们可以删除#ifndef /#endif块中的所有内容。

test.c扩展5:

#define STACK_H

#include <stdlib.h>
#include <stdio.h>

#define SUCCESS 0
#define FAIL -1
#define CELLMAX 255
#define CELLMIN 0
#define ARRJMP 10
#define DTMAXLEN 30000

typedef unsigned char cell;

int loop(cell *ins_tape, unsigned long int *inst_index,
         unsigned long int inst_len, cell *d_tape,
         unsigned int dt_index, stack *head);

typedef struct Stack{
    unsigned long int begin_index;
    unsigned long int end_index;
    struct Stack *prev;
} stack;

int initStack(stack *head);
int pushStack(stack *head, unsigned long int b_i, unsigned long int e_i);
int popStack(stack *head);


int DoFoo(void)
{
    return;
}

<强>要点:

在上面的文件中,问题应该是相当清楚的。 loop()的声明在定义之前使用类型堆栈。

<强>解决方案:

1)在包含stack.h之前总是包含main.h(这是一个非常糟糕的解决方案)

2)有两个头文件并不合理,当你加入其中任何一个时,两个头文件总是包含在内。考虑合并这些头文件。

3)将两个头文件中所需的内容拆分为自己的头文件。然后main.h和stack.h都将包含这个新的头文件而不是彼此。

4)将stack.h所需的所有内容移到stack.h中,并从stack.h中删除#include "main.h"

答案 1 :(得分:0)

您的问题是尝试循环收录:main.h包括stack.h,其中包含main.hmain.h没有包含保护,因此它会在stack.h之前解析,因此来自stack.h的声明尚不可见。

在您的特定情况下,main.h中不需要stack.h内的任何内容,因此您可以轻松地从#include "main.h"删除stack.h行,这样就行了。

在一般情况下,必须通过重构标题来防止这种(尝试的)循环包含,以使它们的依赖关系不包含循环(即形成DAG)。这可以通过明智地使用前向声明来完成。在您的情况下,这可能意味着向前声明struct Stackmain.h中的typedef,因此它不需要包含stack.h

#ifndef MAIN_H
#define MAIN_H

#include <stdlib.h>
#include <stdio.h>

#define SUCCESS 0
#define FAIL -1
#define CELLMAX 255
#define CELLMIN 0
#define ARRJMP 10
#define DTMAXLEN 30000


typedef struct Stack stack;

typedef unsigned char cell;

int loop(cell *ins_tape, unsigned long int *inst_index,
         unsigned long int inst_len, cell *d_tape,
         unsigned int dt_index, stack *head);

#endif