测试和学习 C 中的图形时出现意外错误
Unexpected error in testing and learning about graphs in C
我最近开始研究这本关于算法和数据结构的书SkienaTheAlgorithmDesignManual.pdf,不仅在互联网上,而且我的算法设计老师以及大学,最后我在第 153 页(在书本身)或 165(pdf 格式)上使用了一些代码时遇到了一些错误。
代码如下:
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MAXV 1000
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = NULL;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
main() {
bool directed = true;
graph *g;
read_graph(g, directed);
print_graph(g);
system("pause");
}
错误如下:
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(47): warning C4047: '=': 'int' differs in levels of indirection from 'void *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(49): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(65): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *'
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(73): error C4700: uninitialized local variable 'g' used
1>Done building project "LearningGraph.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我认为主要问题是"incompatible types",但我也可能是错的。
在insert_edge
p->weight = NULL;
无效,因为 weight 是一个 int 而 NULL 是一个指针(通常是 (void*)0
)
在insert_edge
p->next = g->edges[x];
无效,因为 next 是未定义的类型 struct edgenode *
但 edges[x]
是 edgenode *
。要解决这个问题,您必须更换
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
来自
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
print_graph
行也是一样的道理
p = p->next;
显式设置 main 的 return 类型为 int
在 main 中你用 g 调用 read_graph
永远不会 set/initialized 所以当它在 read_graph
行为未定义,print_graph
中也是如此。只需更换
graph *g;
read_graph(g, directed);
print_graph(g);
来自
graph g;
read_graph(&g, directed);
print_graph(&g);
完整修改版:
#include <stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#define MAXV 1000
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = 0;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}
编译:
pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra g.c
pi@raspberrypi:/tmp $
您从未为 graph *g
分配任何内存。
没必要把它当成一个指针,让它成为一个普通的变量,然后把它的地址传递给函数。
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}
我最近开始研究这本关于算法和数据结构的书SkienaTheAlgorithmDesignManual.pdf,不仅在互联网上,而且我的算法设计老师以及大学,最后我在第 153 页(在书本身)或 165(pdf 格式)上使用了一些代码时遇到了一些错误。
代码如下:
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#define MAXV 1000
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = NULL;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
main() {
bool directed = true;
graph *g;
read_graph(g, directed);
print_graph(g);
system("pause");
}
错误如下:
1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(47): warning C4047: '=': 'int' differs in levels of indirection from 'void *' 1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(49): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *' 1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(65): warning C4133: '=': incompatible types - from 'edgenode *' to 'edgenode *' 1>c:\users\dragos\source\repos\learninggraph\learninggraph\main.c(73): error C4700: uninitialized local variable 'g' used 1>Done building project "LearningGraph.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我认为主要问题是"incompatible types",但我也可能是错的。
在insert_edge
p->weight = NULL;
无效,因为 weight 是一个 int 而 NULL 是一个指针(通常是 (void*)0
)
在insert_edge
p->next = g->edges[x];
无效,因为 next 是未定义的类型 struct edgenode *
但 edges[x]
是 edgenode *
。要解决这个问题,您必须更换
typedef struct {
int y;
int weight;
struct edgenode *next;
}edgenode;
来自
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
print_graph
行也是一样的道理
p = p->next;
显式设置 main 的 return 类型为 int
在 main 中你用 g 调用 read_graph
永远不会 set/initialized 所以当它在 read_graph
行为未定义,print_graph
中也是如此。只需更换
graph *g; read_graph(g, directed); print_graph(g);
来自
graph g;
read_graph(&g, directed);
print_graph(&g);
完整修改版:
#include <stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#define MAXV 1000
typedef struct edgenode {
int y;
int weight;
struct edgenode *next;
}edgenode;
typedef struct {
edgenode *edges[MAXV + 1];
int degree[MAXV + 1];
int nvertices;
int nedges;
bool directed;
}graph;
void initialize_graph(graph *g, bool directed);
void read_graph(graph *g, bool directed);
void insert_edge(graph *g, int x, int y, bool directed);
void print_graph(graph *g);
void initialize_graph(graph *g, bool directed) {
int i;
g->nvertices = 0;
g->nedges = 0;
g->directed = directed;
for (i = 1; i <= MAXV; i++) {
g->degree[i] = 0;
g->edges[i] = NULL;
}
}
void read_graph(graph *g, bool directed) {
int i;
int m;
int x, y;
initialize_graph(g, directed);
scanf("%d %d", &(g->nvertices), &m);
for (i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
insert_edge(g, x, y, directed);
}
}
void insert_edge(graph *g, int x, int y, bool directed) {
edgenode *p;
p = malloc(sizeof(edgenode));
p->weight = 0;
p->y = y;
p->next = g->edges[x];
g->edges[x] = p;
g->degree[x]++;
if (directed == false)
insert_edge(g, y, x, true);
else
g->nedges++;
}
void print_graph(graph *g) {
int i;
edgenode *p;
for (i = 1; i <= g->nvertices; i++) {
printf("%d ", i);
p = g->edges[i];
while (p != NULL) {
printf(" %d", p->y);
p = p->next;
}
printf("\n");
}
}
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}
编译:
pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra g.c
pi@raspberrypi:/tmp $
您从未为 graph *g
分配任何内存。
没必要把它当成一个指针,让它成为一个普通的变量,然后把它的地址传递给函数。
int main() {
bool directed = true;
graph g;
read_graph(&g, directed);
print_graph(&g);
system("pause");
}