我正在研究一个有多个结构的数据库。我已经定义了一个从csv文件加载数据并将每一行存储为结构的函数。我使用双指针存储它们,因此一个指针指向每个结构变量的多个指针。该函数确实正确返回双指针,但是我收到一个警告:从不兼容的指针类型返回。
我的代码如下:
struct part** loadParts(char* fileName, int m)
{
typedef struct part
{
int id;
int cost;
} Part;
FILE* fptr = fopen(fileName, "r");
//creat pointer to array of pointers to part structs
Part** parts;
parts = malloc((nParts) * sizeof(Part *));
//length of one line
char line[1000];
//while new items can be added
int i;
i=0;
while (fgets(line, sizeof(line), fptr)!= NULL)
{
parts[i] = malloc(sizeof(Part));
//get id
int id = atoi(strtok(line, ";"));
parts[i]->id = id;
// get cost
int id = atoi(strtok(line, ";"));
parts[i]->cost = cost;
i++;
}
fclose(fptr);
return parts;
}
有人知道为什么会出现此警告吗?非常感谢提前!
答案 0 :(得分:0)
你有大纲:
struct part** loadParts(char* fileName, int m)
{
typedef struct part
{
int id;
int cost;
} Part;
…
Part** parts;
…
parts = …
…
return parts;
}
没有警告就无法编译。根据定义,函数签名中使用的struct part
与函数内定义的struct part
完全无关。因此,您将返回指向函数中某种类型的指针,该函数期望返回指向其他类型的指针,即使这些类型可能拼写为struct part
。甚至没有办法让你的代码摆脱困境。
如注释中所示,结构定义必须在函数定义之前(可能在任何声明之前 - 并且通常在使用结构的任何地方使用的头文件中)都在函数之外。
因此,解决代码的一种方法是:
typedef struct part
{
int id;
int cost;
} Part;
struct part **loadParts(char *fileName, int m)
{
…
Part **parts;
…
parts = …
…
return parts;
}
在这种情况下,您可以让函数返回Part **
。
但是,除非您有一个包含结构定义的标头,否则现在应将该函数定义为static
。如果没有标题,则无法(可靠地)访问其他源文件中的结构类型。 (可以通过两次编写代码来完成,但是编写代码两次应该是令人厌恶的 - 在你完成输入或复制'n'pasting,第二个副本之前,它将成为维护责任。)
您可能正在处理不透明类型;此文件外部的代码不需要知道结构细节。那是合法的;它甚至可以(非常)有益。不过,你只需要一种不同的写作方式:
部首:
typedef struct part Part;
extern struct part **loadParts(char *fileName, int m);
如果您决定不公开名称Part
,则可以改为使用此标题:
struct part;
extern struct part **loadParts(char *fileName, int m);
第一行显示“有struct part
类型,但如果您需要,将在稍后提供详细信息”。第二个声明函数返回指向struct part
值的指针。 extern
是可选的;我用它 - 很多人没有。在此代码中,第一行是可选的。但是,如果您将extern int num_parts(struct part **list);
作为函数,则需要在loadParts()
声明后显示,或者您需要struct part;
行以确保原型中的类型不是新。
来源:
struct part
{
int id;
int cost;
};
struct part **loadParts(char *fileName, int m)
{
…
Part **parts;
…
parts = …
…
return parts;
}
您需要担心标题中的标题保护以确保幂等性。 (在这个例子中,没有自包含的问题,但是你也应该确保你的标题是自包含的 - 如果你搜索的话,SO上有多个问题可以解释这些术语。)