4

我注意到在使用 fopen 和 fgets 时,我在代码中使用了char*变量而不是FILE*变量,但是我的代码可以工作。我想知道这是为什么?我的一段代码如下。

...
char* filePath = ac->filepath;
char* line = malloc(sizeof(char) * MAX_CHAR_PER_LINE) ;
filePath = fopen(filePath, "r"); // we are assigning the result to a char*, not FILE*
if (filePath == NULL) {
    printf ("\n[%s:%d] - error opening file '%s'", __FILE__, __LINE__, filePath);
    printf ("\n\n");
    exit (1);
}

while ((fgets(line, MAX_CHAR_PER_LINE, filePath) != NULL)) {
...
4

2 回答 2

3

achar*和 a都FILE*只是存储一个内存地址。C 具有相当弱的类型(编辑:这是我的一个误解,请参阅下面的评论),因此它可以让您分配指针而不必担心它们指向的类型。

fopen返回FILE对象的地址,然后将该地址存储在某处(在您的情况下,它位于 a 中char*)。当您使用其中的地址时,fgets它仍然具有FILE对象的地址,因此一切都会按预期工作。

于 2013-08-09T19:00:56.257 回答
1

您的编译器非常宽松。它应该抱怨 FILE* 到 char* 的转换无效。

无论如何,假设编译器接受这种隐式转换,答案很简单。按照 C 标准,char* 和 void* 指针可以无损地保存任何指针值。因此,您可以将 SOMETYPE*​​ 转换为 char*,然后再从 char* 转换回 SOMETYPE*​​,您将获得与最初相同的指针。实际上,在大多数系统上,所有指针都是等价的,您可以自由地从一个指针转换到另一个指针。

FILE* 是一个小而不透明的指针类型值。可能是指向内部数据结构的实际指针,但这可能以不同的方式实现(例如,它可能是将 UNIX 文件描述符转换为指针)。STDIO 函数只是希望您在 fread/fwrite/fclose 中使用从 fopen 获得的相同的不透明 FILE* 值。

分配给 filePath 时,FILE* 将转换为 char*。char* 被转换为 FILE* 作为 fgets 的第一个参数(同样,您的编译器应该抱怨),因此返回到它的初始值。

建议:在编译器中使用更高级别的错误/警告并修复代码。

于 2013-08-09T19:03:15.370 回答