




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第六章指針
第一節幾個大家熟悉的指針
第二節C語言中的指針
第三節指針和數組
第四節編譯預處理
第五節文件操作
第六節進階部分知識
陳孟建鄒玉金熊傳光編著電子工業出版社出版第一節幾個大家熟悉的指針一、旅館客房指針概念假設某旅館是一個四層樓房,共有客房16間,在某一時刻房間內入住旅客的人數如圖。從圖中可知,101號房間住的是1名男性、102和103號房間住的是2名男性、104號房間住的是1名女性……。我們將房間號稱為地址,住在房間號(地址)內的人數稱為數據,其屬性有男性或女性、有1名也有2名甚至3名。某旅館某一時刻旅客入住情況陳孟建鄒玉金熊傳光編著電子工業出版社出版旅館住宿情況有以下幾個特點:(1)某一個房間號(地址)入住的旅客是個動態量。(2)某一個房間號(地址)入住的人數是個動態量。(3)某一個房間號(地址)人往人的屬性是個動態量。(4)某一個房間號是一個常量。也就是說,地址(房間號)是一個確定不變的量,而地址內儲存的數據(旅客)是一個不確定可變的量,當然,數據的屬性(男、女)也是可變的。如果使用指針的概念來解釋的話,則地址(房間號)就是指針,例如,101這個房間號就是指向一樓的第一個房間位置的指針、203是指向二樓的第三個房間位置的指針。至于指針指向某個位置內住的旅客人數、性別等是不確定的。陳孟建鄒玉金熊傳光編著電子工業出版社出版二、幾個日常生活中指針概念1.郵件指針概念我們知道傳統的郵件必須寫明收件人的詳細地址,即某某省市、某某街道、某某路牌號、某某門牌號等。例如:(1)王小明的地址是:浙江省杭州市文一路128號,王小明的地址就是王小明的指針,該指針是指向浙江省杭州市文一路128號這個確定的地理位置。(2)張國華的地址是:上海市普陀區文明路818號13幢2單元502室,張國華的地址就是張國華的指針,該指針是指向上海市普陀區文明路818號13幢2單元502室這個確定的地理位置。至于王小明家當時可能有5個人在家,其中二個大人,三個小孩,3男2女,張國華家當時可能有4個人在家,其中三個大人,一個小孩,3女1男。也就是指向某家的地址是一個確定的量,而在家人數是一個不確定的變量。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.取款指針概念我們到銀行去存取款時,銀行工作人員將根據我們的帳號去找我們的存款單,找到之后在存單上寫入存款、取款的金額。如果使用指針的概念來解釋的話,則帳號就是存單的指針,存款數是存單的內容。例如:(1)劉路碧的銀行帳號是10109595310,其存款金額是25000.00元。那么,劉路碧存單的指針就是10109595310,指針指向存款金額是25000.00元。(2)朱畢生的銀行帳號是1542100100200059985,其存款金額是1458.68元。那么,朱畢生存單的指針就是1542100100200059985,指針指向存款金額是1458.68元。陳孟建鄒玉金熊傳光編著電子工業出版社出版四、C語言中的單元地址和單元內容通過前幾個例子可以看出,指針通常與地址有關,指針指向某一個地址,該地址內必然保存著一些內容。那么,C語言中的地址與地址內容又是如何的呢?數據在內存中是如何存儲的,又是如何讀取的呢?1.直接訪問方式圖所示的是三個整型變量i、j、k,編譯時系統分配2000和2001兩個字節給變量i,2002和2003字節給變量j,2004和2005字節給變量k。變量i、j、k三個整型變量的值都是通過地址來進行存取的。例如,printf(“%d”,i)的執行過程是:根據變量名與地址的對應關系,找到變量i的地址2000,然后,從由2000開始的兩個字節中取出數據(即變量的值15),將其輸出。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.間接訪問方式在C語言中還有另外一種存取數據的方式,即將變量i的地址存放在另一個內存單元中,這種存放地址值的變量是一種特殊的變量,我們將它稱為指針變量。假設,定義一個指針變量為i_pointer,該變量被存放在3400開始的兩個字節單元中,其值是地址2000,即:i_pointer=&i;這時,i_pointer變量的值就是i整型變量所占用存儲單元的首地址2000。所謂“指向”就是通過地址來實現的。i_pointer中的值為2000,它是i地址,這樣就在i_pointer與i之間建立起一種聯系,即通過i_pointer能知道i的地址,從而找到變量i的內存單元,圖6-3中以箭頭表示這種“指向”關系。陳孟建鄒玉金熊傳光編著電子工業出版社出版第二節C語言中的指針一、指針變量1.什么是指針變量我們在前幾章中已經知道C語言程序所創建的變量,這些變量有數值變量、字符變量、數組變量等,它們都被分配在某個確定的存儲單元之中,變量的名字就是該存儲單元首字節的地址,是地址常量。C通過變量的地址來訪問變量,訪問的方式可分為直接訪問和間接訪問。由于地址指向要訪問的存儲單元,因此,又將地址形象地稱為“指針”,將地址常量稱為“指針”常量。一個變量的地址稱為該變量的“指針”,例如,地址2000是變量i的指針。如果有一個變量專門用來存放另一個變量的地址,則它稱為“指針變量”。圖6-3所示的i_pointer變量就是一個指針變量,該變量的值就是2000(地址)。所以,我們可以說指針變量的值(即指針變量中存放的值)是指針(地址)。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.指針變量的定義我們知道,在C語言中所有的變量在使用之前都必須事先定義,指針作為一個特殊的變量也不例外,必須事先定義,然后再使用。指針變量定義的一般格式:類型標識符*指針變量名;例如:float*pointer_1;/*定義pointer_1為指針變量,該指針變量指向實型變量*/char*pointer_2;/*定義pointer_2為指針變量,該指針變量指向字符型變量*/陳孟建鄒玉金熊傳光編著電子工業出版社出版3.指針變量四要素要使用指針變量,首先要搞清楚指針變量的四個要素,即:指針變量的類型、指針變量所指向的類型、指針變量的值或者叫指針變量所指向的存儲單元、指針本身所占據的存儲單元。(1)指針變量的類型指的是指針本身的類型,由于指針變量存放的是地址,所以,指針變量本身的類型是整型。(2)指針變量所指向的類型指的是類型標識符。類型標識符指的是定義的指針變量是指向何種數據類型,例如,類型標識符為float,則表示定義的指針變量只能指向實數型的變量;類型標識符為char,則表示定義的指針變量只能指向字符型的變量;類型標識符為int,則表示定義的指針變量只能指向整型變量。陳孟建鄒玉金熊傳光編著電子工業出版社出版(3)指針變量的值指的是指針所指向的存儲單元,該存儲單元稱為地址。例如,某一個變量的存儲單元地址為2024,則指針變量的值就是2024,該值為一個整型值。(4)指針變量本身所占據的存儲單元指的是指針變量用來存放地址時所需占用的位置大小。在32位計算機系統中,該變量本身占4個字節的存儲單元。(5)指針變量名前的標識符“*”表示該變量為指針變量。在定義指針變量時,標識符“*”必須寫上。(6)一個指針變量只能指向同一個類型的變量,不能忽而指向一個整型變量,忽而指向實型變量。也就是說,只有同一類型變量的地址才能放到指向該類型變量的指針變量中。陳孟建鄒玉金熊傳光編著電子工業出版社出版二、運算符&和*1.運算符&運算符&表示取地址,&i的運算結果是一個指針,指針所指向的類型是i的類型,指針所指向的地址,就是i的地址。2.運算符*運算符*稱為指針運算符,有時也可稱為“間接訪問”運算符。&i為變量i的地址,如果有語句pointer_1=&i;該語句表示將i變量的地址賦給指針變量,而*pointer_1則表示該指針變量所指向的是i變量地址的值。陳孟建鄒玉金熊傳光編著電子工業出版社出版三、指針變量的引用通過以上幾個程序的分析,我們已知道指針變量的用法了,下面我們再次對指針變量作進一步的分析。假設pointer_1是一個指針變量,則pointer_1的值是一個地址值,引用指針變量pointer_1所指向的變量的值,應表示為“*pointer_1”。表達式“pointer_1=&a”的作用是:將a的地址送給pointer_1,使pointer_1指向a。表達式“*pointer_1=a”的作用是:將a的值送給pointer_1所指向的變量。請看以下一個程序段:chara[5]={‘A’,’B’,’C’},li=‘x’,*pointer_1=a,*pointer_2;pointer_1=pointer_1+3;*pointer_1=li;pointer_2=&li;*pointer_2=*pointer_1+1;在執行過程中,各變量的當前值如下:陳孟建鄒玉金熊傳光編著電子工業出版社出版(1)執行賦值語句前①*pointer_1=a,表示將a字符數組首地址的值賦給*pointer_1。②li=‘x’,表示li字符變量的初始值為x。③*pointer_2指針變量的值不確定。
以上各變量的當前值如圖6-6所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版(2)執行pointer_1=pointer_1+3時,指針pointer_1指向a[3],其它變量情況仍不變,如圖6-7所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版(3)執行*pointer_1=li時,表示將li字符變量的值賦給指針變量pointer_1所指向的地址,如圖6-8所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版(4)執行pointer_2=&li時,表示將li的地址賦給pointer_2指針變量,pointer_2所指向的是li的地址,如圖6-9所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版(5)執行*pointer_2=*pointer_1+1時,表示將指針變量所指向a[3]變量的值x再向下一個字符,即是‘y’,如圖6-10所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版四、指針運算指針是一種數據類型,具有無符號整數值。對于指針類型數據,可以進行下列的運算:(1)指針變量與整數的加法運算、減法運算。(2)同一數組中各元素的地址之間作關系運算、相減。(3)賦值運算。1.指針變量與整數的加法和減法運算當指針變量與一個整數進行相加、減運算時,例如:P++、P--、P+i、P-i、p--=i等。C語言規定,一個指針變量加或減一個整數并不是簡單的加或減一個整數,而是將該指針變量的地址和它所指向的變量所占的內存字節數相加或相減。即:p+i代表地址計算,表示指針在內存空間向下移動,用式子p+c*i來計算,其中c為系數,根據數據類型長度而定,對整型數據C=2;實型數據C=4;字符型數據C=1。這樣才能保證*(P+i)指向P下面的第i個元素,它才有意義。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.同一數組中各元素的地址之間作關系運算、相減指向不同類型數據的指針之間不可以作關系運算,因為,不同數組被分配了不同的存儲空間,所以兩個指向不同數組中元素的指針類型數據之間作關系運算是沒有任何意義的。兩個指向同一數組中元素的指針類型之間作關系運算,可以得出它們是否指向同一個數組元素的結論。作減法運算時,可以計算出在它們所指向的這兩個數組元素之間有多少個數組元素。例如,圖6-12所示的數組i[6]在內存中存放數據的情況:(1)作關系運算兩個指針P1和P2指向同一個數組元素,P1指向數組前面的元素,P2指向數組后面的元素,則P1<P2,或者說,表達式“P1<P2”的值為1(真),而“P2<P1”的值為0(假)。注意,如果P1和P2不是指向同一數組則比較是無意義的。(2)作減法運算圖中有2個指針變量P1和P2分別指向同一個數組的不同元素,則兩個指針變量值之差是兩個指針之間的元素個數。即:P1指向i[1],P2指向i[4],則P2-P1=4-1=3,也就是說,P2-P1的值是3,即有3個元素。注意,如果P1+P2,則無實際意義。陳孟建鄒玉金熊傳光編著電子工業出版社出版3.指針類型數據之間的賦值運算指針類型數據之間的賦值運算,要求指針變量與表達式必須是同一類型。指針的類型,由以下兩個因素決定的:(1)指向不同類型數據的指針,其類型是不同的。例如:inta=2345,*P;P=&a;(將變量a的地址賦給P,*p的類型為整型)floatarray[10],*P;p=array;(將數組array首地址賦給P,*P的類型為實型)p=&array[i];(將數組array第i個元素的地址賦給P)p1=P2;(將P2的值賦給P1,P1和P2都是指針變量)(2)不同“級”的指針類型數據,其類型也是不同的。對指針類型數據最多可作的間接引用次數稱為指針數據的級。一維數組的名,是一級指針常量;二維數組的名,是二級指針常量,在類型聲明語句的變量名列表中,指針變量名前綴字符“*”的個數是指針變量的級。例如:inta,**b,***c;以上語句是聲明b是指向整型類型數據的2級指針變量,c是指向整型類型數據的3級指針變量。多級指針就是指向指針的指針,在一般情況下,多級指針的用法很少會超過2級,否則,容易造成對程序的理解錯誤,使程序難于閱讀。陳孟建鄒玉金熊傳光編著電子工業出版社出版4.指針變量空值指針變量可以有空值,即該指針變量不指向任何變量,可以有這樣的語句:P=NULL;實際上NULL是整數0,它使P的存儲單元中所有二進位均為0,也就是使P指向地址0的單元。系統保證使該單元不作其它用,即不存放任何有效的數據,有效數據的指針不指向0單元,實際上是先定義NULL,即:
#defineNULL0...P=NULL;這樣定義了一個指針為空值。應注意,P的值為NULL與未對P賦值是兩個不同的概念。前者是有值的(值為0),不指向任何變量,而后者P是未賦值并不等于P無值,只是它的值是一個不確定的值,也就是P實際上可能指向一個事先未指定的單元,這種情況是很危險的。因此,在引用指針變量之前應對它賦值。陳孟建鄒玉金熊傳光編著電子工業出版社出版五、指向指針的指針我們已經知道,一個指針變量可以指向一個類型變量的,即可以指向一個整型變量,或一個實型變量,或一個字符變量,當然,也可以指向一個指針型變量。這應該是可以理解的,因為,一個指針變量既然可以指向另一個變量,那么,被指向的變量當然可以是任一類型的,包括指針變量。定義一個指向指針的指針變量的方法如下:格式:<類型標識符>**<指針變量名>其中:①<類型標識符>指的是指向指針的指針所指向變量的類型;②**表示指向指針的指針變量標識符,該標識符的功能是該變量必須存放的是指針變量的地址值;③<指針變量名>與前相同,表示指針變量的名稱。陳孟建鄒玉金熊傳光編著電子工業出版社出版例如:int**P;該語句是定義一個指針變量P,該P是指向另一個指針變量,是一個二級指針。由于指針運算符“*”是按自右而左順序結合的,所以,以上的定義相當于:int*(*P);從這一形式可以看出,(*P)是指針變量的形式,它外面的“*”表示P指向的又是一個指針變量,int表示該指針變量指向的是整型變量,如圖6-13所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版第三節指針和數組指針和數組主要講解指針在數組中的應用,C語言中的數組的存取表面上可以使用下標的方式,實際上是使用指針的方式,指針在C語言中最大的應用就是用在數組上。數組能用指針表示盡量使用指針表示,因為,用下標方法表示的數組,當編譯時系統仍然要將它轉換成指針表示。當然,有時用指針表示不太方便的時候,仍可采用下標表示。陳孟建鄒玉金熊傳光編著電子工業出版社出版一、一維數組的指針表示1.用指針變量表示一維數組我們已知道,一個數組名代表它的起始地址。那么,數組中各元素的地址又如何計算的呢?如果有一個數組i如圖6-15所示,i的值就是數組的起始地址(設為2000),假設已定義i為實型數組,則i[0]的地址為2000,如果定義P為指針變量,那么,i[1]的地址可以用P+1表示,也就是說“P+1指向i數組的下標為1的元素”,同樣,P+a是i[a]的地址,當a的值為2時,指針P+2指向i[2]元素的地址。陳孟建鄒玉金熊傳光編著電子工業出版社出版實際地址是,P+a中的a要乘上數組元素所占的字節數,即P+a×4(實型數據所占的字節數)=2000(為P的地址)+2×4=2008。同理,P+3的地址為2012,P+4的地址為2016,以此類推……。也就是說,P+a和&i[a]是相等的,都是i[a]的地址。要注意的是:i[a]與&i[a]兩者的含義是不相同的,i[a]是i數組第a個元素的值,而&i[a]是i[a]元素的地址。所以引用數組的方法可以有以下兩種:(1)下標法:即i[a],其中a為下標。(2)地址法:即*(P+a)。陳孟建鄒玉金熊傳光編著電子工業出版社出版二、二維數組的指針表示1.用指針變量表示二維數組我們已知道,一維數組名代表了該數組的起始地址,也就是該一維數組的第一個元素的起始地址,也就是說,它是一個指向所代表的數組即指向其起始單元的指針。由于一維數組被定義后,其起始地址也就被確定了,所以數組名實際上是一個指針常數。一維數組的任何一個元素的地址,都可以用其數組名加上一個偏移量來表示。這個位移量的單位不是字節,而是數組元素的大小。如果對整型數組,則位移單位為2個字節,對實型數組,位移單位為4個字節,對字符數組,位移單位為1個字節等。下面的幾組表達式是等價的。那么對于一個二維數組來說,指針又是如何表示的呢?下面我們以一個3×4的整型數組a[3][4]為例,分析用指針指向二維數組中各元素。陳孟建鄒玉金熊傳光編著電子工業出版社出版實際上,一個二維數組就是一張二維數表,表格中的行是二維數組的第一個下標,表格中的列是二維數組的第二個下標。二維數組a[3][4]就是一張3行4列的表格,如表6-2所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版二維數組a[3][4]在內存的情況如圖6-17所示,a的值就是二維數組的起始地址(設為2020),也就是a[0][0]的地址為2020。a實際上是一個二級int型指針,其中a[i]是一個一級int型指針。由此類推,一個m維數組的數組名,對基本類型來說是一個n級指針。陳孟建鄒玉金熊傳光編著電子工業出版社出版三、指針與字符串我們已知道,字符串是存放在字符數組中的,因此,為了對字符串的操作,可以定義一個字符數組,也可以定義一個字符指針。1.用字符數組來實現2.用字符指針來實現3.應用舉例字符串指針變量的定義說明與指向字符變量的指針變量說明是相同的。只能按對指針變量的賦值不同來區別。對指向字符變量的指針變量應賦予該字符變量的地址。例如:charc,*p=&c;/*p是一個指向字符變量c的指針變量。*/char*s="CLanguage";/*s是指向字符串的指針變量,把字符串的首地址賦予s。*/
陳孟建鄒玉金熊傳光編著電子工業出版社出版四、指針數組1.什么是指針數組我們已經知道,在一個數組里,如果每個元素的類型都是整型的,則該數組稱為整型數組;如果每個元素的類型都是字符型的,則該數組稱為字符數組……。那么,如果,數組中的每個元素的類型都是指針型的,則該數組就稱為指針數組。也就是說,指針數組是用來存放一批指針即存放一批地址的。引入指針數組的目的在于使用字符串的操作,請看下面一個例子:例如,有若干個字符串需要存儲在一個數組中,按我們已學過的方法,可以使用一個字符型的一維數組來存放這個字符串,那么,如果有5個字符串,最長的字符串長度為14個字符,則應定義一個5×15的二維數組如圖6-20所示。
陳孟建鄒玉金熊傳光編著電子工業出版社出版2.指針數組定義格式:<類型標識>*<數組名>[數組長度說明]其中:(1)類型標識指的是指針數組指向的類型。(2)數組名指的是指針數組的名稱。(3)數組長度說明指的是指針數組元素的個數,它是一個選擇項,用于可根據需要進行選擇。例如:int*p[8]/*定義指向整型數據的指針數組*/char*p1[6]/*定義指向字符型數據的指針數組*/陳孟建鄒玉金熊傳光編著電子工業出版社出版第四節編譯預處理編譯預處理指的是在編譯前對源程序進行的一些預加工,預處理由編譯系統中的預處理程序按源程序中的預處理命令進行的。在C語言源程序中,除了完成程序功能的聲明語句、執行語句外,還可以使用編譯預處理命令,編譯預處理命令是以“#”標識符開始的字符,尾部不得加分號,一行不得書寫一條以上的編譯預處理命令。常用的編譯預處理命令有宏定義、文件包含等。陳孟建鄒玉金熊傳光編著電子工業出版社出版一、宏定義宏定義的一般格式為:格式:#define宏名宏體其中:宏名為標識符,宏體為一段文本。功能:預處理時,將把程序中該宏定義之后的所有宏名用宏體替換。我們以前介紹過的符號常數的定義就是這種宏定義的一種應用。例如:#definePI3.1415926這表示指定標識符PI來代替“3.1415926”這個字符串,在編譯預處理時,把程序中在該命令以后的所有PI都用“3.1415926”代替。在這里宏名就是PI,宏體就是3.1415926。陳孟建鄒玉金熊傳光編著電子工業出版社出版在使用過程中應注意以下幾個問題:(1)宏名一般習慣使用大寫的字母表示,以致與變量名相區別。(2)使用宏名代替一個字符串,可以減少程序中重復書寫某些字符串的工作量。(3)宏定義時系統不作語法檢查,也就是說不管定義的含義是否正確,一律只作簡單的置換。(4)宏定義一般須寫在程序最前面,因為它不是C語言的語句,所以宏定義未尾不加分號。(5)如果需要對已作宏定義的字符串恢復原狀,可以使用#undef命令來終止宏定義的作用域。(6)在進行宏定義時,可以引用已定義的宏名,可以層層替換。(7)在程序中只要與宏名相同的字母都作簡單的置換,但如果用雙引號括起來的則不會完成替換工作。陳孟建鄒玉金熊傳光編著電子工業出版社出版二、帶參數的宏定義有時候在宏名后面可以帶參數,其格式如下:
#define宏名(形參列表)宏體功能:在編譯預處理時,將程序中該命令后所有與宏名相同的文本用宏體進行置換,但在置換時宏體中的形參要用相應的實參置換。書寫#defin命令行時應注意的幾個問題:(1)宏名與宏體之間應以空格分隔,所以宏名中不允許含有空格。(2)宏名不允許使用引號括起來。(3)若一行內不能寫完時,可以在本尾使用反斜杠表示續行。(4)對帶參宏定義,宏體及其各個形參應該用圓括號括起來。(5)宏定義一般寫在源程序的最前面,但也可以寫在程序的任何位置處,但必須是寫在使用宏之前。(6)已定義的宏可以用命令#undef來取消。陳孟建鄒玉金熊傳光編著電子工業出版社出版三、文件包含1.文件包含格式和功能文件包含的一般格式為:格式:#include<包含文件名>或:#include“包含文件名”功能:在編譯源程序前,用包含文件的內容置換該預處理命令,也就是從磁盤按包含文件名讀取文件,然后,將它寫入到源程序中該預處理命令處,使它成為源程序中的一部分。實際上是宏定義的延伸。例如,#include“abc.c”當執行源程序后,系統將當前目錄下的abc.c程序嵌入到源程序之中,成為源程序中的一部分。以上兩種格式中,其區別在于,使用“<>”符號括起來的格式時,編譯系統將按照系統設定的標準目錄搜索該文件,使用““””符號括起來的格式時,編譯系統將首先在當前目錄中查找該文件,再按標準目錄查找直到查找到該文件為止。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.常用標準包含文件由C語言系統提供的包含文件,都以“.h”為文件的擴展名。表6-3所示的是87ANSIC(以及ISOC)中提供的15個包含文件。每個函數庫都與某個包含文件相對應。當調用標準函數庫時,應注意把相對應的包含文件用#include命令將它包含到所引用的程序中來,當然,確實不需要時,也可以不使用它,但這樣做往往是不安全的。陳孟建鄒玉金熊傳光編著電子工業出版社出版第五節文件操作一、文件概念1.C語言文件概念計算機中的任何信息資料包括系統軟件和應用軟件,都是以文件的形式儲存在磁介質的外部設備上的。例如,用計算機語言編制的程序、用戶起草的文稿、數據和其他一些信息等,都可以作為文件存儲在磁盤上。操作系統是以文件為對象對數據進行管理的,而且對文件的管理非常靈活,用戶如果想找到保存在外部磁介質上的數據,可以先按文件名找到所指定的文件,然后,再從該文件中讀取數據。當然,用戶也可以向外部磁介質上存儲數據。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.設備保留名C語言中文件名的規定與用法與DOS中文件名的規定與用法相同。DOS中除了一般文件名之外,還有專門為設備設定了保留名(這些保留名都不能用于建立文件),它們有:(1)CON,代表輸入設備的鍵盤和輸出設備的顯示器。(2)AUX或COM1,代表第一個異步通訊適配器的端口。(3)COM2,代表第二個異步通訊適配器的端口。(4)LPT1或PRN,代表第一個并行打印機。(5)LPT2和LPT3,代表第二和第三個并行打印機。(6)NUL,代表虛擬的外部設備名,用于測試運行。當作輸入設備時,立即產生文件結束,當作輸出設備時,則模擬寫操作,實際并無數據輸出。陳孟建鄒玉金熊傳光編著電子工業出版社出版3.文件的處理方法在C語言中有以下兩種對文件的處理方法:(1)緩沖文件系統,指的是系統為每一個文件自動在內存區域開辟一個緩沖區,這個區域專門為數據開辟一個臨時的過渡空間作為傳送數據的媒介。如果從內存向磁盤輸出數據,則先將數據送到內存的緩沖區,待裝滿后再一起送到磁盤去;如果從磁盤向內存讀入數據,則一次從磁盤文件將一批數據輸入到緩沖區,充滿后再從緩沖區逐個將數據送到程序數據區,如圖6-25所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版一般情況下,用緩沖區文件系統來處理文本文件,使用緩沖區文件系統的輸入輸出稱為標準輸入輸出(標準I/O)。標準的I/O提供4種讀寫文件的方法,它們是:①讀寫一個字符的方法,使用fgetc和fputc函數。②讀寫一個字符串的方法,使用fgets和fputs函數。③格式化讀寫的方法,使用fscanf和fprintf函數。④讀寫一個“記錄”(或稱為數據塊)的方法,使用fread和fwrite函數。(2)非緩沖文憑系統,指的是系統不自動開辟確定大小的緩沖區,而是由程序自己為每個文件設定緩沖區。一般情況下,用非緩沖區文件系統來處理二進制文件。使用非緩沖區文件系統的輸入輸出稱為系統級輸入輸出(系統I/O)。陳孟建鄒玉金熊傳光編著電子工業出版社出版二、文件打開與關閉1.文件打開文件的打開指的是程序把要操作的文件的一些信息通知給操作系統,使用戶的程序和操作系統之間建立一種聯系。這種聯系使操作系統知道用戶所需打開的文件名,讀數據還是寫數據等內容。如果是讀數據,則需要先確定此文件是否存在,并將讀寫當前位置設定為文件開頭;如果是寫文件,則檢查原來是否有相同的文件名,若有則將該文件刪除,然后,再新建立一個文件,如果原來無同名的文件,則將讀寫當前位置設定為文件開頭,以便從文件開頭寫入數據。格式:
fopen(文件名,文件使用方式);功能:打開一個文件名,并對該文件進行操作。陳孟建鄒玉金熊傳光編著電子工業出版社出版例如:(1)
fopen(“student”,”r”);表示需要打開的是student的文件名,對文件使用方式為“只讀方式”。(2)fopen(“st_score”,”wb”);表示需要打開的是st_score的文件名,對文件使用方式為“只寫方式”。文件的使用方式如表6-4所示。陳孟建鄒玉金熊傳光編著電子工業出版社出版從表6-4中可知,后6種方式是在前6種方式的基礎上再加一個“+”號形成的,其區別是由一個單一的讀或寫的方式擴展為又能讀又能寫的方式。例如,“r”和“r+”都是為輸入打開一個文本文件,其中“r”的使用方式是只能對該文件進行讀操作,而“r+”的使用方式是既可對該文件進行讀操作,又能對該文件進行寫操作。又如,“W”“W+”都是為輸出打開一個文本文件,其中“W”的使用方式是只能對該文件進行寫操作,而“W+”的使用方式既可對該文件進行讀操作又能對該文件進行寫操作。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.文件關閉文件關閉指的是在使用完一個文件后須將該文件關閉,以免造成數據的丟失。“關閉”就是使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過該指針對原來與其相聯系統的文件進行讀寫操作了。除非再重新打開該文件,使該指針變量重新指向該文件。格式:
fclose(文件指針變量);功能:關閉文件指針指向的文件。例如,fclose(fp);表示關閉文件,也就是通知系統,將此指針指向的文件關閉,并釋放相應的文件信息區(結構體變量)。這樣,原來的指針變量不再指向該文件,此后也就不能通過此指針來訪問該文件了。陳孟建鄒玉金熊傳光編著電子工業出版社出版三、文件順序讀寫打開一個文件以后,就可以對該文件進行讀寫操作了,常用的讀寫操作方法有以下幾種函數。1.字符輸入函數fgetc格式:ch=fgetc(fp);功能:從fp指針指向文件的當前讀寫位置讀入一個字符,并將該字符的ASCII碼值賦給變量ch。若讀到^Z,則返回EOF(即-1)。讀完一個字符后,文件的讀寫位置向后移動一個字節。2.字符輸出函數fputc格式:fputc(ch,fp);功能:在fp指針指向文件的當前讀寫位置寫入一個字符。若寫入字符成功,則函數返回值為該字符的ASCII碼值;若寫入字符不成功,則返回值為EOF。寫完一個字符后,文件的讀寫位置向后移動一個字節。陳孟建鄒玉金熊傳光編著電子工業出版社出版3.字符串輸入函數fgets格式:fgets(str,n,fp);功能:從fp指針指向的文件讀取n-1個字符,并把它放到字符數組str中,在str數組最后自動加一個“\0”結束標志符。如果讀入n-1個字符完成之前遇到換行符“\n”或文件結束符EOF,即結束讀入。函數的返回值為str首地址或NULL。4.字符串輸出函數fputs格式:fputs(str,fp);功能:在fp指針指向的文件寫入一個字符串str(不包括字符串結束標志“\0”)。函數的返回值為所輸出末字符的ASCII碼,若向文件輸出的字符串不成功,則函數的返回值為0。向文件輸出字符串后,文件讀寫位置移動到所寫入的字符串之后。陳孟建鄒玉金熊傳光編著電子工業出版社出版四、數據塊讀寫函數1.讀數據塊函數格式:fread(buffer,size,count,fp);其中:buffer是一個指針,它是讀入數據的存放地址。size是要讀取的字節數。count是要進行讀取多少個size字節的數據項。fp是文件型指針。功能:從fp指針指向的文件中讀取count個size字節的數據項,并存放在buffer地址中。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.寫數據塊函數格式:fwrite(buffer,size,count,fp);其中:buffer是一個指針,它是寫入數據的存放地址。size是要讀取的字節數。count是要進行寫入多少個size字節的數據項。fp是文件型指針。功能:在fp指針指向的文件中寫入count個size字節的數據項,并存放在buffer地址中。如果文件是以二進制形式打開的,則以上兩個函數可以讀寫任何類型的信息,例如:(1)fread(f,4,2,fp);則表示從fp所指向的文件中讀入2次(每次4個字節)數據,存儲到數組f中。陳孟建鄒玉金熊傳光編著電子工業出版社出版(2)如果有一個如下的結構類型:
struct
student_type{charname[10];intnum;intage;charaddr[30];}stu[40];結構體數組stu有40個元素,每一個元素用來存放一個學生的數據(包括姓名、學號、年齡、地址)。假設學生的數據已存放在磁盤文件中,可以用下面的語句讀入40個學生的信息。
for(i=0;i<40;i++)
fread(&stu[i],sizeof(structstudent_type),1,fp);同樣,也可以使用以下語句將內存中的學生數據輸出到磁盤文件中去。
for(i=0;i<40;i++)
fwrite(&stu[i],sizeof(structstudent_type),1,fp);如果fread或fwrite調用成功,則函數返回值為count的值,即輸入或輸出數據的完整個數。陳孟建鄒玉金熊傳光編著電子工業出版社出版五、文件隨機讀寫1.文件的定位要對文件進行隨機讀寫操作,必須先確定文件的記錄指針,文件的記錄指針確定可以使用fseek函數來達到。(1)fseek函數格式:fseek(文件類型指針,位移量,起始點);其中:“超始點”指的是以什么地方為基準進行移動,一般是使用數字來代表的。①數字0表示文件開始處。②數字1表示文件位置指針的當前指向。③數字2表示文件末尾。“位移量”指的是以“起始點”為基點向前移動的字節數。如果它的值為負數,則表示向后移動,反之表示從文件開頭向文件末尾移動的方向。位移量的數據類型為loong型,這樣當文件長度很長時,位移量仍在loong型數據表示范圍之內。功能:將位置指針以起始點為基準開始,移動到位移量所表示的位置處。例如:fseek(fp,10L,0);/*將位置指針移動到離文件開始處10個字節處。*/fseek(fp,-20L,1);/*將位置指針從當前位置向后移動20個字節*/fseek(fp,-50L,2);/*將位置指針從文件末尾后移50個字節。*/有了fseek函數后,就可以隨機讀寫磁盤文件中的信息了。陳孟建鄒玉金熊傳光編著電子工業出版社出版(2)ftell函數格式:i=ftell(fp);功能:返回磁盤文件的當前位置的指向。如果ftell(fp)返回值為-1則表示出錯(例如不存在此文件等)。例如,i=ftell(fp);/*將fp指針指向的文件中位置指針的當前指向賦給i*/if(i==-1L)/*判斷i的值是否為-1*/
printf(“出錯\n”);/*如果是-1,則表示出錯了*/(3)rewind函數格式:rewind(fp);功能:使用位置指針重新返回到文件的開頭處,此函數無返回值。陳孟建鄒玉金熊傳光編著電子工業出版社出版2.文件的出錯檢測在大多數的C語言系統中,都沒有具有明確的出錯信息返回,因此,在調試程序過程中,需要使用一些檢查文件出錯的函數來人為地進行檢測,從而使程序的調試工作做到心中有數,不致于化很多的精力去檢查那些低級錯誤
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 混凝土培訓課件-地鐵
- 《時尚尖端展示畫卷》課件
- 愛崗敬業奉獻教師演講稿(16篇)
- 離婚財產分割不公平上訴狀(3篇)
- 銷售人員辭職報告(27篇)
- 公司職責培訓心得體會(20篇)
- 酒店營銷重點工作計劃(15篇)
- 2025小學師德師風心得體會(17篇)
- 深交所培訓課件下載
- 《助力學生成長:課件制作與教學應用》
- 新視野大學英語(第四版)讀寫教程2(思政智慧版) 教案 Unit 5 Striving for financial health
- 幼兒園獲獎公開課:大班科學活動《茶》課件
- GB/T 34571-2024軌道交通機車車輛布線規則
- 認知與實踐:AI技術在高校圖書館應用現狀調研分析
- 護理行政查房內容
- 沙灘車租賃合同
- 《用戶體驗人員技術能力等級評價》編制說明
- 2025年中國盲盒行業研究報告:市場規模、供需態勢、發展前景預測
- 2025年臨床醫師定期考核必考復習題庫及答案(970題)
- 《材料科學基礎》課程教學大綱
- 班委工作職責一覽表
評論
0/150
提交評論