270 likes | 466 Views
結構 struct. 結構 struct. 結構 (structure) 是資料的集合,我們可以在結構內包含 許多不同的資料型態 。 struct 結構名稱 { 資料型態 結構成員 ; 資料型態 結構成員 ; } struct Card{ char name[20]; int number; }. 一般宣告與 typedef. 結構一般的宣告方式是: struct 結構名稱 結構變數名稱 ; 但若在宣告結構時加上 typedef 並定義其名稱,就可不必加上 struct 。 EX: typedef struct card{ … }card;
E N D
結構struct • 結構(structure)是資料的集合,我們可以在結構內包含許多不同的資料型態。 • struct結構名稱{資料型態 結構成員;資料型態 結構成員;} • struct Card{ char name[20];int number;}
一般宣告與typedef • 結構一般的宣告方式是: • struct結構名稱 結構變數名稱; • 但若在宣告結構時加上typedef並定義其名稱,就可不必加上struct。 • EX: • typedefstruct card{…}card; • card mycard;
存取結構成員-“.“ 運算子 • 存取結構裡面的成員我們可以利用.運算子來進行操作: • EX:mycard.number=2; • 我們可以將用”.”存取的成員當作一般的變數使用。
結構與指標 “->”運算子 • 結構也可以使用指標來間接地存取。 • EX:struct Card{ char name[20];int number;}mycard[10];int main(){struct Card *p=mycard;i=0; for(i=0;i<10;i++)scanf(“%s%d”,p->name,&p->number);}
細談typedef • 雖然typedef不能定義新的型態,但是可以將現有的型態定義新的名稱。 • EX: • typedef long longint LL;LL a;typedefstruct Card{…}Card;Card mycard;
串流(stream)的概念 • 在C裡面,為了對系統輸出入的方便,有一種抽象的概念叫做『串流(stream)』。 • 簡單來說,串流就是一連串的資料,例如一份程式碼就是一份字元的串流。 • 許多裝置的輸出入也都可以視為串流,像是螢幕、鍵盤等,如此一般可以達到輸出入的一致性。
常見的串流 • stdin(standard input):標準輸入串流,一般輸入的資料都會預設放在這裡。 • stdout(standard output):標準輸出串流,所有輸出到螢幕上的資料都會放在這裡。 • stderr(standard error):此串流也會被輸出到螢幕上,但是程式可以根據輸出資料所屬的串流決定是否記錄。
檔案的輸入輸出 • C對於檔案的處理也是基於串流的概念: • 用一個FILE型態的指標指向串流,並且利用這個指標來作輸入輸出。 • 但需要注意的是,要輸入輸出的串流必須要是”開啟”的。
fopen()函數與fclose()函數 • FILE *fopen(const char *filename,const char *mode); • fopen()會用依據使用者指定的*mode,開啟一個代表指定檔案的串流,並回傳串流的指標,若開啟失敗則回傳NULL。 • intfclose(FILE *stream); • fclose()會嘗試關閉指定的串流,成功回傳1,失敗回傳0。 • Ex: • FILE *F;if((F=fopen(“file”,”r”))==NULL){ puts(“ERROR”);}fclose(F);
模式符號*mode • “r”:可以讀取 • “w”:可以寫入 • “a”:只能用附加的方式在最後寫入檔案 • “b”:檔案為二進位的檔案 • “+”:可以讀寫,若前面為”a”,則是可以讀且可以用附加的方式寫入。
輸出串流的運作形式 • C的輸出串流的運作形式是開啟串流後,開啟一個緩衝區,並將之後輸出的資料放入緩衝區中,等到關閉串流之後再將資料存入檔案中。 • 所以開啟一個串流,最後一定要記得關閉串流。
一般的檔案輸出入函數 • intfgetc( FILE *stream );回傳讀到的下一個字元,錯誤或EOF回傳EOF • intfputc( intch, FILE *stream );成功回傳該字元,失敗回傳EOF • char *fgets( char *str, int num, FILE *stream );成功回傳str,失敗回傳NULL • intfputs( const char *str, FILE *stream ); 成功回傳一個非零值,失敗回傳EOF。
一般的檔案輸出入函數 • intfprintf( FILE *stream, const char *format, ... ); • intfscanf( FILE *stream, const char *format, ... ); • 這兩個函數的使用方式與一般輸出入的scanf()以及printf()相同。 • intfeof( FILE *stream );若stream已到檔案結尾則回傳一非零整數。
二進制檔案的輸出入 • intfread( void *buffer, size_t size, size_t num, FILE *stream ); • intfwrite( const void *buffer, size_t size, size_t count, FILE *stream ); • fread與fwrite為C讀寫二進制檔案的途徑,好處在於不用轉換成數值或字元的形式,且是以bytes數量為單位讀寫。
fread()與fwrite() • 跟qsort()函式很像,只是我們現在要做的是把一段記憶體上的東西讀寫到檔案裡。 • fread()會把從stream目前的位置,讀取num個大小為size的位元組,儲存到記憶體buffer上,最後回傳成功讀入的組數。 • fwrite()會從記憶體buffer上取count個大小為size的位元組,寫入stream目前的位置,回傳為成功寫入的組數。
fread()與fwrite() • Example: • Int main(){ FILE *strr; FILE *strw;int n; if((strr= fopen(“inp”,”rb”) )== NULL || (strw= fopen(“opt”,”wb”) )== NULL) { puts(“ERROR”); return 0; }fread(&n,sizeof(int),1,strr);fwrite(&n,sizeof(int),1,strw);fclose(strr);fclose(strw);}
變更在串流中的位置 • intfseek( FILE *stream, long offset, int origin ); • fseek()可以設定stream在串流中目前的位置。 • 函數會從串流中中指定的origin位置移動offset個位元組 • Origin: SEEK_SET:串流開始位置 SEEK_CUR:串流目前位置 SEEK_END:串流結束位置
變更在串流中的位置 • long ftell( FILE *stream ); • ftell()會回傳stream目前的位置,若發生錯誤則回傳-1。 • void rewind( FILE *stream ); • rewind()會將stream設為該串流的開頭。
BMP • BMP是bitmap的簡寫,是一種點陣圖格式。 • 通常會出現的顏色深度有: • 1bit(2色)、2bits(4色)、4bits(16色) 8bits(256色)、16bits(65536色 )、24bits • 代表每個點顏色種類數。
BMP的二進位格式 – 圖形數據 • 接下來會由下而上,由左而右地呈現每一個點的資訊,依據圖形的深度決定每個點所占用的bytes數(如深度為24bits,則每個點占用3bytes) • 當一列填完之後,若該列所填的bytes數不被4整除,則會任意加入一些資料,使得被4整除,再加入下一行的點。