2014-12-18 80 views
5

我一直在C開發一段時間,來自面向對象的語言,如C++和Java,並使用標準庫函數,如fread()strtok(),我開始懷疑:這些函數如何去存儲變量相關到他們的狀態?C庫如何存儲狀態變量?

例如,strtok()對後續調用的行爲會有所不同,並且fread()會跟蹤您在文件中的位置。這些信息必須存儲在某個地方,面向對象的語言中有一些作用域結構,例如privateprotected來防止這些值被不必要的修改,但據我所知C沒有這些。

那麼,他們如何安全地存儲?或者它們實際上是全球性的,可以從任何地方修改?當我寫一個帶有需要存儲類似狀態信息的工具函數的頭文件時,就產生了這個問題。在C中做這種事情的「正確」方式是什麼,它在現有的庫中是如何處理的?

+3

'fread'並不需要保存調用之間的狀態,因爲它需要存儲由'fread'所需的所有信息'FILE'結構。 –

回答

7

這些調用使用static變量。本地靜態變量在函數調用之間保留其值。全局靜態變量或函數只能由同一個文件中聲明的其他函數訪問。

+0

正如旁註所示,仍然可以通過將指針(地址)傳遞給變量,從另一個文件中獲取靜態全局變量(文件範圍)。 – Jite

+0

_in在同一個file_部分是我失蹤。我沒有意識到全局靜態變量的訪問受文件限制。謝謝! – dasizeman

+1

@sizeman請注意,正如我在上面解釋的那樣,它是*鏈接器*,它不能在文件外部看到它,但是如果你有一個帶有全局'static int a'的文件'A',你可以通過地址'a'到文件'B',仍然從文件'B'訪問變量。我認爲這很重要,即使這不是你每天都做的事情。 – Jite

8

在fread()的情況下,狀態存儲在FILE結構中。該結構是由fopen()分配的資源,該資源返回指向它的指針,並將該指針傳遞給每個文件操作調用。當調用fclose()時,資源被釋放。 FILE資源可以從靜態池中分配,也可以從堆中動態分配 - 這將取決於實現。例如:

RESOURCE* getResource() 
{ 
    return malloc(sizeof(RESOURCE)) ; 
} 

int useResource(RESOURCE* r) 
{ 
    return r.index++ ; 
} 

void releaseResource(RESOURCE* r) 
{ 
    free(r) ; 
} 

strtok()另一方面包含當字符串被傳遞,並且當一個空指針傳遞作爲起始點被初始化的內部靜態指針。

例如:

int getState() 
{ 
    static int state = 0 ; 
    return state++ ; 
} 

int main() 
{ 
    int s ; 

    do 
    { 
     s = getState() ; 
     printf("state = %d\n", s ; 

    } while(s < 10) ; 
} 
+0

使用你的例子來澄清一些事情,在你的第二個代碼片段中,我無法直接訪問'state',也沒有直接從'main()'指向它的指針? – dasizeman

+1

@sizeman:正確,getState函數必須顯式地返回一個指針,就像在getResource示例中一樣,因爲它的狀態是在外部訪問的。這些不是唯一的可能性,它們只是fread和strtok使用的方法。例如,可能會返回內部保存的數據的句柄或索引,而不是指針或不透明類型。 – Clifford