【发布时间】:2015-08-20 13:07:25
【问题描述】:
我正在尝试对图形使用称为“拓扑排序”的算法。
为了使用它,我创建了两种数据结构:图形和堆栈。两者是分开写的。
我正在尝试在文件 graph.c 中使用堆栈数据结构(以及您的操作,如 push 和 pop)。为此,我写了:
#include "stack.h"
graph.c 内部,当我编译它时,没有错误。
好吧,当我在 graph.c 中创建堆栈 s1 时没有编译错误(参见下面的代码):
Stack *s1 = init(); //Creates a stack s1
当我尝试使用堆栈的另一个操作(如 push 和 pop)时,就会出现问题。例如,如果我写:
push(3,s1);
并尝试编译,出现如下错误:
graph.c: In function `DIGRAPHdfs':
graph.c:71: parse error before `int'
graph.c:73: `v' undeclared (first use in this function)
graph.c:73: (Each undeclared identifier is reported only once
graph.c:73: for each function it appears in.)
当我尝试使用 pop 功能时出现同样的错误。
为什么我得到这个错误编译?
源文件
graph.c
(请查看此代码中的函数Digraphdfs,出现错误)
#include<stdio.h>
#include<stdlib.h>
#include "graph.h"
#include "stack.h"
#define maxV 10000
static int count, pre[maxV],lbl[maxV];
struct digraph {
int V;
int A;
int **adj;
};
//Cria a matriz de adjacências (utilizando a técnica de vetor de ponteiros)
int **MATRIXint( int r, int c, int val) {
Vertex i,j;
int **m = malloc(r*sizeof(int*));
for (i = 0; i < r; i++)
m[i] = malloc(c*sizeof(int));
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
m[i][j] = val;
return m;
}
//Cria o digrafo com V vertices e V arcos
Digraph DIGRAPHinit(int V){
Digraph G = malloc(sizeof *G);
G->V = V;
G->A = 0;
G->adj = MATRIXint(V,V,0);
return G;
}
//Insere o arco entre v e w
void DIGRAPHinsertA( Digraph G, Vertex v, Vertex w) {
if (G->adj[v][w] == 0)
{
G->adj[v][w] = 1;
G->A++;
}
}
//Remove o arco entre v e w
void DIGRAPHremoveA( Digraph G, Vertex v, Vertex w){
if (G->adj[v][w] == 1){
G->adj[v][w] = 0;
G->A--;
}
}
void DIGRAPHshow(Digraph G){
Vertex v,w;
for (v = 0; v < G->V; v++){
printf("%2d:", v);
for (w = 0; w < G->V; w++)
if (G->adj[v][w] == 1)
printf(" %2d", w);
printf("\n");
}
}
void DIGRAPHdfs( Digraph G) {
Stack *s1 = init(); //There's no error when I create a stack
push(3,s1); //I get a compilation error when I try to use the push function (The same for "pop").
Vertex v;
count = 0;
for (v = 0; v < G->V; v++)
pre[v] = -1;
for (v = 0; v < G->V; v++)
if(pre[v] == -1)
dfsR(G,v);
for (v = 0; v< G->V;v++)
printf("%d ",pre[v]);
printf("\n");
}
void dfsR(Digraph G, Vertex v) {
Vertex w;
pre[v] = count++;
for(w = 0; w < G->V; w++)
if(G->adj[v][w] != 0 && pre[w] == -1)
dfsR(G,w);
}
int DIGRAPHreach( Digraph G, Vertex s, Vertex t) {
Vertex w;
for (w = 0; w< G->V; w++)
lbl[w] = 0;
reachR(G,s);
if (lbl[t] == 0) return 0;
else return 1;
}
void reachR (Digraph G, Vertex v) {
Vertex w;
lbl[v] = 1;
for (w = 0; w < G->V; w++)
if(G->adj[v][w] == 1 && lbl[w] == 0)
reachR(G,w);
}
graph.h
#define Vertex int
typedef struct digraph *Digraph;
Digraph DIGRAPHinit(int V);
int **MATRIXint(int r, int c, int val);
void DIGRAPHinsertA(Digraph G, Vertex v, Vertex w);
void DIGRAPHremoveA(Digraph G, Vertex v, Vertex w);
void DIGRAPHshow(Digraph G);
void DIGRAPHdfs( Digraph G);
void dfsR(Digraph G, Vertex v);
void reachR (Digraph G, Vertex v);
int DIGRAPHreach( Digraph G, Vertex s, Vertex t);
stack.c
#include<stdio.h>
#include<stdlib.h>
#include "stack.h"
#define N 5
struct stack {
int n; //The quantity of elements of the stack
int vector[5]; //The stacks as a vector.
};
//Initialization of the stack
Stack* init(){
Stack *s;
s = (Stack*)malloc(sizeof(Stack));
if (s == NULL){
printf("FATAL ERROR!\n");
exit(1);
}
s->n = 0;
return s;
}
//Push Operation
void push(int q,Stack*s){
//Checks stack overflow
if (s->n == N){
printf("Stack Overflow!\n");
exit(1);
}
s->vector[s->n] = q;
s->n++;
}
int pop(Stack*s){
int v;
if (s->n == 0){
printf("There's no element in the stack!\n");
exit(2);
}
s->n--;
v = s->vector[s->n];
return v;
}
void print_stack(Stack*s){
int i;
for(i = 0; i<s->n; i++){
printf("vector[%d] = %d \n",i, s->vector[i]);
}
}
stack.h
typedef struct stack Stack;
Stack* init();
void push(int q,Stack*s);
void print_stack(Stack*s);
int pop(Stack*s);
【问题讨论】:
-
您使用的是古老的 C90 编译器吗?如果是这样,那就是问题的原因。
-
其他与具体问题无关的问题: - 您应该使用真实的变量名称而不是神秘的单字母名称。 - 您应该分配真正的二维数组,而不是在整个堆中分段的碎片查找表。 - 您的头文件缺少标头保护(也可能与问题有关)。 - 永远不要将指针隐藏在 typedef 后面,即使它们是指向不完整类型的指针。 - 查找“const 正确性”并为所有函数参数实现它。 - 如果您使用的是古老的 C90 编译器,则强制转换 malloc 的值是没有意义的并且可能很危险。
-
@Lundin C90 并不是那么古老。例如,微软直到 2013 年才开始支持 C99,即使在今天,他们的支持也远未完成。
-
@FUZxxl 看看过去 25 年中与计算机相关的事物是如何发展的,从 1990 年开始的事物是非常古老的。在 1990 年还是个孩子的时候,我接触到了我的第一台计算机,一台 DOS 4.0 的 286。这听起来像你今天想使用的东西吗?微软所做的和没有做的都是一个非常糟糕的论据来证明任何事情......如果他们比其他人落后 14 年并且太无能而无法做出符合标准的 C 实现,那对他们来说太糟糕了,我为什么要关心?跨度>
-
感谢@Lundin 的提示
标签: c data-structures graph stack