无法在 c 中传递正确的动态结构数组
Cant pass a correct Dynamic array of structs in c
我正在为学校做一个项目,但我无法将结构的动态数组传递给 c 中的另一个函数。该函数只是应该检查结构的一个元素,如果数组的该元素等于当前元素,则 return 已经添加。我在声明接受 calloc 数组的函数时也遇到了麻烦。任何帮助,将不胜感激!我整晚都在寻找解决方案。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
struct EDGETAG;
typedef struct
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
typedef struct EDGE
{
VERTEX* v;
struct EDGETAG* q;
} EDGE;
int main(int argc, char* argv[])
{
int a;
struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
char s;
int count = 0;
FILE* input = fopen(argv[1],"r");
while((a = fgetc(input)) != EOF)
{
if(isspace(a)==0)
{
s = a;
printf("%c ",s);
determiner(s,vert,count);
count++;
}
}
return 0;
}
和调用函数
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
typedef struct VERTEX
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
typedef struct EDGETAG
{
VERTEX* v;
struct EDGETAG* q;
} EDGE;
void determiner (char a, struct VERTEX *vert, int count)
{
int i;
for(i=0;i < count; i++)
{
if(vert[i].c == a)
{
printf("%c allready added ",vert[i].c);
return ;
}
else
{
VERTEX* new1 = (VERTEX*)malloc(sizeof(VERTEX));
new1->c = a;
vert[i] = *new1;
}
}
return ;
输入是:
甲乙
BC
前任
CD
交流电
output:A B B B 已添加 C E X C D A C
您实际上从未分配任何顶点。
struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
注意到 sizeof(VERTEX*)
了吗?您已经为 100 个指向顶点的指针分配了足够的 space!
除了 David Schwartz 指出的问题,determiner
的缩进版本更清楚地显示了另一个问题:
void determiner(char a, struct VERTEX *vert, int count)
{
int i;
for (i = 0; i < count; i++)
{
if (vert[i].c == a)
{
printf("%c allready added ", vert[i].c);
return;
}
else{
VERTEX* new1 = (VERTEX*)malloc(sizeof(VERTEX));
new1->c = a;
vert[i] = *new1;
}
}
return;
}
您当前的代码查看数组的第一个元素,看它是否与 a
匹配
- 如果匹配,则 returns(好)
- 如果不匹配,它将用新数据覆盖第一个元素(错误)
然后它循环并对第二个元素等做同样的事情
要解决此问题,请将添加新元素的代码移到检查循环之外。如果检查循环结束,那么它还没有找到,所以可以添加。
现在,您有第二个问题 - 无论 determiner
是否找到匹配,您总是增加 count
。您应该将 determiner
更改为 return 一个指示是否添加了项目的值,然后在 main
中使用该值来增加计数。
编辑:另请注意 - 如果您只是将其内容复制到 vert[i]
,则不需要(或不想)使用 malloc 分配新节点。目前您正在泄漏内存 - 直接更新 vert[i].c
更容易。
您正在调用第一个文件
typedef struct
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
稍后下来,你有
struct VERTEX *vert = ...
struct VERTEX
不是第一个文件中的类型。 VERTEX
被定义为一种类型。您应该将结构类型更改为
typedef struct VERTEX // note the VERTEX here
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
这已经在第二个文件中完成了。
作为一般风格指南,您应该在单独的头文件中包含 VERTEX
和 EDGE
的结构声明,并将其包含在两个 .c
文件中。
你的代码有很多问题,但我会在上面的答案中加上我的 2 美分,因为我相信它可能会有帮助:
正如@David 已经注意到的,您正在实例化一个指针数组:
// this should be a struct VERTEX**, if you want to
// have a "pointer to the first pointer to VERTEX"
struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
但您(很可能)想要实例化一个 VERTEX 数组:
// you probably want space for 100 x sizeof(VERTEX),
// so that vert is simply a "pointer to the first VERTEX".
// ALSO: don't cast the result of calloc/malloc
struct VERTEX *vert = calloc(100, sizeof(VERTEX));
vert
不是指向分配数组的第一个 VERTEX
元素的指针。您不需要分配单个 VERTEX
元素,并且 vert
永远不会在您迭代时成为 null
,因此您需要自己跟踪 count
。
count
不应在 main
正文中递增,因为您不知道是否实际添加了该元素。
你的determiner
函数不正确;您似乎在 each 循环迭代中添加了一个新实例。我还会 return 函数实际添加元素时的计数值:
void determiner (char a, struct VERTEX *vert, int *count)
{
for(int i = 0; i < count; i++)
{
if (vert[i].c == a)
{
printf("%c already added ",vert[i].c);
// no need to increase count
return;
}
}
// if we are here, we didn't find the element,
// so this is where you actually initialize it
// and increase count
vert[count]->c = a;
count++;
}
调用函数时,将指针传给count
,让函数自增:
determiner(s, vert, &count);
在处理图形时,通常使用链表,即让节点指向其他节点。在这种情况下,您不分配数组,而是分别为每个节点使用 malloc
并向前跳转,直到到达 null
。尝试在谷歌上搜索如何在 C 中实现图形的示例,以便更好地了解正确的方法。
我正在为学校做一个项目,但我无法将结构的动态数组传递给 c 中的另一个函数。该函数只是应该检查结构的一个元素,如果数组的该元素等于当前元素,则 return 已经添加。我在声明接受 calloc 数组的函数时也遇到了麻烦。任何帮助,将不胜感激!我整晚都在寻找解决方案。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
struct EDGETAG;
typedef struct
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
typedef struct EDGE
{
VERTEX* v;
struct EDGETAG* q;
} EDGE;
int main(int argc, char* argv[])
{
int a;
struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
char s;
int count = 0;
FILE* input = fopen(argv[1],"r");
while((a = fgetc(input)) != EOF)
{
if(isspace(a)==0)
{
s = a;
printf("%c ",s);
determiner(s,vert,count);
count++;
}
}
return 0;
}
和调用函数
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
typedef struct VERTEX
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
typedef struct EDGETAG
{
VERTEX* v;
struct EDGETAG* q;
} EDGE;
void determiner (char a, struct VERTEX *vert, int count)
{
int i;
for(i=0;i < count; i++)
{
if(vert[i].c == a)
{
printf("%c allready added ",vert[i].c);
return ;
}
else
{
VERTEX* new1 = (VERTEX*)malloc(sizeof(VERTEX));
new1->c = a;
vert[i] = *new1;
}
}
return ;
输入是: 甲乙 BC 前任 CD 交流电 output:A B B B 已添加 C E X C D A C
您实际上从未分配任何顶点。
struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
注意到 sizeof(VERTEX*)
了吗?您已经为 100 个指向顶点的指针分配了足够的 space!
除了 David Schwartz 指出的问题,determiner
的缩进版本更清楚地显示了另一个问题:
void determiner(char a, struct VERTEX *vert, int count)
{
int i;
for (i = 0; i < count; i++)
{
if (vert[i].c == a)
{
printf("%c allready added ", vert[i].c);
return;
}
else{
VERTEX* new1 = (VERTEX*)malloc(sizeof(VERTEX));
new1->c = a;
vert[i] = *new1;
}
}
return;
}
您当前的代码查看数组的第一个元素,看它是否与 a
- 如果匹配,则 returns(好)
- 如果不匹配,它将用新数据覆盖第一个元素(错误)
然后它循环并对第二个元素等做同样的事情
要解决此问题,请将添加新元素的代码移到检查循环之外。如果检查循环结束,那么它还没有找到,所以可以添加。
现在,您有第二个问题 - 无论 determiner
是否找到匹配,您总是增加 count
。您应该将 determiner
更改为 return 一个指示是否添加了项目的值,然后在 main
中使用该值来增加计数。
编辑:另请注意 - 如果您只是将其内容复制到 vert[i]
,则不需要(或不想)使用 malloc 分配新节点。目前您正在泄漏内存 - 直接更新 vert[i].c
更容易。
您正在调用第一个文件
typedef struct
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
稍后下来,你有
struct VERTEX *vert = ...
struct VERTEX
不是第一个文件中的类型。 VERTEX
被定义为一种类型。您应该将结构类型更改为
typedef struct VERTEX // note the VERTEX here
{
char c;
bool isVisited;
struct EDGETAG* p;
} VERTEX;
这已经在第二个文件中完成了。
作为一般风格指南,您应该在单独的头文件中包含 VERTEX
和 EDGE
的结构声明,并将其包含在两个 .c
文件中。
你的代码有很多问题,但我会在上面的答案中加上我的 2 美分,因为我相信它可能会有帮助:
正如@David 已经注意到的,您正在实例化一个指针数组:
// this should be a struct VERTEX**, if you want to // have a "pointer to the first pointer to VERTEX" struct VERTEX *vert = (VERTEX*)calloc(100, sizeof (VERTEX*));
但您(很可能)想要实例化一个 VERTEX 数组:
// you probably want space for 100 x sizeof(VERTEX), // so that vert is simply a "pointer to the first VERTEX". // ALSO: don't cast the result of calloc/malloc struct VERTEX *vert = calloc(100, sizeof(VERTEX));
vert
不是指向分配数组的第一个VERTEX
元素的指针。您不需要分配单个VERTEX
元素,并且vert
永远不会在您迭代时成为null
,因此您需要自己跟踪count
。count
不应在main
正文中递增,因为您不知道是否实际添加了该元素。你的
determiner
函数不正确;您似乎在 each 循环迭代中添加了一个新实例。我还会 return 函数实际添加元素时的计数值:void determiner (char a, struct VERTEX *vert, int *count) { for(int i = 0; i < count; i++) { if (vert[i].c == a) { printf("%c already added ",vert[i].c); // no need to increase count return; } } // if we are here, we didn't find the element, // so this is where you actually initialize it // and increase count vert[count]->c = a; count++; }
调用函数时,将指针传给
count
,让函数自增:determiner(s, vert, &count);
在处理图形时,通常使用链表,即让节点指向其他节点。在这种情况下,您不分配数组,而是分别为每个节点使用
malloc
并向前跳转,直到到达null
。尝试在谷歌上搜索如何在 C 中实现图形的示例,以便更好地了解正确的方法。