c - 如何将结构数组作为 C 中的指针传递给函数?
问题描述
我已经完成了以下程序,输入一个图形并将其着色为最多 6 种颜色(给定度数最多 5 等)
大多数代码是不言自明的,并带有注释来解释每一行的作用。
我在下面包含了我的代码和引发的错误,但我特别好奇是什么导致了警告说我输入的参数不是预期的类型。这对我来说已经成为一种反复出现的错误,我希望得到一些反馈!
对代码本身的任何建议也将不胜感激,但我目前的主要问题与参数的传递有关
struct NODE{
int node_no;
char color;
};
char Colors[6]={'a','b','c','d','e','f'};
// l->left index, right index is fixed at n-1, as we colors from 0 to n-1
void ColorTree(struct NODE *Tree[], int l, int n, int Edges [][2], int e)
{
if(n==1) // if only one node, color node with lowest color
{
Tree[0]->color='a';
}
int i,j; char used_colors[6], c='N';
for(i=0;i<=e;i++) // colors
{
if(Edges[i][0] == Tree[l]->node_no)
{
c=Tree[Edges[i][1]]->color;
continue;
}
if(Edges[i][1] == Tree[l]->node_no)
{
c=Tree[Edges[i][0]]->color;
}
for(j=0;used_colors[j]!='\0';j++); // finds empty position of used_colors
if(c!='N')
used_colors[j]=c; // if the color is not N, add to already used colors
}
for(i=0;Colors[i]!='\0';i++)
for(j=0;used_colors[j]!='\0';j++)
{
if(Colors[i]==used_colors[j]) // the color is already used
continue;
else if(used_colors[j+1]=='\0') // the color is not used
break;
}
Tree[l]->color=Colors[i]; // the unused color being assigned to Tree[l]
if(l==(n-1)) // all nodes have been colored
return;
ColorTree(&Tree,l+1,(n-1),Edges, e);
}
int main()
{
int n,e,i;
scanf("%d", &n);
struct NODE Tree[n]; // n-> no. of vertices
for(i=0;i<n;i++) // initialising the tree, with node 0,1,2...n-1 and color = 'N'
{
Tree[i].node_no=i;
Tree[i].color='N'; // 'N'->no color
}
scanf("%d", &e); // e-> no.of edges
int Edges[e][2];
for(i=0;i<e;i++) // entering the edges
{
scanf("%d", &Edges[i][0]);
scanf("%d", &Edges[i][1]);
}
ColorTree(&Tree,0,(n-1),Edges,e);
printf("%c", Tree[0].color); // printing the colors in the graph
for(i=1;i<n;i++)
printf("\n%c", Tree[i].color);
return 0;
}
我得到的错误是:
<file_name>.c:51:15: warning: passing argument 1 of ‘ColorTree’ from incompatible pointer type [-Wincompatible-pointer-types]
51 | ColorTree(&Tree,l+1,(n-1),Edges, e);
| ^~~~~
| |
| struct NODE ***
<file_name>.c:11:29: note: expected ‘struct NODE **’ but argument is of type ‘struct NODE ***’
11 | void ColorTree(struct NODE *Tree[], int l, int n, int Edges [][2], int e)
| ~~~~~~~~~~~~~^~~~~~
<file_name>.c: In function ‘main’:
<file_name>.c:77:15: warning: passing argument 1 of ‘ColorTree’ from incompatible pointer type [-Wincompatible-pointer-types]
77 | ColorTree(&Tree,0,(n-1),Edges,e);
| ^~~~~
| |
| struct NODE (*)[(sizetype)(n)]
<file_name>.c:11:29: note: expected ‘struct NODE **’ but argument is of type ‘struct NODE (*)[(sizetype)(n)]’
11 | void ColorTree(struct NODE *Tree[], int l, int n, int Edges [][2], int e)
|
我的程序最终在输入后通过分段错误终止。在传递结构数组作为参考时我做错了什么?
解决方案
您当前的实现需要一个NODE
指针数组(例如 的数组NODE*
)。实际上,您从不是指针数组的 中传递它&Tree
,它main()
是硬数组的地址。更糟糕的是(如果有这样的事情),你通过递归在伤口上倒更多的盐,在这种情况下,实际上是 NODE
ColorTree
&Tree
&Tree
NODE ***
这些都不需要以这种方式完成。只需传入Tree
两个调用场景并将形式参数更改为NODE *Tree
(或NODE Tree[]
),并修复其中的所有代码即可。下面是一个示例(使用动态分配,因为我的 C 编译器比锤子包更笨并且不理解 VLA):
#include <stdio.h>
#include <stdlib.h>
struct NODE {
int node_no;
char color;
};
char Colors[6] = { 'a','b','c','d','e','f' };
// l->left index, right index is fixed at n-1, as we colors from 0 to n-1
void ColorTree(struct NODE Tree[], int l, int n, int Edges[][2], int e)
{
if (n == 1) // if only one node, color node with lowest color
{
Tree[0].color = 'a';
}
int i, j; char used_colors[6], c = 'N';
for (i = 0; i < e; i++) // colors
{
if (Edges[i][0] == Tree[l].node_no)
{
c = Tree[Edges[i][1]].color;
continue;
}
if (Edges[i][1] == Tree[l].node_no)
{
c = Tree[Edges[i][0]].color;
}
for (j = 0; used_colors[j] != '\0'; j++); // finds empty position of used_colors
if (c != 'N')
used_colors[j] = c; // if the color is not N, add to already used colors
}
for (i = 0; Colors[i] != '\0'; i++)
for (j = 0; used_colors[j] != '\0'; j++)
{
if (Colors[i] == used_colors[j]) // the color is already used
continue;
else if (used_colors[j + 1] == '\0') // the color is not used
break;
}
Tree[l].color = Colors[i]; // the unused color being assigned to Tree[l]
if (l == (n - 1)) // all nodes have been colored
return;
ColorTree(Tree, l + 1, (n - 1), Edges, e);
}
int main()
{
int n, e, i;
scanf("%d", &n);
struct NODE *Tree = malloc(n * sizeof *Tree);
for (i = 0; i<n; i++) // initialising the tree, with node 0,1,2...n-1 and color = 'N'
{
Tree[i].node_no = i;
Tree[i].color = 'N'; // 'N'->no color
}
scanf("%d", &e); // e-> no.of edges
int(*Edges)[2] = malloc(e * sizeof *Edges);
for (i = 0; i<e; i++) // entering the edges
{
scanf("%d", &Edges[i][0]);
scanf("%d", &Edges[i][1]);
}
ColorTree(Tree, 0, (n - 1), Edges, e);
printf("%c", Tree[0].color); // printing the colors in the graph
for (i = 1; i<n; i++)
printf("\n%c", Tree[i].color);
return 0;
}
不能保证这是否解决了您编码所面临的超出所述问题的所有问题(据我所知,它可能充满了逻辑错误),但它会解决所提到的问题。然而,我确实冒昧地修复了 ColorTree 中 for 循环的公然越界。
推荐阅读
- python - Python3 - 运行单元测试时输出 __main__ 文件(来自实际程序,而不是单元测试)
- java - 将加密/解密密钥存储到静态变量中是否安全?
- javascript - 是否可以使用 JavaScript 将行号打印到控制台或 NetSuite 上的执行日志?
- xamarin - 如何使用共享 VM 将属性值从一个选项卡屏幕共享到另一个选项卡屏幕?
- c# - EF6 - 为什么我的所有 DbSet 在枚举它们时都会抛出 InvalidOperationException?
- mongodb - 如何在mongodb的一次执行中更新具有不同值的多行?
- amazon-web-services - 使用 AWS Glue 作业将缺失的列值设置为默认值
- dynamics-crm - 无法从 UCI 的子网格中隐藏查看所有记录按钮
- java - 读取pdf文件中的文本并拆分为多个pdf文件
- shell - 将多个文件合并为一个没有标题