




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、C Primer 始于2014-11-12文字顏色說明:1) 正文中的黑色粗字體表示首次看時,覺得比較重要的文字2) 正文中的紅色表示,復習筆記后添加的知識點ANSI(American National Standards Institute) 美國國家標準協會第13章 文件輸入輸出13.1 和文件進行通信13.1.1 文件是什么l C將文件看成是連續的字節序列,其中每一個字節都可以單獨的讀取;13.1.2 文本視圖和二進制視圖l 二進制視圖中,每一個字節都可以為程序所訪問;l 文本視圖中,不同的操作環境(操作系統),程序所看到的內容和文件有可能不同(例如行尾的標志)13.1.4 標準文件C語
2、言提供3種標準文件。標準輸入、標準輸出、標準錯誤輸出; 標準輸入:getchar()、gets()、scanf() 標準輸出:putchar()、puts()、printf()13.2 標準I/O13.2.1 檢查命令行參數l return 0 與exit(0)的區別: 最初調用的main函數中二者是一樣的,main在一個遞歸程序中時,exit()會終止程序,而return只返回遞歸的前一級。 在main函數以外的函數中調用exit也會終止程序13.2.2 fopen()函數fopen(參數1,參數2) 參數1:是一個地址(指針或數組),數組中包含要打開的文件名 參數2:是一個字符串,指定打開
3、文件的模式。有以下7大類模式1) “r” 打開一個文本文件,可以讀取文件2) “w” 打開一個文本文件,可以寫入文件,先將文件長度截為0。若該文件不存在,先創建3) “a” 打開一個文本文件,向已有文件的尾部追加內容。若不存在,先創建4) “r+” 打開一個文本文件,可以進行更新,也可以讀取和寫入5) “w+” 打開一個文本文件,可以進行更新(讀取和寫入)。先將文件長度截為0,沒有則先創建6) “a+” 打開一個文本文件,可以進行更新(讀取和寫入),讀取整個文件,寫入時只能向尾部追加內容 返回:fopen函數返回一個文件指針fp,這個指針指向FILE(stdio.h中定義的一種派生類型),fp
4、指向關于文件的信息的數據包。如果不能打開文件則返回一個空指針NULL。13.2.3 getc()函數和putc()函數l getc() ch = getc(fp) 表示從fp指定的文件中獲得一個字符;l putc(參數1,參數2)putc(ch,fpout) 表示將字符ch寫入到FILE指針fpout指定的文件中13.2.4 2文件結尾l 從文件中讀取數據的程序需要在到大文件的結尾時停止。到達文件結尾時,getc()函數會返回一個特殊值EOF13.2.5 fclose()函數l Fclose(fp)關閉由指針fp指定的文件,同時根據需要刷新緩沖區。13.2.6 標準文件指針l 包含3個標準文件
5、指針:stdin(標準輸入)、stdout(標準輸出)、stderr(標準錯誤)13.3 一個簡單的文件壓縮程序13.4 文件I/O每個I/O函數都存在一個相似的文件I/O函數。文件I/O函數需要使用一個FILE指針來為這些函數指定要操作的文件。13.4.1 fprintf()和fscanf()函數l fprintf()和fscanf() fprintf/fscanf(參數1,參數2,參數3) 參數1為FILE指針;例如fprintf(fp,“%s”,words)其中fp是FILE指針,words是數組名稱;l rewind(參數1) 使程序回到文件開始處,參數1必須是一個文件指針;13.4.
6、2 fgets()和fputs()函數l fgets(參數1,參數2,參數3) fgets(buf,max,fp) 參數1:一個地址,用于存儲輸入值的地址 參數2:一個整數,輸入字符串的最大長度 參數3:一個文件指針,這個指針指向要讀取的文件 返回值:返回傳遞給它的地址值,當遇到EOF時,返回NULL fgets()函數讀取到它遇到的第1個換行字符的后面,或者讀取比字符串的最大長度少一個的字符,或者讀取到文件結尾。然后fgets()向末尾添加一個空字符以構成一個字符串。如果fgets在達到字符最大數目之前讀完一整行,它將在字符串的空字符前添加一個換行符以表示一行結束。l Fputs(參數1,參
7、數2) 把字符串地址指針所指的字符串寫入指定的文件。(與fgets相比,沒有寫入的長度,因為字符串包含結束符) 參數1:一個地址,是要寫入到文件的字符串的地址 參數2:一個文件指針,指向要寫入字符串的文件l fgets保留了換行符,fputs不會添加換行符;13.5 隨機存取13.5.1 fseek()和ftell() 文件的定位函數l fseek(參數1,參數2,參數3) 參數1:一個文件指針,指向被搜索的文件 參數2:一個long類型的值。表示從起始點開始的偏移量(偏移的字節數),正表示前移,負表示后移,0表示保持不動 參數3:模式,決定偏移量的起始點,一般分為SEEK_SET、SEEK_
8、CUR、SEEK_END 返回值:正常則返回0,不正常則返回-1l ftell(參數1) ftell函數為long型函數,返回文件的當前位置(1個long型數據)。通過返回距離文件起始處的字節數目來確定文件的位置。13.5.4 fgetpos()和fsetpos()處理較大文件的定位函數。13.6 標準I/O內幕l 執行一次fopen函數: 打開一個文件 建立一個(讀寫模式下兩個)緩沖區 創建一個數據結構(包含文件和緩沖區相關數據),包括以下內容 錯誤指示器 文件結尾指示器 指向緩沖區起始處的指針 文件標示符 計數器:記錄實際復制到緩沖區中的字節數 返回一個指向該結構的指針13.7 其他標準I
9、/O函數13.7.4 二進制I/O:fread()和fwrite()數據用二進制形式存入文件,沒有數字形式到字符形式的轉換。存入的數據更精確。13.8 知識總結比較常用的共12 個1) fopen(參數1,參數2) 文件地址,模式2) fclose(參數1) 文件指針3) getc(參數1) 文件指針4) putc(參數1,參數2) 寫入文件的字符,文件指針5) fgets(參數1,參數2,參數3) 存入字符串的地址,字符長度,文件指針6) fputs(參數1) 文件指針7) fprintf(參數1,參數2,參數3) 文件指針,輸出格式,字符串地址8) fscanf(參數1,參數2,參數3)
10、文件指針,輸入格式,字符串地址9) fseek(參數1,參數2,參數3) 文件指針,偏移量,起始點模式10) ftell(參數1) 文件指針11) fread(參數1,參數2,參數3)12) fwrite(參數1,參數2,參數3)第14章 結構和其他數據格式14.1 實例問題:創建圖書目錄P37914.2 建立結構聲明Struct bookchar title41;char author31;float value;struct book library; 把library定義為一個book結構設計的結構變量;l 其中struct是關鍵字,表示接下來是一個結構;l Book:是一個可選的標記l
11、 花括號內是結構成員列表;14.3 定義結構變量l 結構有兩個意思:一是結構設計,一是結構變量 結構設計:告訴編譯器如何表示數據,但并沒讓計算機為數據分配空間 結構變量:編譯器使用book模板為該變量分配空間;l 聲明結構和定義結構變量的過程可以合并,如下:Structchar title41;char author31;float value;library;但是如果要多次使用一個結構模板,就必須使用標記;14.3.1 初始化結構l 使用一個用花括號括起來、逗號分隔的初始化項目列表進行初始化。如下Struct book library“C Primer”,“Stephen Prata”,60
12、.00;14.3.2 訪問結構成員l 訪問結構的成員:用結構成員運算符點(.)例gets(library.title)14.3.3 結構的指定初始化項目l 指定初始化:用點運算符和成員名來表示具體的元素;例:struct book gift = .value = 25.99, .author = “James Broadfool”, .title = “Rue for the Toad”;1) 可以按任何順序指定初始化2) 只初始化某個成員3) 對特定的成員,最后一次賦值是它實際的值14.4 結構數組14.4.1 聲明結構數組Struct book library10;Library本身不是結
13、構名,它是元素類型為struct book結構的數組名。14.4.2 表示結構數組的成員library1.valuelibrary2.title5 第2個結構的title成員的第6個字符14.5 嵌套結構結構的某一個或多個成員也是結構。訪問嵌套結構的成員的方法:應用兩次點運算符。#include #define LEN 20const char *msg5 = /定義字符常量數組 Thank you for the wonderful evening,You certainly prove that a ,is a specail kind of guy.We must get togethe
14、r,over a delicious,and have a few laughs;struct nameschar firstLEN;char lastLEN;struct guystruct names handle;char favfoodLEN;char jobLEN;float income;int main(void)struct guy fellow = /初始化結構Even, Villard ,grilled salmon,personality coach,58112.00;printf(Dear %s,nn,fellow.handle.first);printf(%s%sn,
15、msg0,fellow.handle.first);/訪問嵌套結構的成員printf(%s%sn,msg1,fellow.job);printf(%sn,msg2);printf(%s %s %sn,msg3,fellow.favfood,msg4);printf(n%40s%sn,See you soon,);printf(%40s%sn,Shalala);return 0;14.6 指向結構的指針14.6.1 聲明和初始化結構指針l 聲明:struct guy *him; 意味著指針him現在可以指向任何現有的guy類型的結構。l 初始化:him = & fellow0;14.6.2 使用
16、指針訪問成員l 初始化后的him,有兩種方式訪問指針成員 him - income; (*him).income 二者完全相同14.7 向函數傳遞結構信息函數與結構的傳遞包括3種方式:傳遞結構成員、傳遞結構地址、傳遞結構;14.7.1 向函數傳遞結構成員14.7.2 向函數傳遞結構地址#include #define FUNLEN 50struct fundschar bankFUNLEN;double bankfund;char saveFUNLEN;double savefund;double sum (const struct funds *);/聲明函數,其中參數為指向結構的指針int
17、 main (void)struct funds stan =Garlic-Melon Bank,3024.72,Luckys Savings and Loan,9237.11;printf(Stan has a total of $%.2f.n,sum (&stan);/結構的地址必須用&return 0;double sum (const struct funds *money)return (money-bankfund + money-savefund); /通過指針直接訪問原結構stan14.7.3 向函數傳遞結構#include #define FUNLEN 50struct fu
18、ndschar bankFUNLEN;double bankfund;char saveFUNLEN;double savefund;double sum (struct funds moolah);/聲明函數,參數為結構 int main (void)struct funds stan =Garlic-Melon Bank,3024.72,Luckys Savings and Loan,9237.11;printf(Stan has a total of $%.2f.n,sum (stan);/將結構傳遞給函數 return 0;double sum ( struct funds moola
19、h)return (moolah.bankfund + moolah.savefund); /會創建一個和stan一樣的結構14.7.4 結構的一些特性1) 結構的成員、結構的地址、結構可作為函數的參數向函數傳遞信息2) 賦值:兩個結構類型相同,可將一個結構賦值給另外一個結構3) 把一個結構(已經初始化的)初始化另外一個結構4) 結構可以作為函數的返回值l 結構指針作為參數的例子:/要求輸入名和姓,然后得到姓名中的字母總數#include #include struct namectchar fname20;char lname20;int letters;void getinfo (stru
20、ct namect *);void makeinfo(struct namect *);void showinfo(const struct namect *);int main(void)struct namect person;getinfo(&person);/傳遞的是結構的地址makeinfo(&person);showinfo(&person);return 0;void getinfo (struct namect *pst)printf(Please enter your first name.n);gets(pst-fname);/實際操作的還是那一個結構printf(Plea
21、se enter your last name.n);gets (pst - lname);void makeinfo (struct namect *pst)pst-letters = strlen(pst - fname) +strlen(pst - lname);void showinfo (const struct namect *pst)printf(%s %s,your name contains %d letters.n,pst-fname, pst-lname, pst-letters);l 結構作為參數的例子:/要求輸入名和姓,然后得到姓名中的字母總數#include #in
22、clude struct namectchar fname20;char lname20;int letters;struct namect getinfo (void);/函數返回類型為structstruct namect makeinfo(struct namect);void showinfo(struct namect);int main(void)struct namect person;person = getinfo();person = makeinfo(person);/傳遞的參數為結構showinfo(person);return 0;struct namect geti
23、nfo (void)struct namect temp;/創建一個新的結構printf(Please enter your first name.n);gets(temp.fname);printf(Please enter your last name.n);gets (temp. lname);return temp;struct namect makeinfo (struct namect info)/創建一個新的結構info.letters = strlen(info. fname) +strlen(info.lname);return info;void showinfo (str
24、uct namect info)/創建一個新的結構printf(%s %s,your name contains %d letters.n,info.fname,info.lname, info.letters);14.7.5 結構,還是指向結構的指針1) 為提高效率,使用結構指針作為函數參數,當要保護數據、防止意外改變數據時對指針使用const限定詞2) 處理小型結構時常用傳遞結構值的方法;14.8 把結構內容保存到文件中14.9 結構:下一步是什么14.10 聯合介紹l 定義:一個能在同一個存儲空間里(但不同時)存儲不同類型的數據類型。l 聯合的定義:聯合模板、聯合變量、聯合標記Union
25、 hold int digit; double bigfl; char letter;union hold fit;/其中hold為聯合標記,fit為聯合變量,方括弧為聯合模板;l 聯合的初始化:1) 初始化為同樣的另外一個聯合2) 初始化聯合的第1個元素3) 指定初始化項目14.11 枚舉類型l 定義:枚舉是一種代表整數常量的符號名稱;注:enum常量是int類型的,因此在使用int類型的任何地方都可以使用它。枚舉類型的目的是提高程序的可讀性。l 默認情況下,枚舉列表中的常量被指定為整數值0、1、2等等。l 可以指定常量具有的值。例如:enum levels low = 100,medium
26、 = 500,high = 2000;l 如果只對某一個常量賦值,而沒有對后面的常量賦值,那么這些后面的常量會被賦予后續的值。例如:enum feline cat,lynx =10,puma,tiger; 則對應值的一次為 0,10,11,12。14.12 typedef簡介l 定義:typedef工具是一種高級數據特性,能為某一類型創建自己定義的名字。l Typrdef與#define的區別:1) typedef給出的符號名稱僅限于對類型,而不是對值;2) typedef的解釋由編譯器,而不是預處理器執行3) typedef比#define更靈活l 使用方法:typedef unsigned
27、 char BYTE;隨后就可以用BYTE來定義變量了。即 typedef b A其中b為類型,A為字符名稱l 用typedef來命名一個結構類型時,可以省去結構的標記。注意:typedef并不是創建新的類型,只是創建了便于使用的標簽。14.13 奇特的聲明C語言中,當進行一個聲明時,可以添加修飾符來修飾名稱或標示符。一共包含3個修飾符:*、()、l 這3個修飾符的使用規則:1) 優先級:()、優先級一樣,高于*2) ()、順序從左向右組合14.14 函數和指針l 指向函數的指針:保存著指向函數代碼起始處的地址l 聲明一個函數指針時,必須聲明它指向的函數類型(包括函數返回類型、函數的參量類型)
28、。viod (*pf)(char *)/pf是一個指向函數的指針,(*pf)為一個函數,(char*)為該函數的參量列表,void作為其返回類型。l 函數名可以用來表示函數的地址。第16章 C預處理器和C庫C預處理器:因為在編譯程序之前,先由預處理器檢查程序16.1 翻譯程序的第一步1) 首先將源代碼中出現的字符映射到源字符集;2) 第二,將兩個物理行轉換成一個邏輯行;3) 其次,編譯器將文本劃分成預處理的語言符號序列、空白字符及注釋序列。16.2 明顯常量:#define每個#define行由3部分組成:#define PX printf(“x is %d.n”,x); 第1部分 第2部分
29、第3部分第1部分:#define本身第2部分:縮略語,稱為宏第3部分:類對象宏(主體)l 宏展開:預處理器在程序中發現了宏的實例后,總會用實體代替該宏,從宏變成最終的替換文本的過程稱為宏展開;l 預處理器不進行計算,只是按照指令進行文字替換操作。但是在雙引號中的宏卻不會進行替換,例#define TWO 2#define OW “ABC”Printf(“TWO:OW”); 則打印的結果是TWO:OW16.2.1 語言符號16.2.2 重定義常量假設將LIMIT定義為20,后來在該文件中又把LIMIT定義為25,這個過程被稱為重定義常量。16.3 在#define中使用參數l 類函數宏:通過使用
30、參數,可以創建外形和作用都與函數相似的類函數宏。l 注意事項:1) 使用足夠多的圓括號來保證以正確的順序進行運算和結合;2) 在宏中不要使用減量和加量運算16.3.1 利用宏參數創建字符串:#運算符l 字符串化:#符號可將語言符號轉換為字符串。假如x為一個宏參量,則#x可以把參數名轉化為相應的字符串。16.3.2 #運算符l #運算符:將兩個語言符號組成單個語言符號16.4 宏,還是函數l 宏與函數間的選擇實際上是時間與空間的權衡。1) 宏產生內聯代碼,也就是說在程序中產生語句。如果使用20次宏,則會把20行代碼插入語句中。占用的空間更大。2) 函數的調用涉及控制權的轉移,花費的時間更長。l
31、使用宏注意事項:1) 宏的名字中不能有空格2) 用圓括號括住每個參數,并括主宏的整體定義3) 用大寫字母表示宏函數名4) 使用宏代替函數來加快速度時,應先確定宏是否會引起重大差異。16.5 文件包含:#includel 預處理器發現#include指令后,就會尋找后跟的文件名并把這個文件的內容包含到當前文件中。1) #include 文件名放在尖括號中,告訴預處理器在標準系統目錄文件中尋找文件2) #include”names_st.h” 文件名放在雙引號中,告訴預處理器在當前目錄中尋找文件。16.5.1 頭文件:一個實例1. 頭文件:#define SLEN 32struct names_s
32、tchar firstSLEN;char lastSLEN;typedef struct names_st names;/typedef定義void get_names(names *);/函數參數為指向結構的指針void show_names(const names *);2. names_st.c#include#includenames_st.hvoid get_names(names *pn)int i;printf(Please enter your first name:);fgets(pn-first,SLEN,stdin);/用fgets函數是避免目標數組溢出/*i=0;whi
33、le(pn-firsti != n & pn - firsti != 0)i+;if(pn - firsti = n)pn - firsti = 0;/輸入的字符串中有換行符n(ASII碼值為0x0a)時,用空字符0(ASII碼值為0x00)代替elsewhile(getchar()!= n)continue;/*如果不加入這段程序,則姓的字符個數不到32時,會把換行符當成一個字符,輸出時便會換行。當姓超過32字符時,取前31個字符printf(Please enter your last name:);fgets(pn - last,SLEN,stdin);i=0;while(pn - la
34、sti != n & pn - lasti !=0)i+;if(pn - lasti = n)pn - lasti = 0;elsewhile(getchar()!= n)continue;void show_names(const names *pn)printf(%s %s ,pn - first,pn - last);3. useheader.c/主程序#include#includenames_st.hint main(void)names candidate;get_names(&candidate);printf(Lets welcome );show_names(&candida
35、te);printf(to this program!n);return 0;16.5.2 使用頭文件l 頭文件內容的最常見的形式包括:1) 明顯常量2) 宏函數3) 函數聲明4) 結構板定義5) 類型定義6) 可以用頭文件來聲明多個文件共享的外部變量7) 使用具有文件作用域、內部鏈接和const限定詞的變量或數組。16.6 其他命令有時需要不同的工作環境準備不同的C程序。預處理器提供一些指令來幫助程序員編寫這樣的代碼:改變一些#define宏的值后,這些代碼就可以從一個系統移植到別的系統。可分為四大類:#undef、條件編譯、#line和#error、#progma16.6.1 #undef
36、指令l 取消前面的#define定義l 如果想使用一個特定的名字,但又不確定前面是否已經使用了該名字,為安全起見,就可以取消該名字的定義。16.6.2 已定義:C預處理器的觀點l 已定義:如果C預處理器遇到一個標示符,要么是已定義,要么是未定義。其中已定義是指C預處理定義的,如果標示符不是一個宏,則預處理器把標示符 當做未定義。l 已定義宏:分為類對象宏(包括空宏)、類函數宏。l #define宏的作用域:從文件的定義點開始,直到用#undef取消宏為止,或直到文件尾為止。16.6.3 條件編譯l 條件編譯指令可以告訴編譯器:根據編譯時的條件,接受或忽略信息(代碼)塊。包括#ifdef、#el
37、se、#endif或#ifndef 或#if、#elif1) #ifdef、#else、#endif#ifdef #else格式非常類似于C中的if else。主要差異為預處理器不能識別代碼塊的花括號,所以需要#endif來結束指令塊。2) #ifndef #endif指令 #ifndef用來定義此前未定義的常量。 #ifndef #endif指令通常用于防止多次包含同一文件。3) #if #elif指令 #if后跟常量整數表達式(更像if),在該表達式中可以使用C的關系運算符合邏輯運算符。 #ifdef 與#if的關系#ifdef VAX #if defined(VAX) 其中defined是預處理器運算符。如果defined的參數已用#define定義過,則defined返回1,否則返回016.6.4 預定義
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 校園管理小技巧分享會
- 激光技術工程師知識考點鏈接試題及答案
- 大學生職業規劃大賽《勘查技術與工程專業》生涯發展展示
- 2025年傾廢航行數據記錄儀合作協議書
- 藥物運輸過程考查試題及答案
- 車工安全操作培訓
- 高中化學離子共存知識點
- 2025年共振柱試驗機項目發展計劃
- 西醫臨床考試深入探討試題及答案
- 激光在科研中的角色試題及答案
- 二零二五協警聘用合同范文
- 防雷安全知識培訓課件
- 政務服務人員培訓
- 寵物醫院招聘課件
- 2024年山東司法警官職業學院招聘考試真題
- 2025建筑安全員C證考試(專職安全員)題庫及答案
- 安全標識(教學設計)-2024-2025學年浙美版(2012)美術四年級下冊
- 環境保護部華南環境科學研究所(廣州)2025年上半年招考人員易考易錯模擬試題(共500題)試卷后附參考答案
- 2024-2025學年七年級下冊歷史 【教學課件】第10課《金與南宋的對峙》
- 滁州地鐵筆試試題及答案
- 八年級英語下學期期中模擬卷(上海專用)-2024-2025學年(牛津上海版)
評論
0/150
提交評論