2017-02-21 31 views
2

据我了解,传递指向函数的指针本质上是将指针的副本传递给函数C.我有一个FILE指针,我将其传递给函数func(),func()从文件中读取一行,然后当我们返回main()。我使用相同的FILE指针从文件中读取另一行。为什么FILE指针在被传递给一个函数后在C中返回主时会改变?

但是,虽然我会想象我会在func()之前完全读取该行,但我实际上在读取了func()之后的下一行。 你能解释为什么FILE指针的行为是这样吗?

这是我的代码:当读文件得到改变/写上一些数据

#include <stdio.h> 

#define STR_LEN 22 

void func(FILE *fd); 

int main() { 
    FILE *fd; 
    char mainString[STR_LEN]; 
    if (!(fd = fopen("inpuFile", "r"))) { 
     printf("Couldn't open file\n"); 
     fprintf(stderr, "Couldn't open file\n"); 
    } 

    func(fd); 
    fgets(mainString, STR_LEN, fd); 
    printf("mainString = %s\n", mainString); 

    fclose(fd); 

    return 0; 
} 

void func(FILE *fd) { 
    char funcString[STR_LEN]; 
    fgets(funcString,STR_LEN, fd); 
    printf("funcString = %s\n", funcString); 
} 
+1

我可以说'fd'(很多会读作“文件描述符”,即来自'open()'的int)对于类型为FILE *的变量来说是一个相当糟糕的名字吗?非常混乱。 – unwind

回答

1

因为FILE指针指向。

所以指针不会改变(仍然指向文件的处理程序结构),但是结构所指向的数据确实存在。

尝试将指针传递为const FILE *您会看到不能因为fread操作(和其他人)更改指向的数据。

一种方法是复制文件描述符,该文件描述符是dup,但不适用于缓冲的FILE对象,只有原始文件描述符。

3

不过,虽然我会想象我读线正好从FUNC调用前...

我无法想象,为什么你会想象。如果FILE*引用的网络连接在消耗读数的情况下根本没有重放功能,该怎么办?线路将存储在哪里以便您可以再次阅读?绝对没有地方可以说。

不仅我会不是想象一下,它有点疯狂。

据我明白指针传递到一个函数基本上穿过指针的拷贝到函数中C.

正确。但是一个指针的副本指向同一个对象。如果我指向一辆汽车,并且您复制了我,那么您指向的是我指向的那辆汽车。

1

问题出在您的初始声明中: As far as I understand passing a pointer to a function essentially passes the copy of the pointer to the function in C

这并没有太大的改变,因为无论你作为指针访问什么,仍然保存你正在访问的FILE的位置,使用指针作为C中函数的参数的全部要点是,你可以修改一个函数范围之外的某个值。

例如,整数指针作为函数参数的常见用法:

void DoSomethingCool(int *error); 

立即使用此代码捕获错误将工作是这样的:

int error = 0; 
DoSomethingCool(&error); 

if(error != 0) 
    printf("Something really bad happened!"); 

换句话说,该指针实际上是修改整数错误,通过访问它的位置并写入它。

要避免这种误解,要记住一个重要的事情就是认识到所有指针都是,实质上就是某个地址。

所以,你可以(在理论上,通过简化样样不少)认为一个int *作为单纯的int,其中恰好是某个变量的地址,对于FILE *值,你可以把它作为一个int,其中int的值是FILE变量的位置。

+0

你是对的,将删除它。 –

1

FILE *fd是一个指针,只是在它的实现使用称为“指针”的C构造的意义上。它是而不是是表示文件位置的指针。

FILE *fd表示手柄到I/O库中的文件对象,struct包括所述文件的实际位置。以一种非常简单的方式,您可以将fd想象为指向文件指针的C指针。

当您在程序周围传递fd时,I/O例程会修改文件位置。此位置由fd的所有用户共享。如果func()通过读取一些数据或致电fseek对该位置进行更改,则相同fd的所有用户都将看到更新的位置。

相关问题