2017-02-21 57 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的所有用戶都將看到更新的位置。

相關問題