为什么文件指针在被传递到函数后在C中返回main时会发生变化?
据我所知,将指针传递给函数实际上是将指针的副本传递给C中的函数。我有一个为什么文件指针在被传递到函数后在C中返回main时会发生变化?,c,pointers,C,Pointers,据我所知,将指针传递给函数实际上是将指针的副本传递给C中的函数。我有一个文件指针,我将它传递给函数func(),func()读取文件中的一行,然后当我们返回到main()时。我使用相同的文件指针从文件中读取另一行 然而,虽然我可以想象我完全是在调用func()之前读这一行的,但实际上我是在func()读过的内容之后读下一行的你能解释一下为什么文件指针会这样吗? 这是我的代码: #include <stdio.h> #define STR_LEN 22 void func(FILE
文件指针,我将它传递给函数func()
,func()
读取文件中的一行,然后当我们返回到main()
时。我使用相同的文件
指针从文件中读取另一行
然而,虽然我可以想象我完全是在调用func()
之前读这一行的,但实际上我是在func()
读过的内容之后读下一行的你能解释一下为什么文件指针会这样吗?
这是我的代码:
#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);
}
#包括
#定义STR_LEN 22
无效函数(文件*fd);
int main(){
文件*fd;
字符串[STR_LEN];
如果(!(fd=fopen(“inpuFile”,“r”)){
printf(“无法打开文件\n”);
fprintf(stderr,“无法打开文件”\n);
}
func(fd);
fgets(主干道、主干道、fd);
printf(“主字符串=%s\n”,主字符串);
fclose(fd);
返回0;
}
void func(文件*fd){
char funcString[STR_LEN];
fgets(funcString、STR_LEN、fd);
printf(“funcString=%s\n”,funcString);
}
因为文件
指针指向读/写文件时更改的某些数据
因此指针不会改变(仍然指向文件的处理程序结构),但结构所指向的数据会改变
尝试将指针作为const FILE*
传递,您将看到无法传递指针,因为fread
操作(和其他操作)会更改指向的数据
一种方法是复制文件描述符,dup
会复制文件描述符,但对缓冲的file
对象不起作用,只对原始文件描述符起作用
然而,当我想象我读到func调用之前的那句话时
我无法想象你为什么会这样想。如果文件*
引用了一个网络连接,而该网络连接在需要读取的地方根本没有重播功能,该怎么办。该行存储在哪里,以便您可以再次读取?绝对没有地方放它
我不仅不会想象,这有点疯狂
据我所知,将指针传递给函数实际上是将指针的副本传递给C中的函数
对。但是指针的副本指向同一个对象。如果我指着一辆车,你模仿我,你指的就是我指的那辆车,也是唯一一辆车。问题在于你最初的陈述:
据我所知,将指针传递给函数实际上是将指针的副本传递给C中的函数
这并没有太大的变化,因为无论您以指针的形式访问什么,它仍然保留您正在访问的文件的位置,在C中使用指针作为函数的参数的全部意义在于,您可以修改函数范围之外的某个值
例如,整数指针作为函数参数的常见用法:
void DoSomethingCool(int *error);
现在,使用此代码捕获错误的工作方式如下:
int error = 0;
DoSomethingCool(&error);
if(error != 0)
printf("Something really bad happened!");
换句话说,指针将通过访问其位置并写入来修改整数错误
要避免这种误解,需要记住的一件重要事情是要认识到,指针的所有内容,本质上都是某个对象的地址
因此,您可以(理论上,通过将所有内容简化很多)将int*
简单地视为int
,其值恰好是某个变量的地址,对于文件*
,您可以将其视为int
,其中int的值是文件
变量的位置。文件*fd
只是在其实现使用称为“指针”的C结构的意义上,才是指针。它不是表示文件位置的指针
FILE*fd
表示I/O库中文件对象的句柄,即包含文件实际位置的struct
。以一种非常简单的方式,您可以将fd
看作指向文件指针的C指针
当您在程序中传递fd
时,I/O例程会修改文件位置。此职位由fd
的所有用户共享。如果一个func()
通过读取一些数据或调用fseek
对该位置进行更改,相同fd
的所有用户都将看到更新的位置。我可以说fd
(许多人将其读取为“文件描述符”,即open()
中的int
)对于类型为FILE*
的变量,名称是否相当糟糕?太令人困惑了。