版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
數(shù)組C/C++語言程序設(shè)計(jì)案例教程2案例一統(tǒng)計(jì)學(xué)生成績(jī)1.問題描述從鍵盤上輸入10個(gè)學(xué)生的成績(jī),請(qǐng)編程完成以下操作:(1)保存這10個(gè)成績(jī);(2)按輸入順序的反向輸出10個(gè)成績(jī);(3)求平均成績(jī);(4)求最高成績(jī)和最低成績(jī)。2.問題分析要實(shí)現(xiàn)本案例,需要考慮如下幾個(gè)問題:(1)選擇什么樣的數(shù)據(jù)類型,才能高效的在計(jì)算機(jī)中存儲(chǔ)批量數(shù)據(jù);(2)如何標(biāo)記批量存儲(chǔ)數(shù)據(jù)中的個(gè)體;(3)如何對(duì)批量數(shù)據(jù)進(jìn)行訪問。33.?C語言代碼#include<stdio.h>voidmain(){intscore[10]; /*存放學(xué)生成績(jī)*/intmax,min,sum; /*存放最高成績(jī),最低成績(jī)和總成績(jī)*/
floataver; /*存放平均成績(jī)*/inti; /*循環(huán)變量*/printf("請(qǐng)輸入10個(gè)學(xué)生的成績(jī):\n"); /*輸入提示*/for(i=0;i<=9;i++) /*依次輸入10個(gè)成績(jī)*/scanf("%d",&score[i]);printf("學(xué)生的成績(jī)的逆序?yàn)椋篭n"); /*輸入提示*/for(i=9;i>=0;i--) /*逆序輸出成績(jī)*/printf("%5d",score[i]);sum=0; /*總成績(jī)賦初值*/for(i=0;i<=9;i++) /*計(jì)算總成績(jī)*/sum=sum+score[i];aver=sum/10.0; /*計(jì)算平均成績(jī)*/printf("\n平均成績(jī)=%.2f\n",aver); /*輸出平均成績(jī)*/min=score[0]; /*假設(shè)第一個(gè)成績(jī)是最低成績(jī)*/for(i=1;i<=9;i++) /*用循環(huán)找出最低成績(jī)*/{if(score[i]<min) /*如果有比min小的成績(jī)*/min=score[i]; /*就把此成績(jī)賦值給min*/}max=score[0]; /*假設(shè)第一個(gè)成績(jī)是最高成績(jī)*/for(i=1;i<=9;i++) /*利用循環(huán)找出最高分*/{if(score[i]>max) /*如果有比max大的成績(jī)*/max=score[i]; /*就把此成績(jī)賦值給max*/}printf("最低成績(jī)=%d\n",min); /*輸出最低成績(jī)*/printf("最高成績(jī)=%d\n",max); /*輸出最高成績(jī)*/}44.程序運(yùn)行結(jié)果請(qǐng)輸入10個(gè)學(xué)生的成績(jī):807890817595888598100學(xué)生的成績(jī)的逆序?yàn)椋?00988588957581907880平均成績(jī)=87.00最低成績(jī)=75最高成績(jī)=10054.1一維數(shù)組基礎(chǔ)知識(shí)4.1.1數(shù)組的概念在利用計(jì)算機(jī)解決實(shí)際問題時(shí),常常需要處理批量的類型相同的數(shù)據(jù),就像案例一中的10個(gè)成績(jī),還可能是更多的數(shù)據(jù),如整個(gè)班級(jí)學(xué)生的成績(jī)、一個(gè)企業(yè)的職工的工資、一批商品的價(jià)格等,這時(shí)候如果采用單個(gè)的基本類型變量存儲(chǔ)每一個(gè)數(shù)據(jù),就會(huì)產(chǎn)生很多個(gè)變量,組織和管理這些基本類型變量就會(huì)產(chǎn)生很多不方便,如何解決這個(gè)問題,C語言提供了數(shù)組這個(gè)數(shù)據(jù)類型。數(shù)組是一種構(gòu)造數(shù)據(jù)類型,主要是將相同類型的數(shù)據(jù)集合起來,用一個(gè)名稱來代表,案例一中的10個(gè)成績(jī)可以組織成一個(gè)數(shù)組,用一個(gè)數(shù)組名代表。數(shù)組中的每一個(gè)數(shù)據(jù)個(gè)體稱為數(shù)組元素,案例一中的每一個(gè)成績(jī)可以被認(rèn)為是一個(gè)數(shù)組元素(又稱下標(biāo)變量),它們用同一名字、不同下標(biāo)來區(qū)分。數(shù)組的使用和其他變量的使用一樣,也需要遵循“先定義,后使用”的原則。64.1.2一維數(shù)組的定義在案例一中,為了實(shí)現(xiàn)保存10個(gè)成績(jī)的功能,需要在計(jì)算機(jī)中定義變量,下面學(xué)習(xí)如何定義用來保存10個(gè)成績(jī)的數(shù)組變量。一維數(shù)組定義格式:數(shù)據(jù)類型數(shù)組名[數(shù)組長(zhǎng)度];格式說明:(1)數(shù)據(jù)類型:規(guī)定數(shù)組的數(shù)據(jù)類型,即數(shù)組中各元素的類型。可以是任意一種基本數(shù)據(jù)類型或指針,也可以是后續(xù)章節(jié)中將要學(xué)習(xí)到的其他構(gòu)造數(shù)據(jù)類型。(2)數(shù)組名:表示數(shù)組的名稱,命名規(guī)則和變量相同,為合法用戶標(biāo)識(shí)符,不能和程序中其他變量名或關(guān)鍵字重名。(3)數(shù)組長(zhǎng)度:表示數(shù)組中包含數(shù)組元素的個(gè)數(shù),只能表示成整型常量或整型常量表達(dá)式。其中可以包含常數(shù)或符號(hào)常量,但不能包含變量。7分析案例一,成績(jī)的數(shù)據(jù)類型屬于整型,數(shù)組的名稱起為score,共需要存儲(chǔ)10個(gè)數(shù)據(jù)。可以得出,這個(gè)數(shù)組的定義格式為intscore[10];編譯系統(tǒng)編譯時(shí)會(huì)根據(jù)定義為score分配10個(gè)連續(xù)的存儲(chǔ)單元,每個(gè)存儲(chǔ)單元占4個(gè)字節(jié)(用來存放1個(gè)int類型數(shù)據(jù))。數(shù)組score的存儲(chǔ)結(jié)構(gòu)如圖4.1所示。圖4.1案例一中一維數(shù)組的存儲(chǔ)結(jié)構(gòu)圖8注意:(1)數(shù)組名后的方括號(hào)中內(nèi)容不能為空,否則編譯程序不能確定數(shù)組分配的大小空間。例如“intx[]”是錯(cuò)誤的定義格式。(2)方括號(hào)中必須是常量或常量表達(dá)式,不能是變量。例如:“intn=10;intscore[n];”是錯(cuò)誤的定義格式。94.1.3一維數(shù)組的引用
數(shù)組在定義之后就可以使用了,但是數(shù)組不能作為一個(gè)整體參加各種運(yùn)算,只能通過每個(gè)數(shù)組元素逐個(gè)參與運(yùn)算來完成數(shù)組整體的處理,程序運(yùn)行時(shí)需要引用各個(gè)數(shù)組元素。一維數(shù)組引用格式:數(shù)組名[下標(biāo)表達(dá)式]格式說明:(1)數(shù)組名:要引用的數(shù)組名,必須是前期已經(jīng)定義過的數(shù)組。(2)下標(biāo)表達(dá)式:下標(biāo)是每個(gè)數(shù)組元素的編號(hào),對(duì)于長(zhǎng)度為n的數(shù)組,每個(gè)數(shù)組元素的下標(biāo)從頭至尾依次是0,1,2,3,…,n-1,即第一個(gè)元素的下標(biāo)是0,最后一個(gè)元素的下標(biāo)是n-1。下標(biāo)表達(dá)式可以是任何非負(fù)數(shù)整型表達(dá)式,包括整型常量、整型變量、含運(yùn)算符的整型表達(dá)式,以及返回值為整數(shù)的函數(shù)調(diào)用,下標(biāo)為小數(shù)時(shí),編譯系統(tǒng)將自動(dòng)取整。案例一中對(duì)score數(shù)組的引用如圖4.1所示。10注意:(1)在引用數(shù)組元素時(shí),下標(biāo)可以是整型常量或表達(dá)式,表達(dá)式內(nèi)允許變量存在,例如對(duì)案例一中成績(jī)表示如下:score[3];/*表示下標(biāo)為3的數(shù)組元素,即第4個(gè)成績(jī)*/intn=5;score[n];/*表示下標(biāo)為5的數(shù)組元素,即第6個(gè)成績(jī)*/score[n+3];/*表示下標(biāo)為8的數(shù)組元素,即第9個(gè)成績(jī)*/(2)在引用數(shù)組元素時(shí),下標(biāo)不能越界,否則,可能導(dǎo)致不可預(yù)料的錯(cuò)誤。例如在案例一中,數(shù)組score的下標(biāo)范圍是0至9,所以score[-1]和score[10]都屬于錯(cuò)誤的引用。114.1.4一維數(shù)組的初始化
定義后的數(shù)組每個(gè)數(shù)組元素的值都是隨機(jī)的,需要對(duì)每個(gè)數(shù)組元素賦值后才能使用。在定義數(shù)組的同時(shí)可以給數(shù)組元素賦初值,這種操作稱為數(shù)組的初始化。數(shù)組初始化時(shí)可以給全部數(shù)組元素都賦初值,也可以只給部分?jǐn)?shù)組元素賦初值。一維數(shù)組初始化格式:數(shù)據(jù)類型數(shù)組名[數(shù)組長(zhǎng)度]={常量表達(dá)式1,常量表示式2,…};格式說明:(1)數(shù)據(jù)類型、數(shù)組名、數(shù)組長(zhǎng)度同數(shù)組定義時(shí)要求相同。(2)大括號(hào)內(nèi)的各個(gè)常量表達(dá)式的值即為各數(shù)組元素的初值,各初值之間用逗號(hào)隔開。12根據(jù)賦初值的要求不同,數(shù)組初始化有以下幾種方式:(1)對(duì)全部數(shù)組元素賦值。例如:intx[5]={10,20,30,40,50};初始化后各數(shù)組元素的值分別為:x[0]=10,x[1]=20,x[2]=30,x[3]=40,x[4]=50。(2)對(duì)部分?jǐn)?shù)組元素賦值。例如:intx[5]={50,60};在上面的語句中,定義了5個(gè)元素,但只賦給兩個(gè)值,表示只給前面2個(gè)元素賦值,后續(xù)3個(gè)元素自動(dòng)默認(rèn)為0。初始化后各數(shù)組元素的值分別為:x[0]=50,x[1]=60,x[2]=0,x[3]=0,x[4]=0。(3)如果對(duì)數(shù)組的全部元素賦初值,定義時(shí)可以不指定數(shù)組長(zhǎng)度,系統(tǒng)根據(jù)初值個(gè)數(shù)自動(dòng)確定長(zhǎng)度。即初值的個(gè)數(shù)就是數(shù)組的長(zhǎng)度。這種方式可以對(duì)全部數(shù)組元素賦值的初始化形式簡(jiǎn)寫。例如“intx[5]={10,20,30,40,50};”可以簡(jiǎn)寫為“intx[]={10,20,30,40,50};”。13(4)只能給數(shù)組元素逐個(gè)賦值,不能給數(shù)組整體賦值。如果給數(shù)組x的5個(gè)元素全部賦初值10,只能寫成“intx[5]={10,10,10,10,10};”,而不能寫成“intx[5]=10;”,也不能寫成“intx[5]={10*5};”。144.1.5一維數(shù)組的訪問
數(shù)組可以整體定義,但不能整體訪問,只能通過逐個(gè)訪問每個(gè)數(shù)組元素來完成數(shù)組的整體訪問。因?yàn)閿?shù)組下標(biāo)是連續(xù)的,所以一維數(shù)組通常采用循環(huán)語句來完成對(duì)整體數(shù)組的訪問,用循環(huán)變量來控制要訪問的數(shù)組元素下標(biāo),下面以for循環(huán)語句做說明,其他循環(huán)語句處理原理與之相同。使用for循環(huán)語句訪問一維數(shù)組x的數(shù)組元素格式:for(i=n1;i<=n2;i++){訪問x[i];}格式說明:(1)格式中的n1和n2分別表示要訪問元素范圍的下標(biāo)下界和下標(biāo)上界,即表示要訪問的數(shù)組元素范圍為x[n1]…x[n2]。(2)格式中需要n1<=n2;如果n1>=n2,表示反向處理數(shù)組,需要把i++修改為i--。(3)循環(huán)變量的變化不局限于加1或減1,也可改變?yōu)槠渌介L(zhǎng)。(4)訪問x[i]可以是對(duì)x[i]的輸入或輸出,輸入輸出的方式見案例二。15案例二計(jì)算機(jī)技能大賽1.問題描述在學(xué)校的計(jì)算機(jī)技能大賽中,同學(xué)們積極備戰(zhàn)參與,經(jīng)過一系列比賽角逐,最終進(jìn)入決賽的20名同學(xué)總分已經(jīng)揭曉,為了確定比賽名次,請(qǐng)編程將所有選手的總分從低到高進(jìn)行排序。2.問題分析(1)定義一個(gè)一維數(shù)組準(zhǔn)備用來存儲(chǔ)每位比賽選手的總分。(2)采用循環(huán)結(jié)構(gòu)分別輸入每位比賽選手的總分存入數(shù)組中。(3)用冒泡排序法對(duì)數(shù)組中的總分進(jìn)行遞增排序。(4)輸出排序后的總分序列。163.?C語言代碼#include<stdio.h>voidmain(){inti,j; /*用于循環(huán)控制*/inta[20]; /*儲(chǔ)存選手的總分*/inttemp; /*中間變量*/printf("Pleaseinputthefinalscoreofthetwentyplayers:\n");/*輸入提示*/for(i=0;i<20;i++) /*依次輸入各位選手的總分*/scanf("%d",&a[i]);for(i=0;i<20-1;i++) /*從i=0開始,共進(jìn)行(20-1)輪排序*/{ /*每輪排序都使一個(gè)較大的值到達(dá)較大的位置*/for(j=0;j<20-1-i;j++) /*每輪兩兩比較的數(shù)據(jù)逐層遞減*/{if(a[j]>a[j+1]) /*符合條件則交換,將兩個(gè)元素進(jìn)行交換*/{temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}}printf("AfterSort:\n"); /*輸出提示*/for(i=0;i<20;i++)printf("%d",a[i]); /*依次輸出遞增排序后的各個(gè)總分*/printf("\n");}174.程序運(yùn)行結(jié)果Pleaseinputthefinalscoreofthetwentyplayers8081859091888293838784788975777986927695AfterSort:7576777879808182838485868788899091929395184.2一維數(shù)組排序
在編程過程中,經(jīng)常要完成對(duì)一組數(shù)據(jù)的排序工作,所以掌握幾種排序算法很有必要,冒泡排序法、選擇排序法都是很常用的排序方法。冒泡算法是一種比較經(jīng)典的算法。所謂冒泡法,就是將要排序的數(shù)據(jù)看成一個(gè)“數(shù)據(jù)湖”,在這個(gè)“湖中”,小數(shù)向上浮,而大數(shù)向下沉,按照這個(gè)規(guī)則,所有數(shù)據(jù)最終將變成從小到大的數(shù)據(jù)序列。假設(shè)要排序的5個(gè)數(shù)據(jù)序列是60,15,31,28,7,排序步驟如下:第一輪:從第1個(gè)數(shù)據(jù)開始,將相鄰的兩個(gè)數(shù)據(jù)進(jìn)行比較,若大數(shù)在前,則將這兩個(gè)數(shù)據(jù)進(jìn)行交換;直到最后兩個(gè)數(shù)據(jù)比較完畢,經(jīng)過這樣一輪的比較,所有的數(shù)據(jù)中最大的數(shù)據(jù)將被排在數(shù)據(jù)序列的最后,這個(gè)過程稱為第一輪排序。第一輪排序過程如下所示:19601531287156031287153160287153128607153128760/*第一輪排序后的結(jié)果*/20第二輪:從第1個(gè)數(shù)據(jù)開始到倒數(shù)第2個(gè)數(shù)據(jù)之間的所有數(shù)據(jù)進(jìn)行新一輪的比較和交換,比較和交換的結(jié)果為數(shù)據(jù)序列中的次大的數(shù)據(jù)被排在倒數(shù)第2的位置,排序過程如下所示:15312876015312871528317
152873160 /*第二輪排序后的結(jié)果*/第三輪:從第1個(gè)數(shù)據(jù)開始到倒數(shù)第3個(gè)數(shù)據(jù)之間的所有數(shù)據(jù)進(jìn)行新一輪的比較和交換,比較和交換的結(jié)果為數(shù)據(jù)序列中的第3大的數(shù)據(jù)被排在倒數(shù)第3的位置,排序過程如下所示:15287316015287
157283160 /*第三輪排序后的結(jié)果*/21第四輪:從第1個(gè)數(shù)據(jù)開始到倒數(shù)第4個(gè)數(shù)據(jù)之間的所有數(shù)據(jù)進(jìn)行比較和交換,排序過程如下所示:157283160715283160 /*第四輪排序后的結(jié)果*/像上面共經(jīng)過四輪排序,即(5-1)輪排序,排序結(jié)束,然后再輸出排序后的數(shù)據(jù)。選擇排序法的基本思路是:設(shè)有n個(gè)元素要排序,先把第一個(gè)元素作為最小者,與后面(n-1)個(gè)元素比較,如果第一個(gè)元素大,則與其交換(保證第一個(gè)元素總是最小的),直到與最后一個(gè)元素比較完,第一遍就找出了最小元素,并保證在第一個(gè)元素位置。再以第二個(gè)元素(剩余數(shù)據(jù)中的第一個(gè)元素)作為剩余元素的最小者與后面的元素一一比較,若后面元素較小,則與第二個(gè)元素交換,直到最后一個(gè)元素比較完,第二小的數(shù)就找到了,并保存在數(shù)組的第二個(gè)元素中,依次類推,總共經(jīng)過(n-1)輪處理后就完成了將輸入的n個(gè)數(shù)由小到大排序。22例4.1用選擇排序法實(shí)現(xiàn)案例二的排序。#include<stdio.h>voidmain(){inti,j; /*用于循環(huán)控制*/inta[20]; /*儲(chǔ)存比賽選手的總分*/inttemp; /*中間變量*/printf("Pleaseinputthefinalscoreofthetwentyplayers:\n");/*輸入提示*/for(i=0;i<20;i++) /*依次輸入各位選手的得分*/scanf("%d",&a[i]);for(i=0;i<20-1;i++) /*確定基準(zhǔn)位置*/{for(j=i+1;j<20;j++){if(a[i]>a[j]) /*符合條件則交換,將兩個(gè)元素進(jìn)行交換*/{temp=a[i];a[i]=a[j];a[j]=temp;}}}printf("AfterSort:\n"); /*輸出提示*/for(i=0;i<20;i++)printf("%d",a[i]); /*依次輸出排序后的各個(gè)總分*/printf("\n");}23案例三矩陣的存儲(chǔ)與計(jì)算1.問題描述編寫程序:有一個(gè)矩陣(5行5列),完成以下操作:(1)從鍵盤上輸入數(shù)據(jù)初始化矩陣;(2)在屏幕上輸出該矩陣;(3)計(jì)算矩陣主對(duì)角線元素之和,下三角元素之和;(4)計(jì)算矩陣首行、首列、末行和末列的元素之和。2.問題分析要實(shí)現(xiàn)上述案例,需要解決如下幾個(gè)問題:(1)矩陣類型非線性數(shù)據(jù)的存儲(chǔ)時(shí)需要什么類型的數(shù)據(jù)結(jié)構(gòu);(2)矩陣中的數(shù)據(jù)如何標(biāo)識(shí);(3)如何從矩陣中選取需要的數(shù)據(jù)。243.?C語言代碼#include<stdio.h>voidmain(){inta[5][5]; /*定義矩陣(5行5列)*/inti,j,sum; /*循環(huán)變量與存放和的變量*/printf("Pleaseinputthematrix(5*5):\n"); /*輸入提示*/for(i=0;i<5;i++) /*從鍵盤上輸入數(shù)據(jù)初始化矩陣*/for(j=0;j<5;j++)scanf("%d",&a[i][j]);for(i=0;i<5;i++) /*輸出矩陣*/{for(j=0;j<5;j++)printf("%d\t",a[i][j]);printf("\n");}sum=0; /*主對(duì)角線和初始化*/for(i=0;i<5;i++) /*計(jì)算矩陣主對(duì)角線元素之和*/sum=sum+a[i][i];printf("矩陣主對(duì)角線元素之和為:%d\n",sum); /*輸出矩陣主對(duì)角線元素之和*/sum=0; /*下三角元素之和初始化*/for(i=0;i<5;i++) /*計(jì)算矩陣下三角元素之和*/for(j=0;j<=i;j++)sum=sum+a[i][j];printf("矩陣下三角元素之和為:%d\n",sum); /*輸出矩陣下三角元素之和*/sum=0; /*計(jì)算矩陣首行、首列、末行和末列元素之和*/
for(i=0;i<5;i++)sum=sum+a[0][i]+a[i][0]+a[4][i]+a[i][4];sum=sum-a[0][0]-a[0][4]-a[4][0]-a[4][4];printf("矩陣首行、首列、末行和末列元素之和為:%d\n",sum);}254.程序運(yùn)行結(jié)果Pleaseinputthematrix(5*5):24678562304851379426806372467856230485137942680637矩陣主對(duì)角線元素之和為:22矩陣下三角元素之和為:76矩陣首行、首列、末行和末列元素之和為:76264.3二維數(shù)組基礎(chǔ)知識(shí)4.3.1二維數(shù)組的概念一維數(shù)組可以很方便的解決“一組”相關(guān)數(shù)據(jù)的存儲(chǔ)和處理問題,但對(duì)于“多組”相關(guān)數(shù)據(jù)的存儲(chǔ)和處理如何很好的完成?這就需要使用另外一種數(shù)組(二維數(shù)組)來解決。下面我們看一個(gè)例子:一個(gè)學(xué)生有三門課成績(jī),描述一個(gè)班60名學(xué)生的成績(jī),數(shù)據(jù)之間的關(guān)系如表4.1所示。學(xué)生語文數(shù)學(xué)英語學(xué)生1807590學(xué)生2858995…………學(xué)生60737580表4.1學(xué)生成績(jī)表27表中的3列成績(jī),代表著不同的科目,對(duì)于一個(gè)具體的數(shù)據(jù),例如89,它具有雙重身份,既表明這一成績(jī)屬于學(xué)生2,同時(shí)也表明它是數(shù)學(xué)成績(jī),從而需要兩個(gè)標(biāo)志去標(biāo)記它(學(xué)生姓名和科目),可以用行下標(biāo)和列下標(biāo)分別表示這兩個(gè)標(biāo)記。這樣a[1][1]就可以唯一標(biāo)識(shí)89這個(gè)數(shù)據(jù),即它代表的是第1行第1列上的數(shù)據(jù)元素。我們稱這種帶兩個(gè)下標(biāo)的數(shù)組為二維數(shù)組,它在邏輯上相當(dāng)于一個(gè)矩陣或是由若干行和列組成的二維表。因此在二維數(shù)組中,第一維的下標(biāo)稱為行下標(biāo),第二維的下標(biāo)稱為列下標(biāo)。284.3.2二維數(shù)組的定義二維數(shù)組與一維數(shù)組一樣,也需要“先定義,后使用”,二維數(shù)組定義格式如下:數(shù)據(jù)類型數(shù)組名[行大小][列大小]格式說明:(1)數(shù)據(jù)類型:規(guī)定數(shù)組的數(shù)據(jù)類型,即數(shù)組中各元素的類型??梢允侨我庖环N基本數(shù)據(jù)類型或指針,也可以是后續(xù)章節(jié)中將要學(xué)習(xí)到的其他構(gòu)造數(shù)據(jù)類型。(2)數(shù)組名:表示數(shù)組的名稱,命名規(guī)則和變量相同,為合法用戶標(biāo)示符,不能和程序中其他變量名或關(guān)鍵字重名。(3)行大小與列大小:表示二維數(shù)組中包含的總行數(shù)和總列數(shù),只能表示成整型常量或整型常量表達(dá)式。其中可以包含常數(shù)或符號(hào)常量,但不能包含變量。29例如:inta[3][4] /*定義整型二維數(shù)組a,3行4列,共有12個(gè)數(shù)組元素*/floatb[6][6] /*定義實(shí)型二維數(shù)組b,6行6列,共有36個(gè)數(shù)組元素*/對(duì)于上述60個(gè)學(xué)生3門課程成績(jī)的二維數(shù)組定義為intscore[60][3] /*第一維行數(shù)表示學(xué)生人數(shù),第二維列數(shù)表示課程門數(shù)*/注意:在C語言中二維數(shù)組的元素是按行優(yōu)先存儲(chǔ)的。例如定義的二維數(shù)組:inta[5][6],則在內(nèi)存中,先存儲(chǔ)第0行的元素,再存儲(chǔ)第1行的元素,依次類推,直到最后第4行元素存儲(chǔ)完畢。每行中的5個(gè)元素也是依次存放。304.3.3二維數(shù)組的引用
與一維數(shù)組引用形式類似,二維數(shù)組中的元素引用也只能用數(shù)組名和下標(biāo)逐個(gè)引用。二維數(shù)組引用格式為數(shù)組名[行下標(biāo)表達(dá)式][列下標(biāo)表達(dá)式]其中,行下標(biāo)表達(dá)式和列下標(biāo)表達(dá)式是為任意非負(fù)數(shù)整型表達(dá)式,每個(gè)下標(biāo)都從0開始。31注意:數(shù)組元素引用和數(shù)組定義在形式上有些相似,但兩者具有完全不同的含義。數(shù)組定義語句中的方括號(hào)中給出的是某一維的長(zhǎng)度,即某一維元素的個(gè)數(shù);而數(shù)組元素中的下標(biāo)是該元素在數(shù)組中的位置標(biāo)識(shí)。前者只能是常量,后者可以是常量、變量或表達(dá)式。例如:inta[3][5]; /*定義整型二維數(shù)組a*/a[2][3]=30; /*給行下標(biāo)為2、列下標(biāo)為3的數(shù)組元素賦值30*324.3.4二維數(shù)組元素的初始化
二維數(shù)組初始化是指在數(shù)組定義時(shí)給數(shù)組各元素賦初值,二維數(shù)組初始化可以使用以下形式:(1)按行對(duì)二維數(shù)組賦初值,將每一行元素的初值用一對(duì)花括號(hào)括起來。例如:inta[3][3]={{1,2,3},{4,5,6},{7,8,9}};這種方法比較直觀,不容易出錯(cuò),賦值后數(shù)組各元素為33(2)根據(jù)該數(shù)組元素的個(gè)數(shù),把初始化的數(shù)據(jù)全部括在一個(gè)大括號(hào)內(nèi),根據(jù)二維數(shù)組按行優(yōu)先存儲(chǔ)的規(guī)則,依次賦給數(shù)組對(duì)應(yīng)的元素。例如:inta[3][3]={1,2,3,4,5,6,7,8,9};賦值結(jié)果與第一種形式相同。但當(dāng)數(shù)據(jù)過多時(shí),容易產(chǎn)生遺漏,使用時(shí)需要細(xì)心。例如:inta[3][3]={{1,2},{4,5},{7}};這時(shí)只給第一、二行前兩列,第三行第一列元素賦初值,沒有賦值的元素默認(rèn)初值為0。賦值后數(shù)組元素的值如下:34例如:inta[3][3]={1,2,3,4,5};根據(jù)二維數(shù)組按行優(yōu)先存儲(chǔ)的規(guī)則,賦值后的數(shù)組元素值如下:35(3)在對(duì)數(shù)組元素初始化時(shí)可以省略第一維的長(zhǎng)度,但必須指定第二維的長(zhǎng)度。第一維的長(zhǎng)度由系統(tǒng)根據(jù)初始值表中的初值個(gè)數(shù)來確定,由數(shù)據(jù)元素個(gè)數(shù)除以第二維長(zhǎng)度向上取整來決定。例如:inta[][3]={1,2,3,4,5,6,7,8};由于a數(shù)組有8個(gè)初值,列長(zhǎng)度為3,所以該數(shù)組的行長(zhǎng)度為3。364.3.5二維數(shù)組的訪問
由于二維數(shù)組元素有兩個(gè)下標(biāo),所以一般用雙重循環(huán)來完成對(duì)數(shù)組元素的訪問,兩個(gè)循環(huán)變量分別控制要訪問元素的行下標(biāo)和列下標(biāo)。下面以for循環(huán)語句做說明,其他循環(huán)語句處理原理與之相同。使用for循環(huán)語句訪問二維數(shù)組x的數(shù)組元素格式:for(i=m1;i<=m2;i++) for(j=n1;j<=n2;j++){訪問x[i][j];}37說明:(1)格式中的m1和m2分別代表二維數(shù)組要處理的行下標(biāo)下界和上界;n1和n2分別代表二維數(shù)組要處理的列下標(biāo)下界和上界。以上代碼表示要處理的數(shù)組元素范圍為x[n1]…x[n2]。(2)格式中需要m1<=m2,n1<=n2;如果m1>=m2或n1>=n2,表示反向處理數(shù)組,需要把i++?修改為i--,j++修改為j--。(3)循環(huán)變量的變化不局限于加1或減1,也可改變?yōu)槠渌介L(zhǎng)。38案例四逆轉(zhuǎn)字符串1.問題描述編寫一個(gè)將字符串s1逆轉(zhuǎn)的程序。從鍵盤上輸入字符串s1的內(nèi)容,對(duì)字符串進(jìn)行逆轉(zhuǎn),把逆轉(zhuǎn)后的結(jié)果輸出。2.問題分析要實(shí)現(xiàn)上述案例,需要解決如下幾個(gè)問題:(1)字符串在計(jì)算機(jī)中如何存儲(chǔ);(2)字符串的輸入與輸出;(3)字符串的操作原理。393.?C語言代碼#include<stdio.h>voidmain(){chars1[20],s2[20];inti,j;printf("輸入字符串s1:");scanf("%s",s1);for(i=0;s1[i]!='\0';i++); /*計(jì)算s1數(shù)組中存儲(chǔ)字符串的長(zhǎng)度為i*/for(j=0;s1[j]!='\0';j++)s2[i-j-1]=s1[j]; /*從s1數(shù)組中按照由后往前的順序取元素依次賦值給s2數(shù)組*/s2[i]='\0';printf("逆轉(zhuǎn)后的字符串:%s\n",s2);}4.程序運(yùn)行結(jié)果輸入字符串s1:hello逆轉(zhuǎn)后的字符串:olleh思考:逆轉(zhuǎn)字符串的其他算法。404.4字符數(shù)組與字符串
字符數(shù)組就是類型為char的數(shù)組。同其他類型的數(shù)組一樣,字符數(shù)組既可以是一維的,也可以是多維的。C語言中并沒有字符串這種數(shù)據(jù)類型,而是使用字符數(shù)組存放字符串。字符數(shù)組中的各數(shù)組元素依次存放字符串的各字符,字符數(shù)組的數(shù)組名代表該字符串的首地址,這種方式為處理字符串中個(gè)別字符和引用整個(gè)字符串提供了方便。414.4.1字符數(shù)組
1.字符數(shù)組的定義一維字符數(shù)組的定義形式如下:char數(shù)組名[整型常量表達(dá)式];例如:char
a[10];二維字符數(shù)組的定義形式如下:char數(shù)組名[整型常量表達(dá)式1][整型常量表達(dá)式2];例如:char
b[3][4];422.字符數(shù)組的初始化對(duì)字符數(shù)組初始化,通常的方式是逐個(gè)字符賦給數(shù)組中各元素。例如:charc[10]={'I','','a','m','','h','a','p','p','y'};把10個(gè)字符分別賦給c[0]到c[9]的10個(gè)元素。如果初值個(gè)數(shù)小于數(shù)組長(zhǎng)度,則只將這些字符賦給數(shù)組中前面那些元素,其余元素自動(dòng)賦值為空字符('\0')。例如:charc[10]={'I','','a','m'};數(shù)組中從c[4]至c[9]元素的值為空字符。如果提供的初值個(gè)數(shù)與預(yù)定的數(shù)組長(zhǎng)度相同,在定義時(shí)可以省略數(shù)組長(zhǎng)度,系統(tǒng)會(huì)自動(dòng)根據(jù)初值個(gè)數(shù)確定數(shù)組長(zhǎng)度。例如:charc[]={'I','','a','m','','h','a','p','p','y'};數(shù)組的長(zhǎng)度定義為10。二維字符數(shù)組初始化方法與二維整型數(shù)組方法相同。434.4.2字符串
1.字符串的定義在C語言中,字符串是用雙引號(hào)括起來的字符序列。一般來講,字符串是利用字符數(shù)組來存放的。在存儲(chǔ)一個(gè)字符串時(shí),系統(tǒng)在其末尾自動(dòng)加一個(gè)字符串結(jié)束標(biāo)志'\0'。'\0'是ASCII碼為0的字符,稱為“空字符”,它表示字符串到此結(jié)束,利用該標(biāo)志可以很方便地測(cè)定字符串的實(shí)際長(zhǎng)度。2.字符串的輸入和輸出由于字符串是存放在字符數(shù)組中的,因此字符串的輸入和輸出,實(shí)際上就是字符數(shù)組的輸入和輸出。對(duì)字符數(shù)組的輸入和輸出可以有兩種方式:一種是采用“%c”格式符,每次輸入或輸出一個(gè)字符。另一種是采用“%s”格式符,每次輸入或輸出一個(gè)字符串。在使用scanf函數(shù)來輸入字符串時(shí),“輸入項(xiàng)表”中應(yīng)直接寫字符數(shù)組的名字,而不再用取地址運(yùn)算符&,因?yàn)镃語言規(guī)定數(shù)組的名字就代表該數(shù)組的起始地址。并且注意存儲(chǔ)字符串的字符數(shù)組長(zhǎng)度應(yīng)大于字符串的長(zhǎng)度。44例如:charstr[10];scanf("%s",str);/*在scanf函數(shù)中,str之前不要加上“&”*/另外還可以使用gets函數(shù)輸入字符串。形式為gets(字符串變量)gets()可以接受含有空格的字符串,而scanf函數(shù)只能夠輸入一個(gè)不包含空格的字符串,scanf函數(shù)在輸入時(shí)遇到空格或回車結(jié)束輸入,gets函數(shù)在輸入時(shí)遇到回車結(jié)束輸入。這是gets與scanf的最大差別。例如:char
str[15];
scanf("%s",str);從鍵盤上輸入:How,系統(tǒng)自動(dòng)在后面加上一個(gè)'\0'結(jié)束符,如果輸入為:Howare
you,則字符數(shù)組只能接受How。45若要字符數(shù)組接受Howare
you,修改如下:charstr[15];gets(str);輸入:Howare
you,這時(shí)str能接收所有的字符。使用字符數(shù)組處理字符串時(shí)的注意事項(xiàng):(1)輸出字符不包括結(jié)束符'\0'。(2)用“%s”格式輸出字符串時(shí),printf()的輸出項(xiàng)是數(shù)組名,而不是數(shù)組元素名。例如printf("%s",c[0]);是不符合語法要求的。46(3)輸出時(shí)如果數(shù)組長(zhǎng)度大于字符串實(shí)際長(zhǎng)度,輸出到'\0'結(jié)束。例如:char
c[10]={"china"};
printf("%s",c);實(shí)際輸出5個(gè)字符,到字符a為止,而不是10個(gè)字符。(4)如果一個(gè)字符數(shù)組中包含一個(gè)以上'\0',則遇第一個(gè)'\0'時(shí)輸出就結(jié)束。例如:char
c[10]={"chi\0na"};
printf("%s",c);輸出為chi,輸出到字符i為止。(5)在字符數(shù)組初始化時(shí)初值可以是字符串,例如:charstr1[15]={"Iamhappy"};也可以省略花括弧,直接寫成charstr1[15]="Iamhappy";若要省略數(shù)組下標(biāo),寫成charstr2[]="Iamhappy";47初始化時(shí)是否省略數(shù)組下標(biāo)是有區(qū)別的,區(qū)別在于字符數(shù)組str1中包含15個(gè)字符,從第9個(gè)元素開始都為空字符'\0',字符串占用15個(gè)內(nèi)存單元;而字符數(shù)組str2因?yàn)橛龅浇Y(jié)束符'\0'就停止賦值,所以只包含9個(gè)元素,其中第9個(gè)元素為字符結(jié)束標(biāo)志,字符串占用9個(gè)內(nèi)存單元。48案例五在指定位置插入字符1.問題描述輸入一個(gè)字符串和一個(gè)要插入的字符,然后輸入要插入的位置,在指定的位置插入指定的字符,并將新字符串輸出到屏幕上。2.問題分析(1)自定義一個(gè)插入函數(shù),實(shí)現(xiàn)向字符串中指定位置插入一個(gè)字符的功能;(2)在主函數(shù)中輸入字符串、要插入的字符及位置,調(diào)用插入函數(shù)實(shí)現(xiàn)插入操作。493.?C語言代碼#include<stdio.h>#include<string.h>voidmain(){chars[100],str[100],c;intposition;printf("Pleaseinputs:\n");gets(s); //使用gets()函數(shù)獲得一個(gè)字符串
printf("Pleaseinputachar:\n");scanf("%c",&c); //獲得一個(gè)字符
printf("Pleaseinputposition:\n");scanf("%d",&position); //輸入字符串插入的下標(biāo)位置
strncpy(str,s,position); //將s數(shù)組中的前position個(gè)字符復(fù)制到str中
str[position]=c; //把c放到str后面
str[position+1]='\0'; //用字符串結(jié)束符結(jié)束strstrcat(str,(s+position)); //將s的剩余字符串連接到strstrcpy(s,str);puts(str); //輸出最終得到的字符串}504.程序運(yùn)行結(jié)果Pleaseinputs:chnaPleaseinputachar:iPleaseinputposition:2china51案例六
字符串比較1.問題描述要求對(duì)"clanguage"、"helloworld"、"itcast"、"strcmp"和"justdoit"這五個(gè)字符串按照首字母大小進(jìn)行由小到大的排序,并將結(jié)果輸出到屏幕上。2.問題分析(1)自定義一個(gè)選擇排序法的函數(shù);(2)在主函數(shù)中定義一個(gè)指針數(shù)組用來構(gòu)造一個(gè)字符串?dāng)?shù)組;(3)調(diào)用排序函數(shù)完成從小到大的排序;(4)將排序結(jié)果輸出到屏幕上。523.?C語言代碼#include<stdio.h>#include<string.h> //添加字符串處理頭文件voidmain(){intn=5; //字符串個(gè)數(shù)
inti,j; //循環(huán)變量
chartemp[20]; //中間變量
charstrings[5][20]={"clanguage","helloworld","itcast","strcmp","justdoit"}; //用二維字符數(shù)組存放字符串
for(i=0;i<n-1;i++){for(j=i+1;j<n;j++){if(strcmp(strings[i],strings[j])>0) //根據(jù)大小交換位置
{strcpy(temp,strings[i]);strcpy(strings[i],strings[j]);strcpy(strings[j],temp);}}}for(i=0;i<n;i++) //依次輸出排序后的字符串
printf("%s\n",strings[i]);}534.程序運(yùn)行結(jié)果clanguagehelloworlditcastjustdoitstrcmp544.5字符串處理函數(shù)4.5.1字符串函數(shù)基礎(chǔ)C語言編譯系統(tǒng)為用戶提供了非常豐富的字符串處理函數(shù),使得字符串的處理變得很方便。這些函數(shù)說明都包含在頭文件string.h中,在使用時(shí)只需在相應(yīng)程序前面要加上預(yù)編譯命令#include"string.h"。下面介紹幾個(gè)常用的字符串處理函數(shù),如果編程過程中需要其他函數(shù),讀者可以查閱其他相關(guān)資料。551.字符串拷貝函數(shù)strcpy()調(diào)用形式:strcpy(str1,str2)參數(shù):str1為字符數(shù)組名或指向字符數(shù)組的指針,str2為字符串常量或字符串?dāng)?shù)組。功能:將str2所代表的字符串拷貝到字符數(shù)組str1中,并返回str1的地址。注意:(1)字符數(shù)組str1的長(zhǎng)度應(yīng)大于字符數(shù)組str2的長(zhǎng)度,如果str1的長(zhǎng)度小于str2的長(zhǎng)度,那么str1將容納不下str2的字符,強(qiáng)制拷貝將會(huì)出現(xiàn)運(yùn)行期錯(cuò)誤。(2)因?yàn)榭截悤r(shí)將str2中的字符串連同作為字符串結(jié)尾的字符'\0'一同拷貝到str1中,字符數(shù)組str1中原有數(shù)據(jù)一部分被覆蓋。(3)兩個(gè)字符數(shù)組之間不能直接賦值,當(dāng)需要將一個(gè)字符串或字符數(shù)組賦值給另一個(gè)字符數(shù)組時(shí),應(yīng)采用strcpy函數(shù)來實(shí)現(xiàn)。562.字符串連接函數(shù)strcat()調(diào)用形式:strcat(str1,str2)參數(shù):str1為字符數(shù)組或者指向字符數(shù)組的指針,str2為字符數(shù)組、字符串常量或指向字符數(shù)組的指針。功能:將字符串str2連接到str1后面,并返回str1的地址。注意:(1)字符數(shù)組str1的長(zhǎng)度應(yīng)大于字符數(shù)組str1和str2中的字符串長(zhǎng)度的和。(2)兩個(gè)字符數(shù)組中都必須含有字符'\0'作為字符串的結(jié)尾,而且在執(zhí)行該函數(shù)后,字符數(shù)組str1中作為字符串結(jié)尾的字符'\0'將被字符數(shù)組str2中的字符串的第1個(gè)字符所覆蓋,而字符數(shù)組str2中的字符串結(jié)尾處的字符'\0'將被保留作為結(jié)果字符串的結(jié)尾。573.字符串比較函數(shù)strcmp()調(diào)用形式:strcmp(str1,str2)參數(shù):str1和str2為字符串常量或字符串?dāng)?shù)組。功能:比較字符串str1和str2的大小。字符串的比較規(guī)則是:對(duì)兩個(gè)字符串自左至右逐個(gè)比較字符的ASCII值的大小,直到出現(xiàn)不同的字符或遇到結(jié)束符'\0'為止。如果全部字符相同,則兩個(gè)字符串相等;否則當(dāng)兩個(gè)字符串中首次出現(xiàn)不相同的字符時(shí)停止比較,并以此時(shí)str1中的字符的ASCII值減去str2中的字符的ASCII值作為比較的結(jié)果。具體為:當(dāng)比較的結(jié)果等于0時(shí),str1中的字符串等于str2中的字符串;當(dāng)比較的結(jié)果大于0時(shí),str1中的字符串大于str2中的字符串;當(dāng)比較的結(jié)果小于0時(shí),str1中的字符串小于str2中的字符串。注意:不能直接用關(guān)系運(yùn)算符比較兩個(gè)字符串的大小。在比較字符串大小時(shí),只能利用函數(shù)strcmp來實(shí)現(xiàn)。584.測(cè)試字符串長(zhǎng)度函數(shù)strlen()調(diào)用形式:strlen(str)參數(shù):str為字符串常量或字符數(shù)組。功能:返回字符串str或字符數(shù)組str中的字符串的實(shí)際長(zhǎng)度,不包括'\0'。5.字符串大小寫轉(zhuǎn)換函數(shù)strlwr()和strupr()調(diào)用形式為:strlwr(str)和strupr(str)參數(shù):str為字符串?dāng)?shù)組。功能:strlwr函數(shù)將字符串?dāng)?shù)組str中的大寫字母轉(zhuǎn)換成小寫的字母;strupr函數(shù)將字符串?dāng)?shù)組str中的小寫字母轉(zhuǎn)換成大寫的字母。59案例七用指針實(shí)現(xiàn)對(duì)數(shù)組的操作1.問題描述從鍵盤輸入多個(gè)整數(shù)存入一個(gè)一維數(shù)組中,利用指向一維數(shù)組的指針進(jìn)行操作,分別求這些整數(shù)的最大值與最小值,并輸出最大值與最小值在數(shù)組中的位置。2.問題分析本案例中要求用指針完成操作,需要解決如下幾個(gè)問題:(1)了解地址與指針的概念;(2)熟悉數(shù)組元素的地址表示法;(3)學(xué)會(huì)利用指向一維數(shù)組指針對(duì)數(shù)組進(jìn)行處理。603.?C語言代碼#include<stdio.h>voidmain(){inta[50],*p; //定義數(shù)組存放數(shù)字
intMAX,MIN; //定義最大值和最小值變量
inti,n; //輸入數(shù)字的個(gè)數(shù)
intj=0; //最小值位置
intk=0; //最大值位置
printf("Pleaseinputthesizeofarray:\n");scanf("%d",&n); //輸入數(shù)組的元素個(gè)數(shù)
p=a; //指針指向數(shù)組第一個(gè)元素
printf("Pleaseinputtheelementsofthearrayonebyone:\n");for(i=0;i<n;i++) //依次輸入數(shù)組中的元素
scanf("%d",p+i);MIN=*p; //數(shù)組首元素默認(rèn)為最小值
for(i=1;i<n;i++) //找出數(shù)組元素中的最小值
{if(*(p+i)<MIN) //如果有比MIN小的元素
{MIN=*(p+i); //就把此元素賦值給MINj=i+1; //將存儲(chǔ)最小值的位置賦給j}}MAX=*p; //數(shù)組首元素默認(rèn)為最大值
for(i=1;i<n;i++) //找出數(shù)組元素中的最大值
{if(*(p+i)>MAX) //如果有比MAX大的元素
{MAX=*(p+i); //就把此元素賦值給MAXk=i+1; //將存儲(chǔ)最大值的位置賦給k}}printf("ThepositionoftheMINis:%d\n",j); //輸出最小值所在的位置
printf("TheMINis:%d\n",MIN); //輸出最小值
printf("ThepositionofMAXis:%d\n",k); //輸出最大值所在的位置
printf("TheMAXis:%d\n",MAX); //輸出最大值}614.程序運(yùn)行結(jié)果Pleaseinputthesizeofarray:10Pleaseinputtheelementsofthearrayonebyone:88907875838593958070ThepositionoftheMINis:10TheMINis:70ThepositionofMAXis:8TheMAXis:95624.6一維數(shù)組與指針前面學(xué)習(xí)過,指針是C語言中一種特殊的變量類型,與其他類型的變量不同,指針變量存儲(chǔ)的是地址,正確地使用指針,可以使程序更為高效靈活。用指針對(duì)數(shù)組操作也能很好的提高效率。634.6.1指針運(yùn)算
前面已經(jīng)講過指針的基本概念,指針表示內(nèi)存變量的地址,存放指針的變量稱作指針變量,有時(shí)也簡(jiǎn)稱為指針。指針只能用地址表達(dá)式表示,不能將任意的整數(shù)賦予指針變量,也不能像普通整數(shù)那樣對(duì)指針進(jìn)行任意的運(yùn)算。指針的運(yùn)算主要有以下三種。1.算術(shù)運(yùn)算指針的算術(shù)運(yùn)算:指針加、減一個(gè)整數(shù)和兩個(gè)指針相減運(yùn)算。指針加、減一個(gè)整數(shù)運(yùn)算時(shí),兩個(gè)運(yùn)算對(duì)象是一個(gè)指針而另一個(gè)為整數(shù)類型的量。例如:inta=2;int*p;p=p+a;64表達(dá)式p+a的結(jié)果也是一個(gè)指針(地址值),這時(shí)指針指向指針p后面的第a個(gè)存儲(chǔ)單元的起始地址,但不同數(shù)據(jù)類型占用存儲(chǔ)單元的大小不同,指針移動(dòng)的距離也不同。如果指針p所指向?qū)ο蟮拇鎯?chǔ)單元包含m個(gè)字節(jié)(m為任意自然數(shù)),則指針移動(dòng)的距離為a*m,表達(dá)式p+a的結(jié)果(地址值)應(yīng)為p+a*m。指針加、減一個(gè)整數(shù)經(jīng)常用于對(duì)數(shù)組的操作。設(shè)p是指向數(shù)組中某元素的指針變量,則下列表達(dá)式合法:p+a
表達(dá)式表示從當(dāng)前位置p向地址變大方向移a個(gè)元素所對(duì)應(yīng)的地址,p保持不變;p-a
表達(dá)式表示從當(dāng)前位置p向地址變小方向移a個(gè)元素所對(duì)應(yīng)的地址,p保持不變;p++
表達(dá)式表示p當(dāng)前指向的地址,然后p向地址變大方向移1個(gè)元素,p變大;++p
表達(dá)式表示p當(dāng)前指向的地址向地址變大方向移1個(gè)元素所對(duì)應(yīng)的地址,p變大;p--
表達(dá)式表示p當(dāng)前指向的地址,然后p向地址變小方向移1個(gè)元素,p變小;--p
表達(dá)式表示p當(dāng)前指向的地址向地址變小方向移1個(gè)元素所對(duì)應(yīng)的地址,p變小。65總之,當(dāng)指針指向數(shù)組中某元素時(shí),指針加、減一個(gè)整數(shù),其結(jié)果的類型仍然是指向數(shù)組的元素的指針類型,結(jié)果的值向后(加)或向前(減)移動(dòng)了整數(shù)個(gè)元素。如圖4.2所示,表達(dá)式p+n的結(jié)果使得指向數(shù)組元素a[i]的指針變量p指向后面相隔n個(gè)元素的a[j]。圖4.2指針的移動(dòng)66兩個(gè)指針相減的運(yùn)算只對(duì)指向同一個(gè)數(shù)組的指針有意義。例如p1和p2是指向同一數(shù)組中不同或相同元素的指針(p1小于或等于p2),則p2-p1的結(jié)果為p2和p1之間間隔元素的數(shù)目n,注意兩個(gè)指針相減其結(jié)果是一個(gè)整數(shù)而不是指針。例如,如圖4.3所示,指針p1指向數(shù)組元素a[2],指針p2指向數(shù)組元素a[8];a[2]與a[8]之間相隔6個(gè)元素,所以p2-p1的值為6。圖4.3指針相減運(yùn)算672.關(guān)系運(yùn)算
如果兩個(gè)指針類型相同,則這兩個(gè)指針可以進(jìn)行任何一種關(guān)系運(yùn)算,其中作比較運(yùn)算的兩個(gè)指針應(yīng)指向同一個(gè)數(shù)組中的元素,否則運(yùn)算結(jié)果無意義。設(shè)指針p1、p2指向數(shù)組中的第i、j元素,則下列表達(dá)式為真的含義為:p1<p2(p1>p2)表示p1所指元素位于p2所指元素之前(之后);p1<=p2(p1>=p2)表示p1所指元素位于p2所指元素之前或者同一個(gè)元素(表示p1所指元素位于p2所指元素之后或者同一個(gè)元素);p1==p2(p1!=p2)表示p1和p2指向同一個(gè)元素(表示p1和p2不指向同一個(gè)元素)。NULL指針(整常數(shù)0)可以與任何類型的指針比較。NULL指針與其他類型的指針之間通常是作==和!=比較,判斷指針是否為NULL指針。684.6.2指向一維數(shù)組的指針1.一維數(shù)組地址一維數(shù)組元素a[i]的地址可以寫成表達(dá)式&a[i]或a+i,&a[i]是用下標(biāo)形式表示的地址,a+i是用指針形式表示的地址,二者結(jié)果相同。元素a[i]的地址等于數(shù)組首地址向后偏移若干字節(jié),偏移的字節(jié)數(shù)等于a[i]與首地址之間間隔元素的數(shù)目乘以一個(gè)元素的所占存儲(chǔ)單元字節(jié)數(shù)。例如:float
a[10];由于float類型占4個(gè)字節(jié),因此元素a[3]的地址值為a+3*4,即數(shù)組a的第3個(gè)元素的地址等于數(shù)組首地址向后偏移12個(gè)字節(jié)。692.一維數(shù)組指針的定義一維數(shù)組指針與指向其他簡(jiǎn)單變量的指針定義形式一樣。例如:inta[30];int*p;上面定義了一個(gè)整型數(shù)組a和一個(gè)指向整型量的指針變量p。這時(shí)指針變量p并沒有指向任何對(duì)象,只有當(dāng)將數(shù)組a的起始地址賦值給指針變量p時(shí),指針p才表示指向數(shù)組a,這時(shí)我們稱指針p為指向數(shù)組a的指針,指向過程可以通過下面兩種方法實(shí)現(xiàn):701)用數(shù)組名做首地址p=a;表示將數(shù)組a的起始地址賦值給指針p,而不是將數(shù)組a的所有元素賦值給指針p。將數(shù)組a的起始地址賦值給指針也可以在指針定義的同時(shí)進(jìn)行。如下:inta[30];int*p=a;/*指針的初始化*/這里int*p=a的含義是在定義指針變量p的同時(shí),將數(shù)組a的起始地址賦值給指針變量p,而不是賦值給指針p指向的變量(即*p)。712)用數(shù)組第一個(gè)元素的地址做首地址p=&a[0];數(shù)組名a與數(shù)組元素a[0]的地址相同,都是數(shù)組的起始地址,所以也可以將&a[0]賦值給指針p。無論利用上述那種方式,需要注意的是,對(duì)于指向一維數(shù)組的指針p,它所指向的變量(即*p)的數(shù)據(jù)類型必須與這個(gè)一維數(shù)組的數(shù)組元素的類型一致。例如下面的語句是錯(cuò)誤的:floata[30];int*p=&a[0];/*指向整型的指針不能指向數(shù)組元素類型為單精度的一維數(shù)組*/723.利用指針引用一維數(shù)組元素在將指針p指向一個(gè)一維數(shù)組a之后,就可以利用該指針對(duì)數(shù)組a的元素進(jìn)行引用了。1)下標(biāo)法2)指針法假設(shè)指針p已經(jīng)指向了數(shù)組a的起始地址,表達(dá)式p+n就是指向指針p所指向的數(shù)組元素后面的第n個(gè)元素的指針,*(p+n)就是對(duì)指針p所指向的數(shù)組元素的后面的第n個(gè)元素的值,p-n就是指向指針p所指向的數(shù)組元素前面的第n個(gè)元素的指針,*(p-n)就是對(duì)指針p所指向的數(shù)組元素前面的第n個(gè)元素的值。因此利用指針的加、減整數(shù)就可以產(chǎn)生指向數(shù)組的任意一個(gè)數(shù)組元素的指針,通過指針可以對(duì)數(shù)組的任意一個(gè)元素進(jìn)行引用。另外也可以反復(fù)利用指針的自增運(yùn)算或自減運(yùn)算,比如p++或p--,在數(shù)組的各個(gè)元素間移動(dòng)。73例如:訪問數(shù)組a的第2個(gè)元素a[2]:inta[30];int*p=a;p=p+2;這時(shí)指針p指向數(shù)組的第2個(gè)元素,則?*p等價(jià)a[2]。在利用指針來引用數(shù)組元素時(shí)應(yīng)注意以下幾點(diǎn):(1)通過指針訪問數(shù)組元素時(shí),必須首先讓該指針指向當(dāng)前數(shù)組。(2)因?yàn)閿?shù)組名表示數(shù)組的起始地址,所以數(shù)組名也可以稱為指針,但是注意數(shù)組名是一個(gè)特殊的指針,它不是指針變量,它的值在程序整個(gè)運(yùn)行過程中都不能被改變,只是存放數(shù)組的起始地址。所以像a++?或者a=a+2這些語句都是錯(cuò)誤的。(3)使用指針引用數(shù)組元素時(shí)注意下標(biāo)不能越界。例如:inta[5];int*p,n;p=a;74利用p=p+n移動(dòng)指針使p指向數(shù)組a的任意一個(gè)元素,當(dāng)n等于0、1、2、3、4時(shí),p將分別指向數(shù)組a的第0、1、2、3、4個(gè)元素。但應(yīng)注意的是,對(duì)于n大于4時(shí)也是合法的語句,p=p+n使指針p指向了數(shù)組a后面的存儲(chǔ)單元。在C語言中指針變量可以指向數(shù)組范圍之外的存儲(chǔ)單元,編譯系統(tǒng)不對(duì)數(shù)組元素引用時(shí)在下標(biāo)越界進(jìn)行判斷,因?yàn)榫幾g系統(tǒng)將數(shù)組元素處理成對(duì)數(shù)組起始地址加上數(shù)組元素的相對(duì)位移量所得的指針指向的存儲(chǔ)單元的引用,所以在使用指針引用數(shù)組元素時(shí)注意下標(biāo)不能越界。(4)在進(jìn)行指針運(yùn)算時(shí),應(yīng)注意運(yùn)算符的優(yōu)先級(jí)和結(jié)合性,寫出正確的表達(dá)式。例如,*p++等價(jià)于?*(p++),該表達(dá)式的結(jié)果為指針p所指的存儲(chǔ)單元的內(nèi)容,指針p指向下一個(gè)存儲(chǔ)單元。又例如,*(p++)與(*p)++?不同,表達(dá)式(*p)++?的功能是取指針p所指的存儲(chǔ)單元的內(nèi)容作為該表達(dá)式的結(jié)果值,然后將所指向的存儲(chǔ)單元內(nèi)容進(jìn)行加1運(yùn)算,而指針p的內(nèi)容不變。*++p與表達(dá)式?*(++p)等價(jià)于p=p+1;*p,即得到的是p指向下一個(gè)存儲(chǔ)單元的值,與?*p++?顯然不同。75案例八數(shù)據(jù)表的建立與操作1.問題描述工作生活中常常需要處理一些數(shù)據(jù),小到個(gè)人的日常開支,大到公司的整體運(yùn)營(yíng),為了使數(shù)據(jù)處理的效率更高、操作更加方便,常常使用各式各樣的數(shù)據(jù)表來存儲(chǔ)這些數(shù)據(jù)。例如使用一張表格記錄全班學(xué)生的成績(jī),針對(duì)該表格,可以執(zhí)行基于行的操作,求出某個(gè)學(xué)生的總成績(jī),也可以執(zhí)行基于列的操作,求得某個(gè)科目的成績(jī),進(jìn)而得出本班學(xué)生某科目的平均分。如圖4.4為一個(gè)簡(jiǎn)單的數(shù)據(jù)表。編程實(shí)現(xiàn)一個(gè)數(shù)據(jù)表,用戶可以向系統(tǒng)中動(dòng)態(tài)地輸入一批整數(shù),并利用指向數(shù)組的指針能完成對(duì)行或列的求和運(yùn)算。圖4.4數(shù)據(jù)表樣例762.問題分析圖4.4中是一張用于存儲(chǔ)整數(shù)的數(shù)據(jù)表,程序應(yīng)逐行或者逐列地存儲(chǔ)表中的每一個(gè)數(shù)并能逐個(gè)獲取表中的數(shù)據(jù),按照行或者列對(duì)表中的數(shù)據(jù)進(jìn)行運(yùn)算。該表的形式類似二維數(shù)組邏輯存儲(chǔ)結(jié)構(gòu),所以在本案例實(shí)現(xiàn)時(shí)很容易想到使用二維數(shù)組來存儲(chǔ)該表,但本章節(jié)要講解的知識(shí)點(diǎn)都與指針有關(guān),因此本案例的實(shí)現(xiàn)借助指針完成。773.?C語言代碼#include<stdio.h>voidmain(){intdataTable[5][4]={0}; /*定義數(shù)據(jù)表*/inti,j;intselect,pos,sum;int(*p)[4]=dataTable; /*定義數(shù)組指針*/printf("錄入數(shù)據(jù)中…\n");for(i=0;i<5;i++){for(j=0;j<4;j++)dataTable[i][j]=i*4+j;}printf("錄入完畢\n");printf("輸出數(shù)據(jù):\n");for(i=0;i<5;i++) /*輸出數(shù)據(jù)表*/{for(j=0;j<4;j++)printf("\t%d",*(*(p+i)+j));printf("\n");}printf("請(qǐng)輸入求和方式(行:0/列:1):");scanf("%d",&select);printf("選擇行/列:");scanf("%d",&pos);if(select==0){printf("按行求和,第%d行數(shù)據(jù)",pos);sum=0;for(i=0;i<4;i++) /*按行求和*/sum+=*(*(dataTable+pos-1)+i);}elseif(select==1){printf("按列求和,第%d列數(shù)據(jù)",pos);sum=0;for(i=0;i<5;i++) /*按列求和*/sum+=*(*(dataTable+i)+pos-1);}printf("求和結(jié)果為:%d\n",sum); /*輸出求和結(jié)果*/}784.程序運(yùn)行結(jié)果錄入數(shù)據(jù)中…錄入完畢輸出數(shù)據(jù):012345678910111213141516171819請(qǐng)輸入求和方式(行:0/列:1):1選擇行/列:2按列求和,第2列數(shù)據(jù)求和結(jié)果為:45794.7二維數(shù)組與指針
二維數(shù)組與多維數(shù)組同樣有地址,也可以使用指針引用,只是因?yàn)槠溥壿嫿Y(jié)構(gòu)較一維數(shù)組復(fù)雜,所以操作也較為復(fù)雜。程序中使用較多的通常是一維數(shù)組與二維數(shù)組,本節(jié)介紹指針與二維數(shù)組的關(guān)系。下面定義一個(gè)二行三列的二維數(shù)組,inta[2][3]={{1,2,3},{4,5,6}};其中a是二維數(shù)組的數(shù)組名,該數(shù)組中包含兩行數(shù)據(jù),分別為{1,2,3}和{4,5,6}。從數(shù)組a[]的形式上可以看出,這兩行數(shù)據(jù)又分別為一個(gè)一維數(shù)組,所以二維數(shù)組又被視為數(shù)組元素為一維數(shù)組的一維數(shù)組。與一維數(shù)組一樣,二維數(shù)組的數(shù)組指針同樣指向數(shù)組中第一個(gè)元素的地址,只是二維數(shù)組中的元素不是單獨(dú)的數(shù)據(jù),而是由多個(gè)數(shù)據(jù)組成的一維數(shù)組。指向二維數(shù)組行的指針定義方式如案例八中int(*p)[4]=dataTable;。80在一維數(shù)組中,指向數(shù)組的指針每加1,指針移動(dòng)步長(zhǎng)等于一個(gè)數(shù)組元素的大小,而在二維數(shù)組中,指針每加1,指針也是移動(dòng)一個(gè)元素,但
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)辦公墻紙裝飾協(xié)議
- 商場(chǎng)攤位租賃合同:鮮花綠植租賃
- 市場(chǎng)營(yíng)銷總監(jiān)聘用協(xié)議律師
- 假山醫(yī)院景觀施工合同
- 酒店清水池防水施工合同
- 海南省博物館聘用合同指南
- 皮革行業(yè)合同管理樣本
- 智能醫(yī)療弱電綜合布線施工合同
- 眼鏡專柜租賃合同模板
- 商務(wù)中心會(huì)議廳翻新合同
- 小學(xué)六年級(jí)家長(zhǎng)會(huì)課件
- 2024 年學(xué)校教務(wù)副校長(zhǎng)述職:以教育改革創(chuàng)新鑄學(xué)校卓越發(fā)展
- 【MOOC】馬克思主義基本原理-華東師范大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 福建省泉州市四校2024-2025學(xué)年高三上學(xué)期第一次聯(lián)考語文試題(含答案)
- 河北省邯鄲市2023-2024學(xué)年高二上學(xué)期期末質(zhì)量檢測(cè)數(shù)學(xué)試題
- 【MOOC】財(cái)務(wù)管理-四川大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 2024年律師事務(wù)所工作計(jì)劃(7篇)
- 2024屆高考語文詩歌復(fù)習(xí)教考融合之《李憑箜篌引》(含解析)
- 臨床提高膿毒性休克患者1h集束化措施落實(shí)率PDCA品管圈
- 高考語文模擬試題及參考答案
- 水利工程中的堤防與護(hù)岸工程考核試卷
評(píng)論
0/150
提交評(píng)論