《C語言(第三版)》 課件 項目3、4 掌握 C 語言、應用 C 語言_第1頁
《C語言(第三版)》 課件 項目3、4 掌握 C 語言、應用 C 語言_第2頁
《C語言(第三版)》 課件 項目3、4 掌握 C 語言、應用 C 語言_第3頁
《C語言(第三版)》 課件 項目3、4 掌握 C 語言、應用 C 語言_第4頁
《C語言(第三版)》 課件 項目3、4 掌握 C 語言、應用 C 語言_第5頁
已閱讀5頁,還剩260頁未讀, 繼續免費閱讀

下載本文檔

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

文檔簡介

03掌握C語言99任務1模擬“收款機”——順序結構程序的設計任務2判斷正負數或0——條件和分支結構程序的設計任務3打印九九乘法表——循環結構程序的設計任務4輸出4×4矩陣——數組的使用任務5設計“計算器”——函數的使用任務6按順序輸出10種水果名稱——指針的使用任務7輸出學生成績——結構體的使用任務8按面積售梯形板材——宏和預處理語句的使用100模擬“收款機”——順序結構程序的設計任務1101學習目標1.掌握C程序的基本結構。2.理解各種順序結構程序設計的理念。3.能運用輸入、輸出語句編寫程序。4.掌握簡單的程序設計方法。102任務描述超市的收款機是代替人工收款的機器,它可以通過掃描各商品的條形碼,輸入和顯示商品份數、單價、總價和找零;每當商品因打折等發生價格變化時,只需稍微修改運行程序就能自動實現價格變動。本任務用C程序來模仿收款機,體會簡單修改程序即能滿足收款機功能調整需求的過程,從而掌握數據的表達、運算、流程控制等基本內容,進一步了解C程序的設計思想和方法。103本任務“收款機”程序的具體要求為:現出售A、B、C、D、E、F這6種商品,其單價分別是10.50元、15.00元、18.00元、28.00元、40.20元、24.00元,其中F打6折。要求程序根據顧客購買的數量計算總價,并根據顧客支付的金額計算找零,通過C語言程序進行調試、運行并顯示總價和找零的計算結果。104相關知識一、C語言程序基本結構C語言程序是一種結構化程序,它的基本組成是函數,一個具體的程序任務可以分成若干部分,由函數分別定義和編碼,使程序模塊化。C語言程序一般由一個或者多個C函數組成,而函數又是由若干個C語句構成,一個C語句則是由若干個基本單詞構成。C語言程序的一般形式如下。105全局變量說明;main(){局部變量說明;語句;/*可以包含調用函數的語句。調用函數時,程序跳轉到相應函數的部分,函數結束后再跳轉回主函數,接著執行調用語句的下一個語句。主函數不可被調用*/}函數1(形式參數表)/*被調用函數,可以被主函數調用。此外,函數間也可以106互相調用,甚至可以調用自身*/{

局部變量說明;

語句;}函數2(形式參數表){

局部變量說明;107

語句;}…函數

n(形式參數表){

局部變量說明;

語句;}1081.?C函數C函數是完成C程序某個整體功能的基本單位,它是相對獨立的程序段、過程或模塊。一個C程序由一個主函數和若干其他函數組成,所有的函數都具有相同的結構。1092.?C語句C語句是完成某種功能函數的最小單位。C語句包括表達式語句、復合語句和空語句,都以分號結尾。(1)表達式語句。表達式語句由一個表達式加一個分號構成。(2)復合語句。復合語句由多條語句組成,并且這些語句必須用大括號括起來。(3)空語句。空語句中只有一個分號,程序執行空語句時不產生任何動作,可以用來表示延時,用戶在編程過程中應謹慎使用空語句。1103.?基本單詞基本單詞是構成C語句的最小單位,包括關鍵字(又稱保留字)、標識符、常量、操作符和分隔符5種。4.?程序特點(1)C程序是由函數組成的,一個C程序必須包含一個main()函數(即主函數),此外可以包含若干個其他函數,程序的全部工作由函數來完成。111(2)不論main()函數在什么位置,程序總是從main()函數開始執行。(3)程序的書寫自由,一行可寫多條語句,一條語句也可以根據一定規則分行書寫。但是,最好是每一行書寫一條語句。(4)一般用小寫字母編寫語句,一條語句以分號結尾。(5)在每條C語句后用“/*…*/”表示注釋,注釋并不影響語句的功能,只起提示作用。112二、程序流程圖程序流程圖是算法的圖形表示法,它用圖的形式代替了算法的細節,顯示從開始到結束的整個流程。傳統程序流程圖符號如圖所示。113

傳統程序流程圖符號目前流行的程序流程圖中,平行四邊形被矩形取代,表示連接點的小圓形也被省略。目前流行的程序流程圖如圖所示。右圖中所描述的是C語言常用的程序結構,根據輸入是否結束,程序的流程分成兩個不同的方向。由此可見,可以通過程序流程圖體現算法的細節、邏輯判斷,控制程序流程,讓程序根據不同的情況執行相應的語句。114目前流行的程序流程圖三、C程序設計的基本結構1.?順序結構順序結構是一種從上向下依次執行程序語句序列的線性結構,是最簡單的C程序設計結構,即從第一個語句開始,順序執行各個語句,直到所有的語句都執行完畢。順序結構流程圖如圖a所示。115

流程圖a)順序結構b)分支結構c)循環結構2.?分支結構分支結構是對一個問題給定的條件進行判斷,根據判斷結果來選擇繼續執行哪條語句。分支結構流程圖如上圖b所示。3.?循環結構循環結構比較復雜,是對給定的條件進行判斷,根據判斷結果,C程序或者反復執行某一段語句(稱為循環體),或者結束循環。循環結構流程圖如上圖c所示。116四、數據的輸入輸出交互式程序大多以數據交換來完成,程序分為輸入、處理、輸出3個部分,在C語言中有完備的輸入輸出功能,其中使用較多的是格式輸入輸出函數、單字符輸入輸出函數、文件輸入輸出函數。1.?printf()函數printf()函數可以向屏幕輸出變量、常量、表達式的值,是一種比較常用的輸出函數,它是系統提供的庫函數,函數聲明包含于系統文件stdio.h中。在調用庫函數中的printf()函數時,要先用編譯預處理命令#include<stdio.h>或#include"stdio.h"。117printf()函數的調用形式如下。printf("格式控制字符串",輸出項1,…,輸出項

n);printf()函數可以將不同類型的數據按一定的格式輸出,一個格式的說明必須由“%”開頭,以一種格式控制字符結束。printf()函數常用格式控制字符及其說明見下表,printf()函數附加格式字符及其說明見下表。118119printf(?)

函數常用格式控制字符及其說明120printf(?)函數附加格式字符及其說明2.?scanf_s()函數與printf()函數相似,scanf_s()函數是系統用于輸入的庫函數,函數聲明同樣包含于stdio.h系統文件中,能夠從鍵盤上接收數據并且格式化賦給變量,讀入內存。scanf_s()函數的一般調用形式如下。scanf_s("格式控制字符串",&輸入項1,…,&輸入項

n);在輸入單個字符(%c)或者字符串(%s)時,后面需要加上其長度(字節數N),其調用形式如下。scanf_s("格式控制字符串",&輸入項1,N,…,&輸入項

n,N);上式表示其中的“輸入項1”和“輸入項

n”輸入了單個字符(%c)或者字符串(%s)。121使用scanf_s()函數時,應注意以下幾點。(1)scanf_s()函數中沒有精度控制,如語句“scanf_s("%7.2f",&a);”是非法的。不能用此語句指定輸入小數為兩位的實數。(2)“&a”表示的是變量a的內存地址。scanf_s()函數要求給出變量地址,如給出變量名則會出錯。如語句“scanf_s("%d",a);”是非法的。(3)輸入多個數值數據時,若格式控制字符串中沒有非格式字符做輸入數據之間的間隔,則可用空格、Tab鍵或回車鍵做間隔。C程序編譯時碰到空格、Tab鍵、回車鍵或非法數據即認為該數據結束。(4)輸入字符數據時,若格式控制字符串中無非格式字符,則認為所有輸入的字符均為有效字符。1223.?getchar()和putchar()函數getchar()函數和putchar()函數是用于單個字符的輸入和輸出的函數,函數聲明也存在于系統文件stdio.h里,調用時比printf()函數和scanf_s()函數更簡捷。getchar()函數和putchar()函數調用形式如下。getchar(ch);putchar(ch);其中,ch可以是字符型常量、變量或整型變量。getchar()函數只能接收單個字符,輸入數字也按字符處理。輸入多于一個字符時,getchar()函數只接收第一個字符。123判斷正負數或0——條件

和分支結構程序的設計任務2124學習目標1.能熟練使用if語句、if-else語句編寫條件選擇程序。2.能運用嵌套if語句編寫程序。3.能使用switch語句等編寫多分支結構程序。125任務描述所謂分支結構,和道路的岔路很相似。人們走到岔路口時,會根據不同的條件要求,選擇不同的分岔行走。本任務要求對一個數是正數、負數還是0進行判斷,即看到一個數后,如果判斷它是正數,就顯示“Thisnumberisgreaterthan0.(這個數字大于零。)”,如果判斷它是負數,就顯示“Thisnumberislessthan0.(這個數字小于零。)”,如果判斷它是0,則顯示“Thisnumberis0.(這個數字是零。)”。本任務的具體要求是,用嵌套if語句編寫程序,實現從鍵盤上輸入一個整數,判斷這個整數是正數、負數還是0,并輸出結果。126相關知識一、分支結構分支結構是C語言3種基本結構之一,也是結構化程序設計必需的基本結構,分支結構程序主要使用流程控制語句(也稱過程化語句)實現。主要的流程控制語句有if語句、if-else語句、switch語句以及條件表達式語句等。程序執行到選擇結構時,首先進行條件判斷,根據條件成立或不成立分別選擇相應的語句執行。不管執行哪一個語句,執行結束后,控制語句都轉移到同一個出口結束。分支結構流程圖如圖所示。127128

分支結構流程圖二、簡單的if語句1.?if語句的定義if語句是根據所給定的條件決定執行的操作,是“二選一”的分支結構語句,用于判斷某些條件是否滿足,若條件滿足,則轉移到if語句下的子程序段執行,否則向下順序執行。if語句的一般形式如下。if(表達式){

語句;}129if語句的流程圖如圖所示。if語句執行流程時,如果表達式的值為真(非0),則執行其后的語句,否則不執行。if語句中的表達式可以是任何能轉化為數值的表達式,一般為邏輯表達式或關系表達式等。130if語句流程圖2.?設計if語句設計if語句及其他分支結構語句時,應注意以下幾個問題。(1)正確選擇條件或邏輯表達式作為分支的判斷條件。(2)根據需求繪制分支結構流程圖。(3)按流程圖編寫程序。在if語句結構中,對if語句的設計不同,將對程序的正確邏輯順序產生影響,同時也影響程序運行的效率。當if語句后的執行語句僅有一條時,可以省略大括號,此時執行語句可以放在“if(表達式)”語句的后面,也可以放在其下面。131三、if-else語句if-else語句又稱多分支結構,是由關鍵字if和else構成的多分支結構語句。if-else語句的一般形式如下。if(表達式){

語句1;}else{

語句2;}132if-else語句的執行規則是若表達式的值為真(非0),則進入if分支,執行語句1,然后跳過else分支,繼續執行else分支之后的語句,否則進入else分支,執行語句2。if-else語句流程圖如圖所示。當語句1和語句2為單語句時可省略大括號,當有多條語句出現時必須加大括號。133if-else語句流程圖四、嵌套if語句在if語句中包含一個或多個if語句稱為嵌套if語句。嵌套if語句通常在較為復雜的多流分支結構中使用。嵌套if語句的一般形式如下。if(條件表達式1){if(條件表達式2){

語句1;134

}else{

語句2;}}else{

語句3;}135嵌套if語句流程圖如圖所示。136嵌套if語句流程圖五、switch語句switch語句是多分支選擇語句。switch語句的一般形式如下。switch(表達式){case常量表達式1:

語句1;break;case常量表達式2:137

語句2;break;…case常量表達式n:

語句n;break;default:

語句(n+1);}138switch后面括號內的表達式的值必須是整數類型。當表達式值(判斷條件)與某個case后的常量相同時,執行相應case分支語句,若無break語句,則一直向下執行后面所有的分支語句而不再判斷case后的常量,直到所有case分支語句執行完畢或遇到break為止;若有break語句,則直接跳到switch結構的下一條語句執行,即switch結構的右大括號后面。通常情況下,如果不需要特殊的程序流程,對每個case分支都增加break語句即可。若所有的case分支中的常量表達式的值都沒有與switch后面括號內表達式的值相等的,就執行default后面的語句。switch語句流程圖如圖所示。139140switch語句流程圖打印九九乘法表——循環結構程序的設計任務3141學習目標1.掌握for循環語句的結構。2.掌握do-while循環語句的結構。3.掌握while語句的結構。4.能應用循環語句編寫循環結構程序。142任務描述九九乘法表是中國人發明的用于快速計算乘法的口訣,早在春秋戰國時期就已經被人們廣泛使用。在小學階段,背誦使用九九乘法表也是數學課中的必學內容。如需要編程輸出打印九九乘法表,直接使用printf()函數逐個算式、逐行書寫代碼雖然可以實現,但手動輸入9行共45個算式,顯然是十分煩瑣的。仔細觀察九九乘法表可以發現,它有很強的規律性,即它的行數、乘號前后的兩個數都是按一定規律遞增。像這種大量而重復的工作,恰恰是計算機程序最擅長解決的問題。輸出九九乘法表這個問題,用循環結構設計程序就可以快速完成。循環結構主要通過for、do-while、while等語句實現。143本任務的具體要求是用for循環語句編寫程序,應用for循環語句控制行輸出和列輸出,使用printf()函數輸出控制格式,實現行列對齊,將如下九九乘法表輸出到屏幕上。144相關知識一、循環結構循環結構是C語言3種基本結構之一,是結構化程序設計中最重要的結構,它的主要功能是重復執行某些語句,解決程序中實現重復循環的問題。通常將重復執行的語句稱為循環體,循環體的循環要在一定條件下終止。循環結構流程圖如圖所示。145循環結構流程圖C語言中提供4種循環,即goto循環、while循環、do-while循環和for循環。4種循環可以用來處理同一問題,通常情況下它們可以互相替換,但最好不要使用goto循環,因為強制改變程序的順序經常會給程序的運行帶來不可預知的錯誤。本書主要介紹for循環、while循環、do-while循環這3種循環結構。146二、循環語句1.?for循環語句for循環語句的使用最為靈活,既可以用于循環次數已經確定的情況,又可以用于循環次數不確定只給出循環結束條件的情況。for循環語句的一般形式如下。for(表達式1;表達式2;表達式3)語句;147其中,表達式1是初始表達式,用來給循環變量賦初值,一般是賦值表達式。也允許在for語句外給循環變量賦初值,此時在for循環語句中可以省略該表達式。表達式2是循環控制表達式,是循環條件,一般為關系表達式或邏輯表達式。表達式3是循環賦值表達式,用來修改循環變量的值,一般是賦值表達式。這3個表達式都可以是逗號表達式,即每個表達式都可由多個表達式組成。一般形式中的“語句”即為循環體。148for循環語句的語義如下。(1)計算表達式1的值。(2)計算表達式2的值,若值為真(非0)則執行循環體一次,否則跳出循環。(3)循環體執行結束后,再執行表達式3,修改循環變量,轉回第2步重復執行。在整個for循環過程中,表達式1只計算一次,表達式2和表達式3則可能計算多次。循環體可能多次執行,也可能一次都不執行。149for循環語句流程圖如圖所示。150for循環語句流程圖使用for循環語句時,要注意以下幾點。(1)for循環語句中的各表達式都可省略,但分號間隔符不能少。(2)在循環變量已賦初值時,可省去表達式1,如省去表達式2或表達式3則將造成無限循環,這時必須在循環體內添加break語句或exit語句,以強制結束循環。

(3)循環體可以是空語句。1512.?for循環語句的應用【例

】應用for循環語句編寫程序,求1至100自然數之和。152程序運行結果如圖所示。153程序運行結果3.?while循環語句while循環語句的特點是先判斷循環條件,再根據條件決定是否執行循環體操作。while循環語句的一般形式如下。while(表達式)循環體;格式中的循環體可以是單個語句、空語句,也可以是復合語句。4.?while循環語句的應用while循環語句中的表達式一般是關系表達式或邏輯表達式,只要表達式的值為真(非0),即可繼續循環。1545.?do-while循環語句do-while循環語句的執行特點是先執行循環體,然后判斷條件,根據條件決定是否繼續執行循環。do-while循環語句的循環體至少要執行一次。do-while循環語句的一般形式如下。do循環體while(表達式);155對于do-while循環語句,還應注意以下幾點。(1)在for循環語句、while循環語句中,表達式后面都不能加分號,在do-while循環語句的表達式后面則必須加分號。(2)do-while循環語句也可以組成多重循環,而且也可以和while循環語句相互嵌套。(3)如果do和while之間的循環體由多個語句組成,也必須用“{}”括起來,組成一個復合語句。(4)do-while和while循環語句相互替換時,要注意修改循環控制條件。1566.?do-while循環語句的應用【例

】分析下列程序,給出運行結果,并與上機運行結果相比較。157循環體的輸出語句中,先執行“x-=2”,然后輸出x的值,此時x的值為1。在判斷循環條件“!(--x)”時,首先x的值減1,循環判斷條件變為!0。既然0表示假,則!0表示真,循環繼續,此時x值為0。繼續執行循環體的輸出語句,執行“x-=2”之后,x值為-2。循環條件“!(--x)”不成立,停止循環,x值為-3。執行最后一句“printf("%d\n",x-=2);”輸出x值-5。程序運行結果如圖所示。158程序運行結果for循環語句也可與while語句、do-while循環語句相互嵌套,構成多重循環。以下都是合法的嵌套。159160輸出4×4矩陣——數組的使用任務4161學習目標1.理解一維數組、二維數組的基本概念。2.掌握數組類型變量的定義與引用。3.掌握數組元素的引用。4.能運用數組編寫程序。162任務描述某公司要將全體員工的月薪發放信息建立電子檔案,如果只有5名員工,可以使用5個同類型變量。例如使用語句“intmark0,mark1,mark2,mark3,mark4;”定義5個整型變量,可以存放5名員工的信息,如果是幾百人、幾千人甚至幾萬人的大公司,則不可能這么一直寫下去。在實際程序設計和代碼編寫中,經常會用到大批同類型數據,處理這些數據要占用一大片連續內存空間,于是數組應運而生。163用C語言提供的數組這一數據結構,可以很方便地解決大批同類型數據處理問題,這里的數據結構,可理解為數據的存放和管理方式。學習數組要思路清晰,循序漸進。本任務要求了解一維數組、二維數組的基本概念,掌握數組類型變量的定義與引用,掌握數組元素的引用。本任務的具體要求為某班級一個學習小組4人,共同參加4門考試。編寫程序,輸入每名學生4門課程的成績,輸出小組每門課的平均成績。164相關知識數組是一些具有相同數據類型(如整數型、實數型、字符型等)的變量的有序集合。其特點是變量數量固定、元素數據類型相同。和普通變量一樣,聲明一個數組時,編譯器為數組分配內存存儲空間,數組占據的內存空間是連續的,因此,很容易計算數組占據的內存大小和每個元素對應的內存首地址。所謂內存首地址就是用于存放每個元素的內存空間中第一個字節的內存地址。知道元素內存首地址和元素占據內存的大小,計算機才可以計算出該元素所占據的內存空間,才可以正確訪問該元素。對于不同數據類型的數組,元素所占據的內存大小也不同,通常用sizeof運算符計算特定類型元素所占據的內存大小。165如果第1個元素在內存中的地址為p,那么第M個元素(M不大于N)在內存中的地址可表示為表達式“p+(M-1)*sizeof(short)”。常用的數組種類有一維數組、二維數組和三維數組等。其中一維數組用單下標表示,二維數組用雙下標表示。本任務將重點介紹一維數組和二維數組。166一、一維數組一維數組是用以存儲一維數列中數據的集合。一維數組也稱向量,用以組織具有一維順序關系的一組同類型數據。1.?一維數組的定義一維數組定義的一般形式如下。類型說明符

數組名[常量表達式];其中,“類型說明符”表示數組中所有元素的類型,可以是任意一種簡單類型、構造類型或指針?!皵到M標識符”表示這個數組型變量的名稱,也稱數組名,命名規則與變量名一致。中括號(方括號)“[]”是數組標志,同時也是數組的重要組成部分,不能缺少。167“常量表達式”是中括號內的表達式,必須是正的整型常量表達式,通常是一個整型常量。常量表達式定義了數組中存放的數據元素的個數,即數組長度。如表達式“a[5]”中的5表示數組中有5個元素,下標從0開始,到4結束。例如,定義一個一維數組可使用語句“inta[5];”,該代碼中的int表示數組元素的類型,a表示數組名,中括號中的5表示數組中包含的元素個數。在數組a[5]中只能引用a[0]、a[1]、a[2]、a[3]、a[4]而不能使用a[5],若使用a[5]會出現下標越界的錯誤。1682.?一維數組的初始化初始化數組是在定義數組變量的同時給其中的數組元素賦值。一維數組初始化的一般形式如下。類型說明符

數組名[常量表達式]={值1,值2,…,值

n};定義數組時可直接對全部的數組元素賦初值,即全部初始化。例如,初始化一維數組a的語句如下。該語句是將數組中的元素值依次放在一對大括號中,每個值之間用逗號分隔。經過定義和初始化之后,

數組中的元素為a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5,a[5]=6。169二、二維數組下圖中的數組表示一個大小為M+1的一維數組,下圖中的數組表示一個大小為(M+1)*(N+1)的二維數組。170

一維數組二維數組1.?二維數組的定義二維數組的定義和一維數組類似,只是比一維數組多了一個常量表達式。二維數組定義的一般形式如下。數據類型說明符

數組名[常量表達式1][常量表達式2];其中“常量表達式1”表示第一維下標的長度,“常量表達式2”表示第二維下標的長度。對于二維數組array[n][m],其行下標的取值范圍0~n-1,其列下標的取值范圍0~m-1,該二維數組最大下標元素是array[n-1][m-1]。1712.?二維數組的引用與一維數組相同,定義了二維數組后就可以用它存儲數據、管理數據。二維數組的元素也稱為雙下標變量。引用二維數組元素的一般形式如下。數組名[下標][下標];下標可以是整型常量或整型表達式,例如,對一個二維數組的元素進行引用可使用表達式“a[1][2]”。1723.?二維數組的初始化二維數組同樣可以在聲明時利用初始值表進行元素的初始化。二維數組還可以在初始化表達式中,加內層大括號代表一行。此外,二維數組可對部分元素進行初始化。將一個二維數組中全部元素初始化為0的最簡單的方式是使用語句“intnum[2][3]={0};”。當聲明語句中提供全部元素的初始值時,第1維的大小可以缺省。173在定義數組的同時對其進行初始化,初始值表中的初值個數要少于或等于數組的長度。當初值個數少于數組的長度時,一維數組只能初始化前幾個元素,二維數組的初始化可跳過某些中間元素,給后面的元素賦值。數組元素在內存中是連續排列的,對二維和更高維的方式,數組元素仍然是線性連續排列的,不同下標的關系類似于數字的不同位數,最左邊的下標變化最慢,最右邊的下標變化最快,理解數組的內存模型有利于寫出高質量的代碼。174設計“計算器”——函數的使用任務5175學習目標1.熟練掌握函數的定義和調用,能使用函數嵌套調用和遞歸調用編寫程序。2.能正確使用形式參數和實際參數。3.理解內部函數和外部函數的概念。4.掌握返回語句的用法。5.了解庫函數的應用。176任務描述數學計算涉及公式或函數,數學中的函數是指對任何一個變量x,都有一個y值與之對應,例如“y=x+1”。在C語言中,函數有更重要的意義,它不僅能計算,而且是程序的基本組成單位。本任務調用自定義函數設計“計算器”,展示、體現C語言中函數的功能及其應用。本任務承載著C語言學習的重點,從函數的概念、定義入手,通過實例深入學習函數的調用與返回、函數的參數傳遞機制;應用函數解決實際問題,進一步學習模塊化編程的方法。本任務的具體要求為編寫一個“計算器”程序,調用自定義函數,實現分數的加、減、乘、除4種運算,測試并輸出“”的值。177相關知識一、函數1.?函數的概念函數是C程序的基本組成部分,完整的C程序由一個或多個函數組成??梢詫⒑瘮狄暈榫邆鋵崿FC語言某種功能的模塊,C語言也可稱為函數式語言。1782.?模塊化編程的理念C語言編寫的程序,只是入口和出口位于主函數之中,并不是所有的內容都放在主函數中。通常情況下可以將一個程序劃分成若干個模塊,每一個模塊完成一部分功能,C程序的功能通過函數之間的調用來實現。不同的程序模塊可以由不同的人來完成,目的是方便規劃、編寫和調試,提高軟件開發效率。C語言中函數之間的關系是平行的,函數在被定義的時候是相互獨立的,在一個函數中不能再定義其他函數(稱為嵌套函數)。函數之間是相互調用的關系,main()函數不能被調用。179二、函數的定義與聲明1.?函數的定義C程序中,函數定義的目的是讓編譯器知道函數的功能,函數的定義包括系統提供的標準函數和程序員自定義函數。系統提供的標準函數無須程序員定義,只需將包含該函數聲明的頭文件加在程序開頭,該函數就可以直接使用。函數定義有參數列表、返回類型、函數名和函數體4個要素。參數列表和返回類型對應著數據的輸入輸出,函數名用于和程序中其他程序實體區分,函數體是一段可執行的代碼塊,實現特定的算法或功能。180函數定義的一般形式如下。返回類型

函數名(參數列表){

函數體;}(1)參數列表。參數列表的一般形式如下。類型

變量名1,類型

變量名2,類型

變量名3,…若參數列表為空,需在括號內注明void,告訴編譯器沒有參數。181(2)返回類型。返回類型用于指明函數輸出值的類型,如果沒有輸出值,返回類型為void。如果在函數定義時沒有注明返回類型,默認為int。(3)函數名。函數名用于標識該函數,使之與其他函數區分開來,因此,函數名必須是合乎編譯器命名規則的標識符。參數列表、返回類型和函數名統稱函數頭,與之對應的是函數體。182(4)函數體。函數體是一段用于實現特定功能的代碼塊,比如局部變量聲明和其他執行語句等。在函數體內聲明的變量不能和參數列表中的變量同名。函數的定義是平行的,包括main()函數在內。所謂“平行”,有兩層含義:一是不允許把一個函數定義在另一個函數內,即函數定義要在main()函數外部;二是函數定義放置的位置與main()函數無關,即函數定義可以在main()函數之前,也可以在main()函數之后。183定義一個函數是為了調用,函數調用有兩種情況,第一種情況是“先定義,后調用”,第二種情況是“函數聲明+函數調用”?!跋榷x,后調用”是指函數定義和調用語句在同一個文件內,編譯器從函數定義中提取函數的參數列表、輸出類型等接口信息。1842.?函數的聲明函數調用第二種情況是“函數聲明+函數調用”,大多數情況下,函數的定義與函數的調用不在一個文件中,或者在一個文件中,調用在前,定義在后,這就需要在調用之前對函數聲明,告訴編譯器有此函數存在。函數聲明一般形式如下。返回類型

函數名(參數列表);例如語句“intmul(intx,inty);”。函數的聲明應與此函數頭保持一致,否則,編譯器會報錯。1853.?函數定義與聲明的區別(1)含義。函數的定義是用語句創建、編寫一個具有名字的新函數,實現具體的函數功能。函數聲明是當函數被調用時,需要在調用之前對函數聲明,告訴編譯器有此函數存在。186(2)語法格式。函數定義的一般形式如下。返回類型

函數名(參數列表){

函數體;}函數聲明的一般形式如下。返回類型

函數名(參數列表);(3)與主函數的位置。函數的定義可以在主函數前,也可以在主函數后。函數的聲明必須在主函數前。187三、函數的返回機制1.?遇到“}”后返回函數返回的第一種方式是程序從開頭一直執行到最后一句,當所有語句都執行完畢并遇到“}”后返回。1882.?返回語句定義函數是為了調用,以實現特定的功能。通常函數調用的目的是希望能夠得到一個計算結果,這就是函數的返回值。返回語句的一般形式如下。return(表達式);/*括號可以省略*/(1)在沒有返回值的函數中執行返回語句“return0;”能立即結束所在的函數執行,返回到調用的程序中去。(2)返回語句能夠將函數返回值賦值給調用的表達式。(3)返回值類型以函數定義時返回值類型為準,系統默認返回值類型為整型,返回值類型為void型的函數沒有返回值。189素數是指除了1和它本身以外不再有其他因數的自然數。該程序中要求判斷素數,基本思路是自定義函數1sprime,該函數有一個整型參數num,函數的返回值表示num是否為素數判斷結果,1表示num為素數,0表示num不是素數,返回值類型為整型。函數體通過循環判斷num是否存在整除的數據,如果存在返回0,反之返回1。返回值由return()函數帶回到main()函數中。190四、函數的參數及其傳遞方式函數調用操作時,多數情況下,主調函數和被調函數之間是數據傳遞關系。函數間通過參數傳遞數據,函數利用接收的數據進行操作。1.?形式參數和實際參數調用函數時,涉及兩種參數,即形式參數和實際參數,兩者之間有聯系又有區別。(1)通過名稱理解。形式參數是形式上存在的參數。實際參數是實際存在的參數。191(2)通過作用理解。形式參數是指在定義函數時,函數名后面括號中的變量,簡稱形參。在函數調用之前,傳遞給函數的值將被復制到這些形式參數中。實際參數是指在調用一個函數時,也就是真正使用一個函數時,函數名后面括號中的參數,簡稱實參。函數的調用者提供給函數的參數就是實際參數。實際參數是表達式計算的結果,并且被復制給主調函數的形式參數。1922.?數組做函數參數【例

】編寫程序,定義一個數組,將賦值后的數組元素作為函數的實參進行傳遞,當函數的形參得到實參傳遞的數值后,將這些數值輸出。193程序運行結果如圖所示。該程序在main()函數之前聲明需調用的函數。在main()函數的開始位置定義一個整型的數組和一個整型變量i,使用for語句,以變量i作為條件進行循環,對數組中的元素賦值,并且作為數組的下標制定數組元素的位置。使用自定義的ShowMember()函數顯示數據。194

程序運行結果數組名作為參數時,數組的長度是不需要說明的(多余的說明可能導致編譯出錯)。因為當數組名作為函數參數時,主調函數向被調用函數傳遞的并不是整個數組的所有元素值,而僅僅是這個數組的內存首地址。由于數組在內存中是順序存儲,知道數組的首地址和元素的數據類型,計算機就可以計算出數組中任一個元素的內存位置。195使用數組做函數參數時注意以下幾點。(1)用數組名做參數,應該在主調函數中定義數組。(2)實參數組與形參數組類型應一致。(3)形參數組也可以不指定大小,在定義數組時在數組名后面跟一個空的中括號。(4)用數組名作函數參數時,不是把數組元素的值傳遞給形參,而是把實參數組的起始地址傳遞給形參數組。196五、函數的調用方式在現實工作中,為了完成某項特殊的工作,需要一些特殊的工具,要先制作這個工具,然后使用。自定義函數就是用來完成編程工作的特殊工具,需要先定義,后使用,其使用的過程就是函數的調用。1.?函數的語句調用函數的語句調用是把函數作為一個語句進行調用。函數的語句調用是最常用的調用函數的方式。函數的語句調用一般形式為函數加上分號。1972.?函數的表達式調用函數的表達式調用是指函數出現在一個表達式中,這時要求函數返回一個確定的值,這個值參加表達式的運算。3.?函數的參數調用函數的參數調用是把函數作為另一個函數的實際參數調用,將函數返回值作為實際參數傳遞到函數中使用。函數的參數調用要求被調用函數必須有返回值。又如以下語句把調用函數max()的返回值作為printf()函數的實參來使用。1984.?函數的嵌套調用C語言中,函數的定義是互相平行、獨立的,定義函數時,函數內部不能再定義另一個函數。C語言不能嵌套定義函數,但是允許嵌套調用函數。一個函數既可以被其他函數調用,也可以調用別的函數,這就是函數的嵌套調用。嵌套調用函數的目的是完成某程序的子程序中某項功能,如同實際工作中逐級分配布置具體任務。199例如,學校里有許多項具體工作,校長把專業教學任務分配給各個學院,各院長把不同學科教學任務分配給各個教研室,各個教研室主任把具體學科教學任務分配給每位教師,每位教師按照教學要求完成教學任務。其過程如圖所示。200分配教學任務5.?函數的遞歸調用一個函數直接或間接調用該函數本身稱為函數的遞歸調用。函數的遞歸調用是C語言重要特點之一,當一個問題具有遞歸關系時,采用遞歸調用方式將使被處理的問題變得簡潔。201六、內部函數與外部函數的使用1.?內部函數內部函數又稱為靜態函數,它只能在定義它的文件中被調用,而不能被其他文件中的函數調用。如果在不同的文件中有同名的內部函數,這些同名的函數是互不干擾的。在定義內部函數時,要在函數返回值類型和函數名前面加上static作為關鍵字。定義內部函數一般形式如下。static返回值類型

函數名(參數列表)2022.?外部函數函數在本質上都具有外部性質,除了內部函數之外,其余的函數都可以被其他文件中的函數調用。稱這樣的函數為外部函數。為了明確這種性質,可以在函數定義和調用時使用關鍵字extern進行修飾。在使用一個外部函數時,要先用關鍵字extern聲明所用的函數是外部函數。例如,函數頭可以寫成下面的形式。externAdd(intiNuml,intiNum2);這樣函數Add就可以被其他源文件調用。203七、庫函數的應用1.?數學函數數學函數是C語言編譯系統提供的一種庫函數。在編寫C程序中經常會應用數學函數進行求值運算,得到數學函數的雙精度返回值。在使用數學函數時,要先包含頭文件math.h。代碼中,先定義用來保存計算結果的變量,然后得到結果,最后通過輸出語句將結果輸出。數學函數功能眾多,例如,求絕對值的函數有abs()函數、labs()函數和fabs()函數三種。其中,abs()函數的功能是求整數絕對值,labs()函數的功能是求長整型絕對值,fabs()函數的功能是求浮點數(小數)絕對值。2042.?字符檢測函數字符檢測函數也是C語言編譯系統提供的一種庫函數。在編寫C程序時用于檢測字母或檢測數字等,得到檢測的返回值。在使用字符檢測函數時,要先引用頭文件ctype.h。常用的字符檢測函數有以下幾種。(1)isdigit()函數isdigit()函數的作用是測試字符是否為阿拉伯數字。其函數定義語句為“intisdigit(intc);”,其中只有參數c為阿拉伯數字0到9時才能返回真。205206(2)isalpha()函數isalpha()函數的作用是測試字符是否為英文字母,其函數定義語句為“intisalpha(intc);”。(3)isalnum()函數isalnum()函數的作用是測試字符是否為英文字母或數字,其函數定義語句為“intisalnum(intc);”,相當于使用表達式“isalpha(c)||isdigit(c)”做測試。在編寫C程序時,首先盡量考慮使用庫函數,然后再考慮使用自定義函數。正確和靈活運用庫函數能提高程序的質量和編寫速度。按順序輸出10種水果名稱——指針的使用任務6207學習目標1.掌握指針與地址的概念。2.掌握指針變量的定義、初始化及指針的運算。3.掌握指針作為函數參數的應用。4.掌握指針與數組、指針數組、二級指針等知識。208任務描述運用指針編程是C語言主要的風格之一。利用指針變量可以操作各種數據結構,很方便地使用數組和字符串,從而編寫出精練而高效的程序,指針豐富了C語言的功能。本任務是運用指針變量輸入10種水果名稱,并按字母先后順序排列后輸出。本任務具體要求是以字符串的形式隨機輸入不同的水果名,應用指針數組等知識編寫程序,把輸入的水果名稱排序,再按字母先后順序輸出這些水果名稱。209相關知識一、C語言中地址與指針的概念1.?地址的概念計算機中的數據存放在存儲器中,一般把存儲器中的一個或幾個字節稱為一個內存單元,不同的數據類型所占用的內存單元數不等,為了正確地訪問這些內存單元,必須為每個內存單元編上號,根據一個內存單元的編號就可以準確地找到該內存單元,內存單元的編號也稱地址。一個內存地址可能包含多個內存單元。2102.?指針的基本概念指針是簡單變量、數組、函數等某個對象所占用的存儲單元的首地址。專門用來存放某種類型變量的首地址(指針值)的變量稱為該種類型的指針變量。對于一個內存單元來說,內存單元的地址即為指針,其中存放的數據是該內存單元的內容,內存單元的指針和內存單元的內容是兩個不同的概念。211指針變量是C語言中數據類型的特殊變量,一個指針值是一個地址,一個指針變量可以被賦予不同的指針值。指針不僅可以是變量的地址,還可以是數組、數組元素、函數的地址。正確地使用指針,能夠有效地表示和處理復雜的數據結構,特別有利于對動態數據的管理。指針的概念比較復雜,而且用法也非常靈活,要想真正掌握它,就必須多思考、多實踐。212二、指針變量的定義和引用1.?指針變量的定義定義指針變量的目的是通過指針去訪問內存單元。指針變量的值不僅可以是變量的地址,也可以是其他數據結構的地址。在C語言中,一種數據類型或數據結構往往都占有一組連續的內存單元。用“地址”這個概念并不能很好地描述一種數據類型或數據結構,而“指針”雖然實際上也是一個地址,但它卻是一個數據結構的首地址,它是“指向”一個數據結構的,因而概念更為清楚,表示更為明確。213定義指針變量的一般形式如下。類型說明符*指針變量名;其中,“類型說明符”表示本指針變量所指向的變量的數據類型;“*”表示這是一個指針變量。一個指針變量只能指向同類型的變量,例如,v1定義為指向浮點型變量的指針后,不能時而指向一個浮點型變量,時而又指向一個字符型變量。214指針變量指向的變量要預先定義。指針變量的定義語句及其含義見下表。215指針變量的定義語句及其含義2.?指針變量的引用(1)指針運算符。指針運算符包括取地址運算符“&”和取內容運算符“*”。取地址運算符“&”是單目運算符,其結合性為右結合性,其功能是取變量的地址。取內容運算符“*”是單目運算符,其結合性為右結合性,用來表示指針變量所指的變量。需要注意的是指針運算符“*”和指針變量定義中的指針說明符“*”是不同的,在指針變量定義中出現的“*”是類型說明符,表示其后的變量是指針類型,而在表達式中出現的“*”則是一個指針運算符,表示指針變量所指的變量,即通過指針變量間接訪問指針指向的變量。216例如,i_pointer代表指針變量,而*i_pointer是i_pointer所指向變量的值,因此,下面兩個語句作用相同。第一個語句的含義是將8賦給變量i,第二個語句的含義是將8賦給指針變量i_pointer所指向的變量。指針變量同普通變量一樣,使用之前不僅要定義,而且必須賦予具體的值。指針變量的賦值只能賦予有效地址。217若指向整型變量的指針變量為a,把整型變量b的地址賦予a有兩種方式,即指針變量初始化的方式和賦值語句的方式。指針變量初始化的語句如下。賦值語句如下。218語句“inta=1,*b=&a;”中的“*b=&a;”表示指針變量b獲取了整型變量a的地址。“printf("%d",*b);”語句表示輸出變量a的值。指針變量和一般變量一樣,其存儲的值是可以改變的。這時如果執行賦值表達式“p2=p1”,就使p2與p1指向同一對象i,此時“*p2”就等價于i,而不是j。如果執行表達式“*p2=*p1;”,則表示把p1指向的內容賦給p2所指的區域。219(2)指針變量的運算。1)賦值運算。指針變量的賦值運算,有以下幾種形式。①指針變量初始化賦值,例如以下語句。②把一個變量的地址賦予指向相同數據類型的指針變量,例如以下語句。220③把一個指針變量的值賦予指向相同類型變量的另一個指針變量,例如以下語句。④把數組的首地址賦予指向數組的指針變量,例如以下語句。221⑤把字符串的首地址賦予指向字符類型的指針變量,例如以下語句?;蛴贸跏蓟x值的方法寫為以下語句。⑥把函數的首地址賦予指向函數的指針變量,例如以下語句。2222)加減算術運算。數組指針變量向前或向后移動一個位置和地址加1或減1在概念上是不同的。因為數組可以有不同的類型,各種類型的數組元素所占的字節長度是不同的,指針變量的加減運算只能對數組指針變量進行,對指向其他類型變量的指針變量作加減運算是無意義的,例如以下語句。2233)兩個指針變量之間的運算。只有指向同一數組的兩個指針變量之間才能進行運算,否則運算無意義。兩指針變量進行關系運算是指向同一數組的兩指針變量進行關系運算,表示它們所指數組元素之間的位置關系。指針變量還可以與0比較。對指針變量賦0值和不賦值是不同的。指針變量未賦值時,可以是任意值,它指向的是臟數據(未經驗證或不符合預期格式的數據)。指針變量賦0值后,可以使用,只是它不指向具體的變量。224三、指針和函數1.?指針作為函數參數函數的參數不僅可以是整型、實型、字符型等數據,還可以是指針類型數據。它的作用是將一個變量的地址傳送到另一個函數中。2252.?函數指針變量在C語言中,一個函數總是占用一段連續的內存空間,而函數名就是該函數所占內存空間的首地址??梢园押瘮档倪@個首地址賦予一個指針變量,使該指針變量指向該函數。通過指針變量就可以找到并調用這個函數。我們把這種指向函數的指針變量稱為函數指針變量。函數指針變量定義的一般形式如下。類型說明符(*指針變量名)();其中“類型說明符”表示被指函數的返回值的類型?!?”后面的變量是定義的指針變量名,最后的空括號表示指針變量所指的是一個函數。226調用函數指針變量的一般形式如下。(*指針變量名)(實參表)使用函數指針變量還應注意以下兩點。第一,對函數指針變量進行算術(指針)運算是沒有意義的,這與數組指針變量不同。數組指針變量加減一個整數可使指針在內存的數據存儲區移動指向后面或前面的數組元素,而函數指針的移動是在程序存儲空間變換地址,是無意義的。第二,函數調用中“(*指針變量名)”的兩邊的括號不可少,其中的“*”不應該理解為求值運算,在此處它只是一種表示符號。227函數指針變量形式調用函數的步驟如下。先定義函數指針變量,如程序中“int(*pmax)(inta,intb);”,定義pmax為函數指針變量。把被調函數的首地址賦予該函數指針變量,如程序中的語句“pmax=max;”。用函數指針變量形式調用函數,如程序第18行的語句“z=(*pmax)(x,y);”。2283.?指針型函數函數類型是指函數返回值的類型。在C語言中允許一個函數的返回值是一個指針,這種返回指針值的函數稱為指針型函數。定義指針型函數的一般形式如下。類型說明符*函數名(形參表){…/*函數體*/}其中“類型說明符”表示返回的指針值所指向的數據類型,函數名之前加了“*”號表明這是一個指針型函數,即返回值是一個指針。229四、指針和數組1.?通過指針引用數組C語言規定,如果指針變量p已指向數組中的一個元素,則p+1指向同一數組中的下一個元素。引入指針變量后,就可以用兩種方法來訪問數組元素。如果指針變量p的初值為&a[0],則“p+i”和“a+i”就是a[i]的地址,或者說它們指向a數組的第i個元素;“*(p+i)”或“*(a+i)”就是“p+i”或“a+i”所指向的數組元素,即a[i]。指向數組的指針變量也可以帶下標。230根據以上敘述,引用一個數組元素可以用下標法和指針法。(1)下標法,即用a[i]形式訪問數組元素。(2)指針法,即采用“*(a+i)”或“*(p+i)”形式,用間接訪問的方法來訪問數組元素,其中a是數組名,p是指向數組的指針變量,其初值為p=a。2312.?指針變量、數組名分別做函數形參和實參指針變量、數組名做函數參數有四種情況。實參和形參都用數組名;實參用數組名,形參用指針變量;實參和形參都用指針變量;實參用指針變量,形參用數組名。(1)函數的實參和形參都是數組名。array為實參數組名,arr為形參數組名。數組名就是數組的首地址,實參向形參傳送數組名,實際上就是傳送數組的首地址,形參得到該地址后也指向同一數組。同樣,指針變量的值也是地址,數組指針變量的值即為數組某元素的地址,當然也可作為函數的參數使用。232(2)實參用數組名,形參用指針變量。(3)實參和形參都用指針變量。main()函數中的指針變量p是有確定值的。即如果用指針變量做實參,必須先使指針變量有確定值,指向一個已定義的數組。(4)實參用指針變量,形參用數組名。函數sort()用數組名作為形參,也可改為用指針變量,這時函數體的其他語句不變,其首部可以改為語句“voidsort(int*x,intn)”。2333.?指向多維數組的指針(1)多維數組的地址。設有整型二維數組a[3][4]如下。它的定義語句如下。假設16位機器中數組a的首地址為0x1000。234前面介紹過,C語言允許把一個二維數組分解為多個一維數組來處理。因此數組a可分解為三個一維數組,即a[0]、a[1]和a[2]。每一個一維數組又含有四個元素,例如a[0]數組中含有a[0][0]、a[0][1]、a[0][2]、a[0][3]四個元素。235數組及數組元素的地址表示如下。從二維數組的角度來看,“a”是二維數組名,“a”代表整個二維數組的首地址,也是二維數組第1行的首地址,等于0x1000。表達式“a+1”代表第2行的首地址,等于0x1008。“a[0]”是第一個一維數組的數組名和首地址,因此也為0x1000。表達式“*(a+0)”或“*a”是與a[0]等效的,它表示一維數組a[0]第0號元素的首地址,也為0x1000。“&a[0][0]”是二維數組a的0行0列元素地址,同樣是0x1000。由此可得出,表達式“a+i”“a[i]”“*(a+i)”是等價的。236(2)指向多維數組的指針變量。把二維數組a分解為一維數組a[0]、a[1]、a[2]之后,設p為指向二維數組的指針變量,可使用定義語句“int(*p)[4];”,它表示p是一個指針變量,它指向包含4個元素的一維數組。若p指向第一個一維數組a[0],其值等于a、a[0]或&a[0][0]等。而“p+i”則指向一維數組a[i]。從前面的分析可得出“*(p+i)+j”是二維數組i行j列的元素的地址,而“*(*(p+i)+j)”則是i行j列元素的值。237二維數組指針變量說明的一般形式如下。類型說明符(*指針變量名)[長度]其中“類型說明符”為所指數組的數據類型。“*”表示其后的變量是指針類型?!伴L度”表示二維數組分解為多個一維數組時,一維數組的長度,也就是二維數組的列數。應注意“(*指針變量名)”兩邊的括號不可少,如缺少括號則表示是指針數組,意義就完全不同了。2384.?指針數組的概念一個元素值為指針的數組即為指針數組。指針數組是一組有序的指針的集合。指針數組的所有元素都必須是具有相同存儲類型或指向相同數據類型的指針變量。指針數組說明的一般形式如下。類型說明符*數組名[數組長度];其中“類型說明符”為指針值所指向的變量的類型。239通??捎靡粋€指針數組來指向一個二維數組。指針數組中的每個元素被賦予二維數組每一行的首地址,因此也可理解為指針數組中的每個元素指向一個一維數組。二維數組指針變量是單個的變量,其一般形式中“(*指針變量名)”兩邊的括號不可少。而指針數組類型表示的是多個指針(一組有序指針),在一般形式中“*指針數組名”兩邊不能有括號。2405.?指向指針的指針如果一個指針變量存放的是另一個指針變量的地址,則稱這個指針變量為指向指針的指針變量。通過指針訪問變量稱為間接訪問。由于指針變量直接指向變量,該指針變量中存放了一個目標變量的地址,所以稱為“單級間址”。通過指向指針的指針變量來訪問變量則構成“二級間址”。定義一個指向指針型數據的指針變量p可使用語句“char**p;”,其中p前面有兩個“*”號,相當于表達式“*(*p)”。顯然“*p”是指針變量的定義形式,如果沒有最前面的“*”,那就是定義了一個指向字符數據的指針變量,它前面又有一個“*”號,表示指針變量p是指向一個字符指針型變量,“*p”就是p所指向的另一個指針變量。241五、指針和字符串1.?字符串的表示形式在C語言中,可以用兩種方法訪問一個字符串。(1)用字符數組存放一個字符串。(2)用字符串指針變量指向一個字符串。字符串指針變量的定義說明與指向字符型變量的指針變量的定義說明是相同的,只能按對指針變量的賦值不同來區別,對指向字符型變量的指針變量應賦予該字符型變量的地址。2422.?字符串指針變量與字符數組的區別用字符數組和字符串指針變量都可實現字符串的存儲和運算,但是兩者是有區別的。字符串指針變量本身是一個變量,用于存放字符串的首地址,而字符串本身是存放在以該首地址為首的一塊連續的內存空間中,以“\0”字符作為字符串的結束。字符數組是由若干個數組元素組成的,這些數組元素是字符串中的字符。字符串指針變量的書寫方式可如以下語句。243可以寫為如下形式。而對字符數組的書寫方式可如以下語句。不能寫為如下形式。字符數組只能對字符數組的各元素逐個賦值。指針變量在未取得確定地址前使用是危險的,容易引起錯誤,C語言對指針變量賦值時要給以確定的地址。244輸出學生成績——結構體的使用任務7245學習目標1.能熟練使用結構體變量、結構體數組以及結構體類型的指針,利用指針處理鏈表。2.了解共用體數據類型的特點。246任務描述在實際應用中,一組數據往往具有不同的數據類型。例如,在學生成績單中,姓名應為字符型數據,學號可為整型或字符型數據,年齡應為整型數據,性別應為字符型數據,成績可為整型或實型數據。顯然不能用一個數組來存放這一組數據,因為數組中各元素的類型和長度都必須一致,以便編譯系統處理。為了解決這樣的問題,C語言中給出了另一種構造數據類型——結構體。本任務通過使用結構體設計和編寫程序的實例,介紹結構體變量、結構體數組以及結構體指針等的使用方法;了解利用指針處理鏈表的方法,了解共用體數據類型的特點。247本任務的具體要求是使用結構數據類型,編寫“輸出學生成績單”的程序。學生成績單信息包括學號、小組、姓名以及三門課程成績(語文、計算機、英語)?!拜敵鰧W生成績”程序的主要功能是能按學號查詢學生的總分及平均分,且能查詢學生不及格科目,學生成績單見下表。248249學生成績單相關知識一、結構體當處理大量的同類型的數據時,利用數組很方便。然而,在實際應用中,常常有許多不同類型的數據也作為一個整體存在,如與日期有關的年、月、日,一個學生的信息等。如果能夠把這些有關聯的數據有機地結合起來并能利用一個變量來管理的話,將會大大提高對這些數據的處理效率。C語言中提供的名為結構體的數據類型,就是用來描述這類數據的。2501.?結構體的一般形式定義一個結構體的一般形式如下。struct結構體名{成員表列};其中,“成員表列”由若干個成員組成,每個成員都是該結構體的一個組成部分。對每個成員也必須作類型說明,其形式如下。類型說明符

成員名;其中,“成員名”的命名應符合標識符的書寫規定。251例如以下語句的功能就是建立一個結構體。252在這個結構體定義中,結構體名為report,該結構體由4個成員組成。第一個成員為num,被定義為整型變量;第二個成員為name,被定義為字符數組;第三個成員為gender,被定義為字符型變量;第四個成員為score,被定義為實型變量。應注意在括號后的分號是不可少的。結構體定義之后,即可進行結構體變量說明。凡說明為結構體report的變量都由上述4個成員組成。由此可見,結構體是一種復雜的數據類型,是數目固定、類型不同的若干有序變量的集合。2532.?說明結構體變量(1)先定義結構體,再說明結構體變量。例如:該段語句說明了兩個變量people1和people2為report結構體類型。254C語言中也可以用宏定義一個符號常量來表示一個結構體類型,例如以下語句。255(2)在定義結構體的同時說明結構體變量。例如:在定義結構體的同時說明結構體變量的一般形式如下。struct結構體名{成員表列}變量名表列;256(3)直接說明結構體變量。例如:直接說明結構體變量的一般形式如下。struct{成員表列}變量名表列;2573.?結構體變量成員的表示方法在程序中使用結構體變量時,往往不把它作為一個整體來使用。在C語言中除了允許具有相同類型的結構體變量相互賦值以外,一般對結構體變量的使用,包括賦值、輸入、輸出、運算等都是通過結構體變量的成員來實現的。表示結構體變量成員的一般形式如下。結構變量名.成員名如果成員本身也是一個結構體,則必須逐級找到最低級的成員才能使用。2584.?結構體變量的賦值結構體變量的賦值就是給各成員賦值,可用輸入語句或賦值語句來完成。5.?結構體變量初始化和其他類型變量一樣,結構體變量可以在定義時進行初始化賦值。6.?定義結構體數組數組的元素也可以是結構體類型的,因此可以構成結構體數組。結構體數組的每一個元素都是具有相同結構體類型的下標結構體變量。在實際應用中,經常用結構體數組來表示具有相同數據結構的一個群體。2597.?指向結構體變量的指針變量一個指針變量用來指向一個結構體變量時,稱其為結構體指針變量。結構體指針變量中的值是所指向的結構體變量的首地址。通過結構體指針即可訪問該結構體變量,這與數組指針和函數指針的情況是相同的。結構體指針變量說明的一般形式如下。struct結構體名*結構體指針變量名與前面討論的各類指針變量相同,結構體指針變量也必須先賦值后才能使用。賦值是把結構體變量的首地址賦予該指針變量,不能把結構體名賦予該指針變量。260結構體名和結構體變量是兩個不同的概念,不能混淆。結構體名只能表示一個結構體的形式,編譯系統并不對它分配內存空間。只有當某變量被說明為這種類型的結構體時,才對該變量分配內存空間。有了結構體指針變量,就能更方便地訪問結構體變量的各個成員。其訪問的一般形式如下。(*結構體指針變量).成員名或者采用如下形式。結構體指針變量->成員名261結構體成員有以下三種表示的形式。結構體變量.成員名(*結構體指針變量).成員名結構體指針變量->成員名這三種用于表示結構體成員的形式是完全等效的。2628.?指向結構體數組的指針指針變量可以指向一個結構體數組,這時結構體指針變量的值就是整個結構體數組的首地址。結構體指針變量也可指向結構體數組的一個元素,這時結構體指針變量的值就是該結構體數組元素的首地址。設ab為指向結構體數組的指針變量,則ab指向該結構體數組的0號元素,ab+1指向1號元素,ab+i則指向i號元素。這與普通指針數組的情況是一致的。263一個結構體指針變量雖然可以用來訪問結構體變量或結構體數組元素的成員,但是不能使它指向一個結構體數組元素的成員,也就是說不允許取一個成員的地址來賦予一個結構體指針變量。因此,下面的賦值語句是錯誤

溫馨提示

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

評論

0/150

提交評論