Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么文件指针在被传递到函数后在C中返回main时会发生变化?_C_Pointers - Fatal编程技术网

为什么文件指针在被传递到函数后在C中返回main时会发生变化?

为什么文件指针在被传递到函数后在C中返回main时会发生变化?,c,pointers,C,Pointers,据我所知,将指针传递给函数实际上是将指针的副本传递给C中的函数。我有一个文件指针,我将它传递给函数func(),func()读取文件中的一行,然后当我们返回到main()时。我使用相同的文件指针从文件中读取另一行 然而,虽然我可以想象我完全是在调用func()之前读这一行的,但实际上我是在func()读过的内容之后读下一行的你能解释一下为什么文件指针会这样吗? 这是我的代码: #include <stdio.h> #define STR_LEN 22 void func(FILE

据我所知,将指针传递给函数实际上是将指针的副本传递给C中的函数。我有一个
文件
指针,我将它传递给函数
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*
的变量,名称是否相当糟糕?太令人困惑了。