我想将堆栈实现为链接列表,但每次我尝试编译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()
首先声明。
感谢您的帮助,对不起,如果已经在某处已经回答了。我已经看了几个问题,但他们遇到了不同的问题。
答案 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.h
。 main.h
没有包含保护,因此它会在stack.h
之前解析,因此来自stack.h
的声明尚不可见。
在您的特定情况下,main.h
中不需要stack.h
内的任何内容,因此您可以轻松地从#include "main.h"
删除stack.h
行,这样就行了。
在一般情况下,必须通过重构标题来防止这种(尝试的)循环包含,以使它们的依赖关系不包含循环(即形成DAG)。这可以通过明智地使用前向声明来完成。在您的情况下,这可能意味着向前声明struct Stack
和main.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