简体   繁体   English

如何将结构数组作为 C 中的指针传递给函数?

[英]How do I pass a array of structures to a function as a pointer in C?

I have done the following program, to input a graph and color it in at most 6 colors (given degree at most 5 etc.)我已经完成了以下程序,输入一个图形并将其着色为最多 6 种颜色(给定度数最多为 5 等)

Most of the code is self explanatory, with comments to explain what each line does.大部分代码都是不言自明的,用注释来解释每一行的作用。

I have included my code below and the errors that are raised, but I'm especially curious whats causing the warning saying the parameter I've input isn't of expected type.我在下面包含了我的代码和引发的错误,但我特别好奇是什么导致警告说我输入的参数不是预期的类型。 This has become sort of a recurring error for me, and I'd love some feedback!这对我来说已经成为一种反复出现的错误,我希望得到一些反馈!

Any suggestions on the code itself would be appreciated too, but my main issue at the moment is related to the passing of parameters对代码本身的任何建议也将不胜感激,但我目前的主要问题与参数的传递有关

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;
}

The errors i'm getting are:我得到的错误是:

<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)
      |   

My program eventually terminates through Segmentation fault after the inputs.我的程序最终在输入后通过分段错误终止。 What am I doing wrong in passing the array of structures as reference?将结构数组作为参考传递时我做错了什么?

Your current implementation expects a NODE pointer array (eg an array of NODE* ).您当前的实现需要一个NODE指针数组(例如一个NODE*数组)。 In reality, your passing it &Tree from main() , which is not NODE pointer array, its the address of a hard array.实际上,您从main()传递它&Tree ,它不是NODE指针数组,它是硬数组的地址。 Worse (if there is such a thing), in ColorTree you're pouring more salt on the wound by recursing with &Tree , in that context, &Tree is actually NODE ***更糟糕的是(如果有这样的事情),在ColorTree您通过使用&Tree递归在伤口上撒了更多盐,在这种情况下, &Tree实际上是NODE ***

None of this needs to be done this way.这一切都不需要以这种方式完成。 Simply passing Tree in both calling scenarios and changing the formal argument to NODE *Tree (or NODE Tree[] ), and fixing all the code therein will work.只需在调用场景中传递Tree并将形式参数更改为NODE *Tree (或NODE Tree[] ),然后修复其中的所有代码即可。 An example is below (that utilizes dynamic allocations because my C compiler is dumber than bag of hammers and doesn't understand VLAs):下面是一个示例(使用动态分配,因为我的 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;
}

Whether this solves every issue you code faces beyond the stated question isn't guaranteed (for all I know it could be chock full of logic errors), but it will fix the problem(s) mentioned.不能保证这是否能解决您编写的代码所面临的所有问题,超出了所述问题(据我所知,它可能充满了逻辑错误),但它会解决提到的问题。 I did, however, take liberty to fix the blatant overreach of the for-loop in ColorTree.然而,我确实冒昧地修复了 ColorTree 中 for 循环的明显过度使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM