C程序設計讀書筆記_第1頁
C程序設計讀書筆記_第2頁
C程序設計讀書筆記_第3頁
C程序設計讀書筆記_第4頁
C程序設計讀書筆記_第5頁
已閱讀5頁,還剩15頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、C程序設計讀書筆記關鍵字:c語言原作者姓名:loose_went寫在前面:C程序設計可以說是一本再基礎不過的編程書了,但每讀一遍的感覺卻都是不同的,可以說,每讀一遍,都會有很多新的收獲。真所謂老書再讀,回味無窮啊!此筆記是C程序設計譚浩強編著,清華大學出版社出版。除了將書中的重點知識點記下來外,也加入了我對知識點的理解,我想這一點是讀書筆記的重要性所在。 第一章概述第二章數據類型、運算符與表達式第三章最簡單的程序設計第四章邏輯運算和判斷選取控制第五章循環控制第六章數組第七章函數第八章預編譯處理第九章指針第十章結構體與共用體第十一章位運算第十二章文件第一章概述1 C語言的特點語言簡潔、緊湊,使用

2、方便、靈活。共有個關鍵字,種控制語句。運算符豐富,公有種運算符。數據結構豐富,數據類型有:整型、實型、字符型、數組、指針、結構體、共用體等。具有結構化的控制語句(如ifelse、while、dowhile、switch、for)語法限制不太嚴格,程序設計自由度大。允許直接訪問物理地址,能進行位(bit)操作,可以直接對硬件操作。生成目標代碼質量高,程序執行效率高。可移植性好。 2 C語言的用途C雖不擅長科學計算和管理領域,但對操作系統和系統實用程序以及對硬件進行操作方面,C有明顯的優勢。現在很多大型應用軟件也用編寫。Top of Page第二章數據類型、運算符與表達式1 C的數據類型C的數據類

3、型包括:整型、字符型、實型或浮點型(單精度和雙精度)、枚舉類型、數組類型、結構體類型、共用體類型、指針類型和空類型。2 常量與變量常量其值不可改變,符號常量名通常用大寫。變量其值可以改變,變量名只能由字母、數字和下劃線組成,且第一個字符必須為字母或下劃線。否則為不合法的變量名。變量在編譯時為其分配相應存儲單元。3 整型數據整型常量的表示方法:十進制不用說了,八進制以0開頭,如0123,十六進制以0x開頭,如0x1e。整型變量分為:基本型(int)、短整型(short int)、長整型(long int)和無符號型。不同機器上各類數據所占內存字節數不同,一般int型為個字節,long型為4個字節

4、。4 實型數據實型常量表示形式:十進制形式由數字和小數點組成(必須有小數點),如:0.12、.123、123.、0.0等。指數形式如123e3代表123×10的三次方。實型變量分為單精度(float)和雙精度(double)兩類。在一般系統中float型占4字節,7位有效數字,double型占8字節,1516位有效數字。5 字符型數據字符變量用單引號括起來,如'a','b'等。還有一些是特殊的字符常量,如'n','t'等。分別代表換行和橫向跳格。字符變量以char 來定義,一個變量只能存放一個字符常量。 字符串常量是由雙

5、引號括起來的字符序列。這里一定要注意'a'和"a"的不同,前者為字符常量,后者為字符串常量,c規定:每個字符串的結尾加一個結束標志'0',實際上"a"包含兩個字符:'a'和'0'。6 數值型數據間的混合運算整型、字符型、實型數據間可以混合運算,運算時不同類型數據要轉換成同一類型再運算,轉換規則:char,short -> int -> unsigned -> long -> double <- float7 運算符和表達式c運算符包括:算數運算符(+-*/%)關

6、系運算符( > < = >= <= != )邏輯運算符( ! && | )位運算符( << >> | & )賦值運算符(= )條件運算符(? : )逗號運算符( , )指針運算符( * & )求字節數( sizeof )強制類型轉換(類型)分量運算符(. -> )下標運算符( )其它運算符(如函數調用運算符( ) )自增自減運算符(+ - )注意:+i和i+的不同之處,+i使用i之前先使i加,i+使用i之后,使i加。逗號表達式的求解過程:先求解表達式,再求解表達式,整個表達式的值是表達式的值。Top of P

7、age第三章 最簡單的程序設計c的種控制語句:if() elsefor()while()dowhile()continuebreakswitchgotoreturn程序的三種基本結構:順序結構,選擇結構,循環結構 數據輸出c語言不提供輸入輸出語句,輸入輸出操作是由c的庫函數完成。但要包含頭文件stdio.h。putchar( ) 向終端輸出一個字符printf( )的格式字符: d格式符用來輸出十進制整數%d 按整型數據的實際長度輸出%md 使輸出長度為m,如果數據長度小于m,則左補空格,如果大于m,則輸出實際長度%ld 輸出長整型數據 o格式符以八進制形式輸出整數 x格式符以十六進制形式輸出

8、整數 u格式符用來輸出unsigned型數據,以十進制形式輸出 c格式符用來輸出一個字符 s格式符輸出一個字符串%s輸出實際長度字符串%ms 輸出的串占m列,如果串長度小于m,左補空格,如果大于m,實際輸出%-ms輸出的串占m列,如果串長度小于m,右補空格,%m.ns 輸出占m列,但只取字符串中左端n個字符并靠右對齊%-m.ns m、n含義同上,靠左對齊,如果n>m,則m自動取n值 f格式符以小數形式輸出實數%f 整數部分全部輸出,小數部分輸出6位%m.nf 輸出數據共占m列,其中有n位小數。如果數值長度小于m,左補空格 %-m.nf 同上,右補空格 e格式符以指數形式輸出實數%e 系統

9、指定位小數,5位指數(e+002 ) g格式符輸出實數,根據數值大小,自動選f格式或e格式3數據輸入getchar( ) 從終端輸入一個字符scanf( 格式控制,地址列表) 標準C scanf中不使用%u,對于unsigned型數據,以%d或%o或%x輸入。后的*,用來跳過它相應的數據。輸入數據時不能規定精度如scanf( "%7.2f", &a );是不合法的。Top of Page第四章 邏輯運算和判斷選取控制1 關系運算符:c提供種關系運算符(> < <= >= = != )前四種優先級高于后兩種。2 If語句C提供了三種形式的if語

10、句If(表達式) 語句If(表達式) 語句1 else 語句2If(表達式1) 語句1Else if(表達式2) 語句2else 語句n3 條件運算符(a>b)?a:b 條件為真,表達式取值a,否則取值b4 Switch語句Switch(表達式)case 常量表達式:語句; break;case 常量表達式:語句2; break; case 常量表達式n:語句; break;default :語句; Top of Page第五章 循環控制1 幾種循環語句goto語句(現已很少使用)while語句先判斷表達式后執行語句do-while語句先執行語句后判斷表達式for語句2 Break語句和

11、continue語句Break語句用于跳出循環,continue用于結束本次循環。Top of Page第六章 數組1 一維數組c規定只有靜態存儲(static)和外部存儲(extern)數組才能初始化。給數組初始化時可以不指定數組長度。2 二維數組3 字符數組部分字符串處理函數puts(字符數組)將一個字符串輸出到終端。gets(字符數組) 從終端輸入一個字符串到字符數組,并且得到一個函數值,為該字符數組的首地址strcat(字符數組,字符數組2)連接兩個字符數組中的字符串,數組1必須足夠大。Strcpy(字符數組,字符串2)將字符串拷貝到字符數組中。Strcmp(字符串1,字符串2) 比較

12、字符串,相等返回0,字符串>字符串2,返回正數,小于返回負數。 Strlen(字符數組) 求字符串長度。Strlwr( 字符串)將字符串中的大寫字母轉換成小寫Strupr( 字符串) 將字符串中的小寫字母轉換成大寫以上是一些比較常用的字符串處理函數。Top of Page第七章 函數1 關于形參和實參的說明 在函數被調用之前,形參不占內存 實參可以是常量、變量或表達式 必須指定形參的類型 實參與形參類型應一致 實參對形參的數據傳遞是"值傳遞",即單向傳遞2 函數返回值如果想讓函數返回一個值,在函數中就要用return語句來獲得,在定義函數時也要對函數值指定類型,如果不

13、指定,默認返回整型。3 函數調用1)注意在函數調用時實參和形參的個數、類型應一一對應。對實參表求值的順序是不確定的,有的系統按自左至右,有的系統則按自右至左的順序。這一點要注意。2)函數調用的方式:函數語句,函數表達式,函數參數 3)如果主調函數和被調函數在同一文件中,并且主調函數在前,那么一般要在主調函數中對被調函數進行說明。除非:(1)被調函數的返回值類型為整型或字符型(2)被調函數出現在主調函數之前。4)對函數的說明和定義是不同的,定義是指對函數功能的確立,包括指定函數名,函數值類型,形參及其類型、函數體等。說明則只是對已定義的函數返回值類型進行說明,只包括函數名、函數類型以及一個空的括

14、弧,不包括形參和函數體。5)c語言允許函數的遞歸調用(在調用一個函數的過程中又出現直接或間接的調用該函數本身)。4 數組作為函數參數1)數組元素作為函數參數和一般變量相同2)數組名作參數應該在主調和被調函數分別定義數組,形參數組的大小可以不定義。注意:數組名作參數,不是單向傳遞。3)多維數組作參數,在被調函數中對形參數組定義時可以省略第一維的大小說明,但不能省略第二維或更高維的說明。5 局部變量和全局變量從變量作用域角度分,變量可分為局部變量和全局變量。1)內部變量(局部變量)在一個函數內定義,只在函數范圍內有效的變量。 2)外部變量(全局變量)在函數外定義,可以為本文件其它函數所共用,有效范

15、圍從定義變量的位置開始到本文件結束。建議盡量少使用全局變量,因為它在程序全部執行過程中都占用資源,而且使函數的通用性降低了。如果在定義外部變量之前的函數要想使用該外部變量,則應在該函數中用extern作外部變量說明。6 動態存儲變量與靜態存儲變量從變量值存在的時間(生存期)角度來分,可分為靜態存儲變量和動態存儲變量。靜態存儲指在程序運行期間給變量分配固定的存儲空間,動態存儲指程序運行期間根據需要動態的給變量分配存儲空間。C語言中,變量的存儲方法分為兩大類:靜態存儲類和動態存儲類,具體包括:自動的(auto),靜態的(static),寄存器的(register),外部的(extern)。1) 局

16、部變量的存儲方式函數中的局部變量如不作專門說明,都之auto的,即動態存儲的,auto可以省略。局部變量也可以定義為static的,這時它在函數內值是不變的。靜態局部變量如不賦初值,編譯時系統自動賦值為,動態局部變量如不賦初值,則它的值是個不確定的值。C規定,只有在定義全局變量和局部靜態變量時才能對數組賦初值。為提高執行效率,c允許將局部變量值放在寄存器中,這種變量叫register變量,要用register說明。但只有局部動態變量和形式參數可以作為register變量,其它不行。2) 全局變量的存儲方式全局變量在函數外部定義,編譯時分配在靜態存儲區,可以在程序中各個函數所引用。多個文件的情況

17、如何引用全局變量呢?假如在一個文件定義全局變量,在別的文件引用,就要在此文件中用extern對全局變量說明,但如果全局變量定義時用static的話,此全局變量就只能在本文件中引用了,而不能被其它文件引用。3) 存儲類別小結從作用域角度分,有局部變量和全局變量局部變量:自動變量,即動態局部變量(離開函數,值就消失)靜態局部變量(離開函數,值仍保留)寄存器變量(離開函數,值就消失)(形參可定義為自動變量和寄存器變量)全局變量:靜態全局變量(只限本文件引用)全局變量(允許其它文件引用)從存在的時間分,有靜態存儲和動態存儲動態存儲:自動變量(本函數內有效)寄存器變量(本函數內有效)形參靜態存儲:靜態局

18、部變量(函數內有效)靜態全局變量(本文件內有效)全局變量(其它文件可引用)從變量值存放的位置分靜態存儲區:靜態局部變量靜態全局變量全局變量動態存儲區:自動變量和形參寄存器內:寄存器變量7 內部函數和外部函數 內部函數:只能被本文件中的其它函數調用,定義時前加static,內部函數又稱靜態函數。外部函數:可以被其它文件調用,定義時前加extern,如果省略,則隱含為外部函數,在需要調用此函數的文件中,一般要用extern說明。Top of Page第八章 預編譯處理c編譯系統在對程序進行通常的編譯之前,先進行預處理。c提供的預處理功能主要有以下三種:1)宏定義2)文件包含3)條件編譯1 宏定義不

19、帶參數的宏定義用一個指定的標識符來代表一個字符串,形式:#define 標識符 字符串幾點說明:) 宏名一般用大寫) 宏定義不作語法檢查,只有在編譯被宏展開后的源程序時才會報錯) 宏定義不是c語句,不在行末加分號) 宏名有效范圍為定義到本源文件結束) 可以用#undef命令終止宏定義的作用域) 在宏定義時,可以引用已定義的宏名帶參數的宏定義定義形式:#define 宏名(參數表)字符串 這和函數有些類似,但他們是不同的:) 函數調用時,先求實參表達式值,再代入形參,而宏只是簡單替換,并不求值) 函數調用是在程序運行時分配內存的,而宏展開時并不分配內存,也沒有返回值的概念) 對函數中的實參和形參

20、都要定義類型,而且要求一致,宏名無類型,其參數也沒有類型。) 函數只有一個返回值,而宏可以得到幾個結果) 宏替換不占運行時間,只占編譯時間,而函數調用占運行時間2 文件包含處理#include "文件1" 就是將文件1的全部內容復制插入到#include位置,作為一個源文件進行編譯。在#include命令中,文件名可以用" "也可以用< >,假如現在file1.c中包含file2.h文件," "表示系統先在file1.c所在目錄中找file2.h,如果找不到,再按系統指定的標準方式檢索目錄,< >表示系統直接按

21、指定的標準方式檢索目錄。所以用" "保險一點。3 條件編譯條件編譯指不對整個程序都編譯,而是編譯滿足條件的那部分。條件編譯有以下幾種形式:1)#ifdef 標識符 程序段 #else程序段#endif它的作用:當標識符在前面已經被定義過(一般用#define),則對程序段編譯,否則對程序段編譯。)#ifndef 標識符程序段#else程序段#endif它的作用和#ifdef相反,當標識符沒被定義過,對程序段編譯,否則對程序段編譯。)#if 表達式程序段#else程序段#endif它的作用:當表達式值為真(非)時,對程序段編譯,否則對程序段編譯。Top of Page第九章

22、指針指針說白了就是地址。指針變量就是用來存放指針(地址)的變量。1 變量的指針和指向變量的指針變量讀起來很拗口,說白了就是變量的地址和用來存放變量地址的地址變量。因為一個變量在編譯的時候系統要為它分配一個地址,假如再用一個變量來存放這個地址,那么這個變量就叫做指向變量的指針變量,也就是用來存放變量地址的這么一個變量。所謂"指向"就是指存放××的地址,如指向變量的指針變量,"指向"就是指用來存放變量的地址,再如指向數組的指針變量,"指向"就是指存放數組的地址。只要理解了這個,指針也就不難了。另外,還有指向字符串的指針

23、變量,指向函數的指針變量,指向指針的指針變量等。1) 指針變量的定義形式:類型標識符*標識符如:int *pointer;要注意兩點:*表示pointer是個指針變量,在用這個變量的時候不能寫成*pointer, *pointer是pointer指向的變量。一個指針變量只能指向同一個類型的變量。如上面pointer只能指向int型變量。2)指針變量的引用兩個有關的運算符:& 取地址運算符 &a 就代表變量a的地址* 指針運算符*a就代表變量a的值2 數組的指針和指向數組的指針變量數組的指針指數組的起始地址,數組元素的指針指數組元素的地址。 1)指向數組元素的指針變量的定義與賦值

24、定義和指向變量的指針變量定義相同,c規定數組名代表數組的首地址,即第一個數組元素地址。2)通過指針引用數組元素我們通常引用數組元素的形式是ai,如果用指針可以這樣引用,*(a+i),或定義一個指針變量p,將數組a的首地址賦給p,p=a;然后用*(p+i)引用。注意:指針變量指向數組a首地址,則p+指向數組的下一元素地址,即a1的地址。3)數組名作函數參數形參數組和實參數組之間并不是值傳遞,而是共用同一段地址,所以在函數調用過程中如果形參的值發生變化,則實參的值也跟著變化。4)指向多維數組的指針和指針變量 以二維數組為居多。假設定義了一個二維數組a34,那么a代表整個二維數組的首地址,也代表第0

25、行的首地址,同時也是第0行第0列的元素的首地址。a +0和a0代表第0行首地址,a+1和a1代表第一行的首地址。假設a是一個數組的首地址,那么如果a是一維的,a+I代表第I個元素的地址,如果a是二維的,則a+I代表第I行的首地址。那么第一行第二列的元素地址如何表示呢?a1+2或&a12或*(a+1)+2。我們只要記住:在二維數組中a代表整個數組的首地址,aI代表第I行的首地址,aI與*(a+I)等價就行了。只要運用熟練了就沒什么復雜的了。 5)指向由m個整數組成的一維數組的指針變量如:int (*p)4,p是一個指向包含4個元素的一維數組,如果p先指向a0,則p+1指向a1,即p的增值

26、是以一維數組的長度為單位的,這里是4,舉個例子:假設a34=1,3,5,7,9,11,13,15,17,19,21,23,p先指向a0也就是數組a的首地址,那么p+1就是a1的首地址即元素9的地址,因為在定義p時int (*p)4,定義一維數組長度為4,所以p+1就等于加了一個一維數組的長度4。3 字符串的指針和指向字符串的指針變量1)字符串的表示形式c中字符串有兩種表示形式:一種是數組,一種是字符指針 char string="I love c!"char *str="I love c!"其實指針形式也是在內存中開辟了一個數組,只不過數組的首地址存放在

27、字符指針變量str中,千萬不要認為str是一個字符串變量。2)字符串指針作函數參數實際上字符串指針就是數組的首地址。3)字符指針變量與字符數組的區別 字符數組由若干元素組成,每個元素存放一個字符,而字符指針變量只存放字符串的首地址,不是整個字符串 對數組初始化要用static,對指針變量不用。 對字符數組賦值,只能對各個元素賦值,不能象下面這樣:char str14;str="I love c!"對指針變量可以, char *str;str="I love c!"注意:此時賦給str的不是字符,而是字符串首地址。 數組在定義和編譯時分配內存單元,而指針變

28、量定義后最好將其初始化,否則指針變量的值會指向一個不確定的內存段,將會破壞程序。如: char *a;scanf( "%s", a );這種方法是很危險的,應該這樣:char *a, str10;a = str;scanf( "%s", a );這樣字符指針就指向了一個確定的內存段。 指針變量的值是可以改變的,而字符數組名所代表的字符串首地址卻是不能改變的。4 函數的指針和指向函數的指針變量一個函數在編譯時被分配一個入口地址,這個入口地址就稱為函數的指針。函數名代表函數的入口地址,這一點和數組一樣。我們可以用一個指針變量來存放這個入口地址,然后通過該指針

29、變量調用函數。如:假設有一個求兩者較大的函數如下:int max( int x, int y );當我們調用這個函數時可以這樣:int c;c=max( a, b );這是通常調用方法,其實我們可以定義一個函數指針,通過指針來調用,如:int (*p)(); /注意指向函數指針變量的定義形式p=max; /此句就是將函數的入口地址賦給函數指針變量pc=(*p)( a, b );有些朋友可能對(*p)()不大理解,其實它的意思就是定義一個指向函數的指針變量p,p不是固定指向哪個函數的,而是專門用來存放函數入口地址的變量。在程序中把哪個函數的入口地址賦給它,它就指向哪個函數。但要注意,p不能象指向

30、變量的指針變量一樣進行p+,p-等無意義的操作。既然p是一個指針變量,那么就可以作為函數的參數進行傳遞。其實函數的指針變量最常用的用途之一就是作為函數參數傳遞到其它函數。這也是c語言中應用的比較深入的部分了。5 返回指針值的函數我們知道,一個函數可以帶回一個整型值、字符值、實型值等,函數還可以帶回一個指針型的數據,即地址。這種函數的定義形式如下:類型標識符 *函數名(參數表) 如:int *a(x,y)返回一個指向整型的指針使用這種函數的時候要注意:在調用時要先定義一個適當的指針來接收函數的返回值。這個適當的指針其類型應為函數返回指針所指向的類型。這樣的函數比較難于理解,其實只要把它當做一般的

31、函數來處理就容易了。當我們覺得指針難于理解的時候,就把它暫時當做整型來看,就好理解多了。6 指針數組指針數組無疑就是數組元素為指針,定義形式為: 類型標識*數組名數組長度如:int *p4,千萬不要寫成int (*p)4,這是指向一維數組的指針變量。指針數組多用于存放若干個字符串的首地址,注意一點,在定義指針數組時初始化,如下: static char *name="Li jing","Wang mi","Xu shang"不要以為數組中存放的是字符串,它存放的是字符串首地址,這一點一定要注意。7 指向指針的指針說的明白一點,將一個指

32、針再用一個變量來存放,那么這個變量就是指向指針的指針。定義如:char * *p;8 指針數組作main()函數的參數函數形式為main( int argc, char *argv )main函數的參數是從命令行得到的,argc指命令行參數個數,注意命令名也算一個參數,命令行參數都是字符串,他們的首地址構成一個指針數組argv。Main函數的形參用argc和argv只是一個習慣,也可以定義成別的名字。9 指針小結1)有關指針的數據類型定義含義Int I;定義一個整型變量IInt *p;P為指向整型數據的指針變量Int an;定義整型數組a,它有n個元素Int *pn;定義指針數組p,它有n個指

33、向整型的指針元素Int (*p)n;P為指向含有n個元素的一維數組的指針變量Int f();F為返回整型值的函數Int *p();P為返回值為指針的函數,該指針指向整型數據Int (*p)();P為指向函數的指針,該函數返回一個整型值Int *p;定義一個指向指針的指針變量2)ANSI新增了一種void *指針類型,即定義一個指針變量,但不指向任何數據類型,等用到的時候再強制轉換類型。如: char *p1;void *p2;p1 = (char *)p2;也可以將一個函數定義成void *型,如:void *fun( ch1, ch2 )表示函數fun返回一個地址,它指向空類型,如果需要用到

34、此地址,也要對其強制轉換。如(假設p1為char型):p1=(char *)fun( c1,c2 );指針應該說是c語言中比較重要的概念,也是c語言的精華,它有很多優點,但用不好也會帶來嚴重性的錯誤,這就需要我們多用,多練,慢慢的積累經驗。Top of Page第十章 結構體與共用體1 定義結構體定義的一般形式:struct 結構體名成員列表;定義一個結構體變量可以這樣定義:struct 結構體名 結構體變量名;2 結構體變量的引用在引用結構體變量時應注意以下規則:1)不能將結構體變量作為一個整體輸入輸出,只能對變量當中的各個成員輸入輸出。新標準C允許將一個結構體變量直接賦值給另一個具有相同結

35、構的結構體變量。3 結構體變量的初始化如:struct studentlong int num;char name20;char sex;char addr20;a=89031,"Li Lin",'M',"123 Beijing Road" ;4 結構體數組struct student stu4;定義了一個數組stu,其元素為struct student類型,數組有4個元素。注意數組各元素在內存中是連續存放的。在定義結構體數組時,數組元素個數可以不指定。編譯時,系統會根據給出初值的結構體常量的個數來確定數組元素的個數。5 指向結構體變量的

36、指針因為結構體變量在內存中是連續存放各成員的,因此我們可以將結構體變量在內存中的起始地址存放到一個變量中,那么這個變量就是指向結構體變量的指針。注意將結構體變量的首地址賦給指針變量的形式:struct student stu_1;struct student *p;p=&stu_1; /要加取地址符而指向函數和指向字符串的指針不用在對引用結構體變量中的成員時,有三種方式:以上面的結構體為例:設p為指向此結構體變量的指針,即p=&a;1) a.num2) (*p).num3) p->num6 指向結構體數組的指針struct student *p;struct studen

37、t stu4;p=stu;則p為指向結構體數組的指針變量。這里應注意p+,p指向stu0,p+則指向stu1。P指向的是數組中一個元素的首地址,而不能讓p指向元素中的某一成員,如p=&stuI.name是不對的。7 用指向結構體的指針作函數參數雖然ANSI C允許用整個結構體作為函數參數,但要將全部成員值一個一個傳遞,開銷大。所以用指針作參數,能提高運行效率。 Struct student stu;用整個結構體作為參數調用形式:fun( stu );而且被調函數fun中也要定義成結構體變量,struct student stu;用指針作參數調用形式:fun( &stu );被調

38、函數fun中定義成指針變量,struct student *p;8 用指針處理鏈表鏈表是一種重要的數據結構,原因就在于它可以動態的進行存儲分配。鏈表都有一個頭指針,用來存放整個鏈表的首地址。鏈表的定義形式如下:struct nodeint num;struct node *next;next用來存放下一節點的地址。如何進行動態的開辟和釋放存儲單元呢?c提供了以下有關函數:1) malloc(size) 在內存的動態存儲區開辟一個長度為size的連續空間。成功返回空間首地址,失敗返回0;2) calloc(n,size) 在內存的動態存儲區開辟n個長度為size的連續空間。成功返回空間首地址,失

39、敗返回0;3) free(ptr) 釋放由ptr指向的內存區。Ptr是最近調用一次調用malloc和calloc時返回的值。 上面函數中,n和size為整型,ptr為字符指針。9 共用體定義形式:union 共用體名成員列表變量列表;共用體和結構體類似,只是有一點不同,結構體中個成員的起始地址不同,結構體變量在內存中的長度為各成員長度之和;而共用體中個成員的起始地址相同,共用體變量所占的內存長度為最長的成員的長度。 共用體類型數據的特點:1) 同一個內存段可以存放幾種不同類型的成員2) 共用體變量中起作用的成員是最后一次存放的成員3) 不能對共用體變量名賦值,不能在定義時初始化。4) 不能把共

40、用體變量作為函數參數5) 共用體類型可以出現在結構體定義中,反之也可,也可以定義共用體數組。 另外,結構體名可以作為參數,而共用體名不可以。這兩中數據結構在不同場合中各有所用。10 枚舉類型定義形式如下:舉個例子enum weekdaysun,mon,tue,wed,thu,fri,sat;enum weekday workday,week_end; /定義枚舉變量workday和week_end被定義成枚舉類型,他們的值只能為sun到sat之一。也可以直接定義枚舉變量,這一點與結構體相同enum weekdaysun,mon,tue,wed,thu,fri,satwordday,week_e

41、nd;注意:枚舉元素是作為常量存在的,他們是有值的,c在編譯時使他們的值按順序為0,1,2如:上面的定義中,sun的值為0,mon的值為1另外:雖然枚舉元素有值,但不能將一個整數直接賦給一個枚舉變量。應進行強制類型轉換,如:workday=(enum weekday)2;它相當于把tue賦給了workday。11 用typedef定義類型typedef的作用就是能夠讓你定義一個自己喜歡的數據類型名來代替已有的數據類型名。如:typedef int INT;那么我就可以用INT來定義整型變量了。作用和int一樣。Typedef用于結構體定義,如:Typedef structInt day;Int

42、 month;Int year;DATE;DATE birthday;DATE *p;等等用typedef有利于程序的通用與移植。Top of Page第十一章 位運算1)概述所謂位運算是指進行二進制位的運算。在系統軟件中,常要處理二進制位的問題。c提供的位運算符有:& 按位與| 按位或 按位異或 取反<< 左移>> 右移&對于將一個單元清零、取一個數中的某些指定位以及保留指定位有很大用途。|常被用來將一個數的某些位置1。判斷兩個位值,不同為1,相同為0。常用來使特定位翻轉等。常用來配合其它位運算符使用的,常用來設置屏蔽字。<<將一個數的各二

43、進制位全部左移,高位左移后溢出,舍棄不起作用。左移一位相當于該數乘2,左移n位相當于乘2n。左移比乘法運算要快的多。>>右移時,要注意符號問題。對無符號數,右移時左邊高位移入0,對于有符號數,如果原來符號位為0(正數),則左邊移入0;如果符號位為1(負數),則左邊移入還是要取決于系統。移入的稱為"邏輯右移",移入的稱為"算數右移"。2)位段將一個字節分為幾段來存放幾個信息。所謂位段是以位為單位定義長度的結構體類型中的成員。如:struct packed-dataunsigned a:2; unsigned b:6;unsigned c:4;u

44、nsigned d:4;int I;data;其中a,b,c,d分別占2位,6位,4位,4位。I為整型,占4 個字節。對于位段成員的引用如下:data.a = 2;等,但要注意賦值時,不要超出位段定義的范圍。如位段成員a定義為2位,最大值為3,即(11)2,所以data.a=5;就會取5的兩個低位進行賦值,就得不到想要的值了。關于位段的定義和引用,有幾點重要說明:若某一個段要從另一個字開始存放,可以定義:unsigned a:1;unsigned b:2;unsigned :0;unsigned c:3; (另一單元)使用長度為0的位段,作用就是使下一個位段從下一個存儲單元開始存放。一個位段必

45、須存放在用一個存儲單元中,不能跨兩個單元。可以定義無名位段。如:unsigned a:1;unsigned :2; (這兩位空間不用)unsigned b:3;位段的長度不能大于存儲單元的長度,也不能定義位段數組。 Top of Page第十二章 文件1) 概述c語言將文件看成一個字符的序列,分為ASCII文件(文本文件)和二進制文件。即一個c文件就是一個字節流或二進制流。ASCII文件每一個字節放一個ASCII碼,代表一個字符,輸出與字符一一對應,便于逐個處理字符,但占用空間較多。二進制文件按內存中的存儲形式原樣輸出到磁盤上,節省空間,由于輸出與字符不對應,不能直接輸出字符形式,一般用于保存

46、中間結果。目前c對文件的處理只有緩沖文件系統一種方法,即無論是從程序到磁盤文件還是從磁盤文件到程序,數據都要先經過緩沖區,待緩沖區充滿后,才集中發送。2) 文件夾類型指針在緩沖文件系統中,關鍵的概念是文件指針。因為每個被使用的文件都在內存中開辟一個緩沖區,來存放文件有關信息。這些信息保存在一個結構體變量中,該結構體類型是由系統定義的,取名為FILE,在stdio.h中定義。FILE *fp;定義了一個文件指針變量fp,以后對文件的操作都是通過fp進行的。3) 文件的打開與關閉在對文件讀寫之前,要先打開文件。打開文件的函數為:fopen(),調用方式為:FILE *fp;fp=fopen( fi

47、lename,使用文件方式 );fopen()失敗返回一個空指針NULL,成功則返回一個指向"filename"的文件指針,賦給fp,這樣fp就和打開的文件聯系在一起了。或者說,fp指向了"filename"。文件使用方式:r,w,a,rb,wb,ab,r+,w+,a+,rb+,wb+,ab+,具體含義要記住。4)文件的關閉為了防止數據丟失,程序結束前,務必將打開的文件關閉,即將文件指針與文件脫鉤。用fclose(文件指針)函數關閉文件,執行函數后,先將緩沖區中的數據送到磁盤文件,然后釋放文件指針。成功返回0,失敗返回非0。5)文件的讀寫文件打開后,就可以對其讀寫了,常用的文件讀寫函數有:fputc和fgetcfputc將一個字符寫到文件,形式為fputc( ch,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論