編寫簡單的c執行庫(二)

2022-07-09 22:03:13 字數 2577 閱讀 8047

在前面編寫簡單的c執行庫(一)中主要實現了呼叫main函式前的初始化、獲取引數和環境變數、退出程式等工作。接下來我們真正實現c標準庫中的一些函式(主要是檔案操作、字串操作函式)。不過我們對這些函式的實現力爭簡單,對於效率方面考慮的不是很多,因為目的主要還是學習神秘的庫是怎麼實現的。

1 檔案操作

c中的標準i/o庫都是帶有快取的,我們在這裡為了實現的簡單,將快取省略了,直接包裝了有關檔案操作的系統呼叫。現在我們直接看檔案開啟的函式:

1

static

int open(const

char *pathname, int flags, int

mode)

2

open函式中直接呼叫了嵌入彙編呼叫了系統呼叫。對於系統呼叫的返回值,如果是負數,直接返回-1,否則直接返回。這個函式是系統呼叫的乙個包裝,本質其實就是個系統呼叫。然後我們在open函式的基礎上實現c標誌庫函式中的fopen函式。

1 file *fopen(const

char *path, const

char *mode)

2

由於我沒有像標誌i/o庫那樣實現快取,所以我直接把file定義為int型,這樣我們用file就相當於用了檔案描述符。從上面的**中可以知道我設定了檔案的建立許可權只有檔案建立者有讀寫執行的許可權,還有就是我只實現了以唯讀、只寫、讀寫方式開啟檔案,對於追加等方式沒有實現。然後函式read、fread和write、fwrite都可以用相同的方式實現,還有fputc,fputs也是已一樣的。

2 輸出函式

i/o函式中比較麻煩的要屬實現printf、fprintf這些可變引數的函式,當然這些函式都是呼叫vfprintf函式實現的,所以只要實現了vfprintf函式,其它的函式實現就比較簡單了。

首先來看下我實現的vfprintf函式**:

1

int vfprintf(file *stream, const

char *format, va_list ap)217

else

18 flag = 1;19

break;20

case'd

':21if (flag == 1)22

27else

2832 flag = 0;33

break;34

case's

':35if (flag == 1)36

40else

4145 flag = 0;46

break;47

case'\n

':48/*

換行*/

49 fputc(0x0d

, stream);

50 n ++;

51 fputc(0x0a

, stream);

52 n ++;

53break;54

default

:55 fputc(*format, stream);

56 n ++;57}

58 format ++;59}

60return

n;61 }

vfprintf主要麻煩的是對格式化字串的分析,我們在這裡使用一種比較簡單的演算法:

(1)定義模式:翻譯模式/普通模式

(2)迴圈整個格式字串

a) 如果遇到%

i 普通模式:進入翻譯模式

ii 翻譯模式: 輸出%, 退出翻譯模式

b) 如果遇到%後面允許出現的特殊字元(如d和s)

i 翻譯模式:從不定引數中取出乙個引數輸出,退出翻譯模式

ii 普通模式:直接輸出該字串

c) 如果遇到其它字元(除\n):無條件退出翻譯模式並輸出字元

d) 如果遇到'\n'字元,如果直接輸出是不能達到換行的效果的,必須要同時輸出回車換行才行

從上面的實現vfprintf的**中可以看出,並不支援特殊的格式控制符,例如位數、進度控制等,僅支援%d與%s這樣的簡單轉換。真正的vfprintf格式化字串實現比較複雜,因為它支援諸如「%f」、「%x」已有的各種格式、位數、精度控制等。我覺得上面實現的**已經充分的展示了vfprintf的實現原理和它的關鍵技巧,所以沒有必要乙個乙個的都實現。現在來實現printf的就簡單多了,下面是printf的實現**:

1

int printf(const

char *format, ...)

2

對於可變引數的程式設計,我已經在c語言中的可變引數程式設計中詳細的講過了,包括它的實現原理。所以只要了解了可變引數的程式設計,對於實現printf函式來說就真的沒什麼難度了,純粹就是呼叫vfprintf函式而已。如果實現了printf函式,那麼對於實現scanf、fscanf也是同樣的原理。

附件:檔案操作

C執行庫 二

任何乙個c程式,它的背後都有一套龐大的 來進行支撐,以使得該程式能夠正常執行。這套 至少包括入口函式,及其所依賴的函式所構成的函式集合。當然,它還理應包括各種標準庫函式的實現。這樣的乙個 集合稱之為執行庫 runtime library 而c語言的執行庫,即被稱為c執行庫 crt 如果擁有visua...

windows 打包c 執行庫

c 程式開發完成以後需要打包,一般情況下需要帶著c 執行庫,打包執行庫有兩種方式 1 直接打包安裝程式,比如vc redist.x64.exe 2 打包執行庫dll 微軟官方支援第一種方式,對於第二種方式沒有給出具體的操作流程。第一種方式一般是在程式安裝完成後,安裝vc redist.x64.exe...

spine unity 執行庫簡單基本使用指南

說是寫個指南,其實是想吐槽。官方執行庫文件真的辣雞的不行,它的說明文件看著寫的挺全的,結果都是過時的了,裡面提的api大部分根本就找不到!官方文件 但是我們又不得不用不是,所以就要自己翻它 找真正能呼叫的api了,這裡推薦還是看一看它的官方文件,可以至少讓我們對它的架構思路有一定的理解,方便快速分析...