首页 > 解决方案 > 如何将结构数组作为 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)
      |   

我的程序最终在输入后通过分段错误终止。在传递结构数组作为参考时我做错了什么?

标签: cpointersstructgraph

解决方案


您当前的实现需要一个NODE指针数组(例如 的数组NODE*)。实际上,您从不是指针数组的 中传递它&Treemain()是硬数组的地址。更糟糕的是(如果有这样的事情),你通过递归在伤口上倒更多的盐,在这种情况下,实际上是 NODEColorTree&Tree&TreeNODE ***

这些都不需要以这种方式完成。只需传入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 循环的公然越界。


推荐阅读