C語言程序設計(第五章)_第1頁
C語言程序設計(第五章)_第2頁
C語言程序設計(第五章)_第3頁
C語言程序設計(第五章)_第4頁
C語言程序設計(第五章)_第5頁
已閱讀5頁,還剩121頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

第5章數組和指針主講:楊林5.1一維數組的定義和引用為處理方便,把具有相同類型的若干變量按有序的形式組織起來,這些按序排列的同類數據元素(變量)的集合稱為數組。一個數組可以包含多個數組元素,按數組元素的類型不同,數組又可分為數值型數組、字符型數組等各種類別。數組概述

對于數組中元素的序列,在C語言中就用a0,a1,a2,…,an-1來表示,a為數組名,下標代表數組中元素的序號,數組元素也稱為下標變量,ai用a[i]表示,i就是下標。一維數組是最簡單的數組,它的元素只有一個下標,如a[8]。還有二維數組(元素有兩個下標,如a[2][3]),三維數組(元素有三個下標,如a[2][3][6])和多維數組(元素有多個下標)。5.1.1定義一維數組定義一維數組的格式如下:

數組元素類型數組名[常量表達式],…;其中,數組元素類型可以任何類型,數組名是用戶定義的數組標識符(不可與普通變量同名)。方括號中的常量表達式表示數據元素的個數,也稱為數組的長度。例如:inta[18]; floatb[16],c[28]; charch[29]; 對于數組類型說明應注意以下幾點:對于同一個數組,其所有元素的數據類型都必須相同。如不一致,則會自動轉化為與數組元素相同的類型。數組名不能與其它變量名相同,例如:

intmain(void) /*主函數main()*/ { inta; /*定義變量a*/ floata[10]; /*定義數組*/ …… }

是錯誤的。方括號中常量表達式表示數組元素的個數,如a[18]表示數組a有18個元素。但是其下標從0開始計算。因此18個元素分別為a[0],a[1],a[2],…,a[17]

不能在方括號中用變量來表示元素的個數,但是可以是符號常數或常量表達式,例如:

#defineFD5 /*定義常量FD*/ intmain(void) /*主函數main()*/ {inta[3+2],b[7+FD]; /*定義數組a,b*/ …… }下面的使用方式是錯誤的:

intmain(void) /*主函數main()*/ { intn=5; /*定義整型變量n*/ inta[n]; /*定義數組,錯,元素個數n不是

…… }在同一個類型說明中,可以同時定義多個數組和多個變量。例如:

inta,b,c,d,k1[10],k2[20]; 5.1.2引用數組元素數組元素也是一種變量,其標識方法為數組名后跟一個下標。下標表示了元素在數組中的順序號。引用數組元素的一般格式為:

數組名[下標];其中的下標只能為整型常量或整型表達式。例如,a[6],a[i+j],a[k]都是合法的數組元素數組元素通常也稱為下標變量。在C語言中只能逐個地使用下標變量,而不能一次引用整個數組。例如,輸出有10個元素的數組必須使用循環語句逐個輸出各下標變量:

for(i=0;i<10;i++) printf("%d",a[i]); 而不能用一個語句輸出整個數組。下面的寫法是錯誤的:

printf(“%d”,a);

例5.1一維數組示例。intmain(void) /*主函數main()*/{ inti,a[10]; /*定義變量i與數組a*/ for(i=0;i<10;i++) { a[i]=2*i+1;} /*循環為數組元素賦值*/ for(i=9;i>=0;i--) { printf("%d",a[i]);} /*循環逆序輸出數組元素*/ printf("\n"); /*換行*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下:

191715131197531

請按任意鍵繼續...給數組賦值的方法除了用賦值語句對數組元素逐個賦值外,還可采用初始化賦值和動態賦值的方法。數組初始化賦值是指在數組說明時給數組元素賦予初值。初始化賦值的一般格式為:數組元素類型數組名[常量表達式] ={值1,值2,…,};在{}中的各數據值即為各元素的初值,各值之間用逗號間隔。例如:inta[10]={0,1,2,3,4,5,6,7,8,9}; C語言對數組的初始賦值還有以下幾點規定:可以只給部分元素賦初值。當{}中值的個數少于元素個數時,只給前面部分元素賦值,后面的元素自動賦值為0,例如:inta[10]={0,1,2}; /*表示只給a[0]--a[2]共3個元素賦值,而后7個元素自動賦0值*/只能給元素逐個賦值,不能給數組整體賦值。例如給十個元素全部賦1值,只能寫為:inta[10]={1,1,1,1,1,1,1,1,1,1};

而不能寫為inta[10]=1;如給全部元素賦值,則在數組定義中,可以不給出數組元素的個數。例如:inta[5]={1,2,3,4,5}; /*初始化5個數組元素值*/

可寫為:inta[]={1,2,3,4,5}; /*初始化5個數組元素值, 省略元素個數*/

一維數組初始化的小結:

1.給定數組長度,并逐個給數組賦初值intx[5]={10,20,30,40,50};2.給定數組長度,單只給數組的前面部分賦初值intx[5]={10,20,30};3.不給定數組長度,但對數組全部的元素賦初值intx[]={10,20,30,40,50};可以在程序執行過程中,對數組作動態賦值。這時可用循環語句配合scanf()函數逐個對數組元素賦值。例5.2數組元素最大值。intmain(void) /*主函數main()*/{ inti,max,a[10]; /*定義變量與數組*/ printf("輸入10個數:"); /*輸入提示*/

for(i=0;i<10;i++) { scanf("%d",&a[i]); } /*循環輸入數組元素*/ max=a[0]; /*設a[0]最大*/

for(i=1;i<10;i++) { if(a[i]>max) /*如果a[i]更大*/ max=a[i]; } /*將a[i]賦值給max*/

printf("最大值:%d\n",max); /*輸出最大值*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出參考如下: 輸入10個數:17491281856980

最大值:98

請按任意鍵繼續...#include<stdio.h>main(){ inti,s=0,t[]={1,2,3,4,5,6,7,8,9}; for(i=0;i<9;i+=2) s=s+t[i]; printf("%d\n",s);}以上程序運行結果?#include<stdio.h>main(){ inta[5]={1,2,3,4,5},b[5]={0,2,1,3,0},i,s=0; for(i=0;i<5;i++)s=s+a[b[i]]; printf("%d\n",s);}以上程序運行結果?5.2二維數組5.2.1定義二維數組定義二維數組一般形式是:數組元素類型數組名[常量表達式1][常量表達式2],…;其中常量表達式1表示第一維下標的長度,常量表達式2表示第二維下標的長度。例如:

inta[3][4]; /*定義二維數組*/定義了一個三行四列的數組,數組名為a,其下標變量的類型為整型。該數組的下標變量(元素)共有3×4個,即:

a[0][0],a[0][1],a[0][2],a[0][3] a[1][0],a[1][1],a[1][2],a[1][3] a[2][0],a[2][1],a[2][2],a[2][3]二維數組下標變量在數組中的位置也處于一個平面之中,但是硬件存儲器卻是連續編址的,也就是存儲器單元是按一維線性排列的。在一維存儲器中存放二維數組有兩種方式:按行排列,即放完一行之后順次存儲下一行。按列排列,即存儲完一列之后再順次存儲下一列在C語言中,二維數組是按行排列的。對于上面定義的數組,按行順次存放,先存儲第1行,再存儲第2行,最后存儲第3行。每行中有四個元素也是依次存儲。具體存儲順序如下: a[0][0],a[0][1],a[0][2],a[0][3],a[1][0],a[1][1],a[1][2],a[1][3],a[2][0],a[2][1],a[2][2],a[2][3]5.2.2引用二維數組元素二維數組的元素也稱為雙下標變量,其引用形式為: 數組名[下標][下標]其中下標應為整型常量或整型表達式。引用下標變量與定義數組在形式中有些相似,但兩者具有完全不同的含義。定義數組的方括號中給出的是某一維的長度;而數組元素中的下標是該元素在數組中的位置標識。例5.3一個學習小組有5個人,每個人有三門課的考試成績如下所示。求全組分科的平均成績和各科總平均成績。 姓名 數學 C語言數據結構 張明 80

75

92

王小艷68

78 88

李杰 89

98 61

趙剛 78

86 69

周勇 98

96 89可設一個二維數組a[5][3]存放五個人三門課的成績。再設一個一維數組v[3]存放所求得各分科平均成績,設變量l為全組各科總平均成績。intmain(void) /*主函數main()*/{ inti,j,a[5][3]; /*定義變量*/ floats=0,v[3]={0}; /*平均成績賦初值0* printf("輸入成績:\n"); /*輸入提示*/ for(i=0;i<5;i++) {for(j=0;j<3;j++) {scanf("%d",&a[i][j]);/*輸入成績*/ s=s+a[i][j]; /*求和*/ v[j]=v[j]+a[i][j]; /*對第j門課程成績求和*/ } } for(i=0;i<3;i++) v[i]=v[i]/5; /*求平均成績*/ s=s/15; /*總平均成績*/ printf("數學:%f\nC語言:%f\n數據庫系統:%f\n",v[0],v[1],v[2]); /*輸出各科平均成績*/ printf("總平均成績:%f\n",s); /*輸出總平成績*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出參考如下: 輸入成績: 807592 687888 899861 788669 989689

數學:82.599998 C語言:86.599998

數據庫系統:79.800003

總平均成績:83.000000

請按任意鍵繼續...5.2.3二維數組的初始化二維數組初始化也是在類型說明時給各下標變量賦以初值。二維數組可按行分段賦值,也可按行連續賦值。例如對數組a[5][3]:按行分段賦值可寫為:

inta[5][3]={ {80,75,92}, {68,78,88}, {89,98,61}, {78,86,69}, {98,96,89}};

按行連續賦值可寫為:

inta[5][3]={80,75,92,68,78,88,89,98,61,78,86,69,98,96,89};

例5.4將例5.3的成績通過初始方式賦值,改寫例5.3的程序,求全組分科的平均成績和各科總平均成績。intmain(void) /*主函數main()*/{ inti,j;

floats=0,v[3]={0}; /*定義變量*/ inta[5][3]={ /*按行分段賦值*/ {80,75,92}, {68,78,88}, {89,98,61}, {78,86,69}, {98,96,89}}; for(i=0;i<5;i++) { /*行*/ for(j=0;j<3;j++) { /*列*/ s=s+a[i][j]; /*求和*/ v[j]=v[j]+a[i][j];/*對第j門課程成績求和*/ } } for(i=0;i<3;i++) v[i]=v[i]/5; /*求平均成績*/ s=s/15; /*總平均成績*/ printf("數學:%f\nC語言:%f\n數據庫系統:%f\n",v[0],v[1],v[2]); /*輸出各科平均成績*/ printf("總平均成績:%f\n",s); /*輸出總平成績*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 輸入成績: 807592 687888 899861 788669 989689

數學:82.599998 C語言:86.599998

數據庫系統:79.800003

總平均成績:83.000000

請按任意鍵繼續...對于二維數組初始化賦值有如下說明:可以只對部分元素賦初值,未賦初值的元素自動取0值,例如:inta[3][3]={{1},{2},{3}};對每一行的第一列元素賦值,未賦值的元素取0值。賦值后各元素的值為:100200300如對全部元素賦初值,則第一維的長度可以不給出,例如:inta[3][3]={1,2,3,4,5,6,7,8,9};可以寫為:inta[][3]={1,2,3,4,5,6,7,8,9};

二維數組可以看作是由一維數組的嵌套而構成的。設一維數組的每個元素都又是一個數組,就組成了二維數組。二維數組a[3][4]可分解為三個一維數組,其數組名分別為a[0],a[1],a[2]。這三個一維數組都有4個元素,例如:一維數組a[0]的元素為

a[0][0],a[0][1],a[0][2],a[0][3]二維數組的初始化小結:1.按行給二維數組賦初值intx[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};2.按元素的排列順序賦初值intx[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};3.對部分元素賦初值intx[3][4]={{1,2,3},{5,6,}};4.如果對數組的全部元素都賦初值,定義數組時,第一維德元素個數可以不指定。intx[][4]={1,2,3,4,5,6,7,8,9,10,11,12};#include<stdio.h>main(){ intb[3][3]={0,1,2,0,1,2,0,1,2},i,j,t=1; for(i=0;i<3;i++) for(j=1;j<=1;j++) t+=b[i][b[j][i]]; printf("%d\n",t);}以上程序運行結果?5.3數組名作為函數參數5.3.1數組元素作函數參數由于函數實參可以是表達式,數組元素可以是表達式的組成部分。數組元素可以作函數的實參,按普通變量的方式對數組元素進行處理。例5.5編寫程序實現求給定的數組元素表示的工資中工資大于2000的人數。#defineN10 /*定義常量N*/intmain(void) /*主函數main()*/{intwage[N]={1500,1890,2100,2600,1980,2980, 3100,3600,2180,3208}; /*定義工資數組*/ inti,num=0; /*定義變量i,num*/ intCount2000(intw); /*函數聲明*/ for(i=0;i<N;i++) num=num+Count2000(wage[i]); /*統計工資大于2000元的人數*/ printf("共有%d人的工資大于2000.\n",num); /*輸出工資大于2000元的人數*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}intCount2000(intw) /*函數定義*/{ returnw>2000?1:0; /*當w大于2000時,返回1,否則返回0*/}程序運行時屏幕輸出如下: 共有7人的工資大于2000.

請按任意鍵繼續...5.3.2數組名作為函數參數用數組名作函數參數時,要求形參和相對應的實參都必須是元素類型相同的數組。在函數形參表中,允許不給出形參數組的長度,但[]不能省,也可以用一個變量來表示數組元素的個數。例5.6數組a中存放了一個學生5門課程的成績,求平均成績。floatAverage(floata[],intn) /*定義函數*/{ inti; /*定義整型變量*/ floatav,s=0; /*定義實型變量*/ for(i=0;i<n;i++) s=s+a[i]; /*循環累加求和*/ av=s/n; /*求平均值*/ returnav; /*返回平均值*/}intmain(void) /*主函數main()*/{ floatav,score[5]={68,86,98,79,99}; /*定義變量av與數組*/ av=Average(score,5); /*調用Average()求平均分*/ printf("平均分:%0.1f\n",av); /*輸出平均分*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 平均分:86.0

請按任意鍵繼續...數組名就是數組的首地址。因此在數組名作函數參數時所進行的傳送只是地址的傳送,也就是說把實參數組的首地址賦予形參數組名。形參數組和實參數組為同一數組,共同擁有一段內存空間,當形參數組元素發生變化時,實參數組元素也隨之變化。例5.7編程實現逆序數組中的元素。#include<stdio.h> /*標準輸入/出頭文件*/#include<stdlib.h> /*包含庫函數system()所需信息*/voidReverse(intb[],intn) /*定義函數*/{ inti,tem; /*定義變量*/ for(i=0;i<n/2;i++) { /*交換b[i]與b[n-i-1]*/ tem=b[i];b[i]=b[n-i-1];b[n-i-1]=tem; /*循環賦值實現交換b[i]與b[n-i-1]*/ }}…………intmain(void) /*主函數main()*/{ inta[10],i; /*定義變量與數組*/ for(i=0;i<10;i++) a[i]=2*i+1; /*為數組a的各元素賦值*/

printf("逆序前:"); /*輸出提示*/ for(i=0;i<10;i++) printf("%d",a[i]); /*輸出數組a各元素的值*/ printf("\n"); /*換行*/

Reverse(a,10); /*逆序數組a各元素*/

printf("逆序后:"); /*輸出提示*/ for(i=0;i<10;i++) printf("%d",a[i]); /*輸出數組a各元素的值*/ printf("\n"); /*換行*/

system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下:

逆序前:135791113151719

逆序后:191715131197531

請按任意鍵繼續...本題程序中“tem=b[i];b[i]=b[n-i-1];b[n-i-1]=tem;”用于交換b[i]與b[n-i-1]假設b[i]=3,b[n-i-1]=17,具體執行過程如下圖*5.3.3多維數組作函數的參數多維數組也可以作為函數的參數。在函數定義時對形參數組可以指定每一維的長度,也可省去第一維的長度。因此,以下寫法都是合法的。

intFun(inta[6][10])或

intFun(inta[][10])例5.8有一個3×4的二維數組,試編寫函數實現求數組中所有元素的最大值。#include<stdio.h> /*標準輸入/出頭文件*/#include<stdlib.h> /*包含庫函數system()所需信息*/intMax(inta[][4],intn) /*定義函數*/{ inti,j,m=a[0][0]; /*定義變量*/ for(i=0;i<n;i++) { /*行*/ for(j=0;j<4;j++) { /*列*/ if(a[i][j]>m) /*如果a[i][j]更大*/ m=a[i][j]; /*將a[i][j]賦值給m*/ } } returnm; /*返回最大值*/}…………intmain(void) /*主函數main()*/{ inta[3][4]={1,2,3,7,9,12,6,98,189,168,-20,58}; /*定義二維數組*/ intm; /*定義變量*/ m=Max(a,3); /*調用函數Max()求最大值*/ printf("最大值:%d\n",m); /*輸出最大值*/

system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 最大值:189

請按任意鍵繼續...5.4字符數組與字符串5.4.1字符數組用于存放字符量的數組稱為字符數組字符數組類型說明的形式與前面介紹的數值數組相同。例如:

charc[10]; /*定義長度為10的字符數組a*/字符數組也可以是二維或多維數組,例如:

charc[6][18];/*定義二維字符數組a*/字符數組允許在類型說明時作初始化賦值。例如:charc[10]={'H','e','l','l','o'};

賦值后各元素的值為:'H','e','l','l','o','\0','\0','\0','\0','\0'數組c的c[5],c[6],c[7],c[8]和c[9]未賦值,由系統自動賦字符‘\0’(字符‘\0’的ASCII碼為0)當對全體元素賦初值時也可以省去長度說明。例如:charc[]={‘H’,‘e’,‘l’,‘l’,‘o'}; 例5.9二維字符數組示例。intmain(void) /*主函數main()*/{ inti,j; /*定義變量*/ chara[][5]={{'B','A','S','I','C',}, {'d','B','A','S','E'}}; /*定義二維數組*/

for(i=0;i<=1;i++) { /*行*/ for(j=0;j<=4;j++) printf("%c",a[i][j]); /*顯示一行中字符*/ printf("\n"); /*換行*/ }

system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下:

BASIC dBASE

請按任意鍵繼續...5.4.2字符串在C語言中沒有專門的字符串變量,通常用一個字符數組來存放一個字符串。字符串總是以‘\0’作為串的結束符。因此當把一個字符串存入一個數組時,也把結束符‘\0’存入數組,并以此作為該字符串是否結束的標志。C語言允許用字符串的方式對數組作初始化賦值。例如:

charc[]={‘C','','p','r','o','g','r','a','m','\0'}; /*定義字符串,并賦初值*/可寫為: charc[]={"Cprogram"};/*定義字符串,并用串常量賦初值。系統自動添加’\0’*/或去掉{}寫為:

charc[]=“Cprogram”;/*自動添加’\0’*/無論哪種方式為字符數組賦初值都要注意:必須以’\0’作為字符串的結尾。除了上述用字符串賦初值的辦法外,還可用printf()函數和scanf()函數或gets()函數和puts()函數一次性輸入、輸出一個字符數組中的字符串。例5.10字符串示例。intmain(void) /*主函數main()*/{ chars[15]; /*定義字符串*/ printf("輸入串:\n"); /*輸入提示*/ scanf("%s",s); /*輸入串*/ printf("%s\n",s); /*輸出串*/

system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出參考如下: 輸入串: Helloworld! Hello

請按任意鍵繼續...對一個字符數組,如果不作初始化賦值,則必須說明數組長度用scanf()函數輸入字符串時,字符串中不能含有空格,否則將以空格作為串結束的標志5.4.2字符串常用函數C語言提供了豐富的字符串處理函數,使用這些函數可大大減輕編程的負擔。用于輸入輸出的字符串函數,在使用前應包含頭文件“stdio.h”;使用其它字符串函數則應包含頭文件“string.h”。1.字符串輸出函數puts()使用格式:puts(字符數組名);功能:將字符數組中的字符串輸出到顯示器。即在屏幕上顯示該字符串,并自動回車。例5.11字符串輸出函數puts()示例。#include<stdio.h> /*標準輸入/出頭文件*/#include<stdlib.h> /*包含庫函數system()所需信息*/intmain(void) /*主函數main()*/{ charstr[]="Thisisastring."; /*定義字符串*/ puts(str); /*輸出串*/

system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下:

Thisisastring.

請按任意鍵繼續...2.字符串輸入函數gets()使用格式:gets(字符數組名);功能:從標準輸入設備鍵盤上輸入一個字符串。本函數的函數返回值為該字符數組的首地址。例5.12字符串輸入函數gets()示例。intmain(void) /*主函數main()*/{ charstr[18]; /*定義字符串*/ printf("輸入串:\n"); /*輸入提示*/ gets(str); /*輸入串*/ puts(str); /*輸出串*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 輸入串: Thisisastring. Thisisastring.

請按任意鍵繼續...gets()函數并不以空格作為字符串輸入結束的標志,而只以回車作為輸入結束3.字符串連接函數strcat()使用格式:strcat(字符數組名1,字符數組名2);功能:stringcatenate,把字符數組2中的字符串連接到字符數組1中字符串的后面,并刪去字符串1后的串標志“\0”。函數返回值是字符數組1的首地址。原型:

strcat(char*str1,constchar*str2);例5.13字符串連接函數strcat()示例。intmain(void) /*主函數main()*/{ charstr1[30]="你的名字是",str2[10]; /*定義字符串*/ printf("輸入你的名字:"); /*輸入提示*/ gets(str2); /*輸入str2*/ strcat(str1,str2); /*將str2連接到str1的后面*/ puts(str1); /*輸出str1*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 輸入你的名字:李明 你的名字是李明 請按任意鍵繼續...4.字符串拷貝函數strcpy()使用格式:strcpy(字符數組名1,字符數組名2);功能:stringcopy,把字符數組2中的字符串拷貝到字符數組1中。串結束標志“\0”也一同拷貝。字符數組名2也可以是一個字符串常量。原型:strcpy(char*str1,constchar*str2)例5.14字符串拷貝函數strcpy()示例。#include<stdio.h>#include<string.h>main() { charstr1[18]="我學習",str2[]="C語言"; puts("使用strcpy之前的str1:"); puts(str1); strcpy(str1,str2); puts("使用strcpy之后的str1:"); puts(str1); puts("使用strcpy之后的str2:");puts(str2); }5.字符串比較函數strcmp()使用格式:strcmp(字符數組名1,字符數組名2)功能:stringcompare,按照ASCII碼順序比較兩個數組或字符串常量中的字符串,并由函數返回值返回比較結果。如果字符串1=字符串2,則返回值=0如果字符串2>字符串2,則返回值>0如果字符串1<字符串2,則返回值<0

原型:

strcmp(constchar*str1,constchar*str2)例5.15字符串比較函數strcmp()示例。intmain(void) /*主函數main()*/{ intk; /*定義變量*/ charstr1[18],str2[]="CLanguage";/*定義字符串*/ printf("輸入串str1:"); /*輸入提示*/ gets(str1); /*輸入str1*/ k=strcmp(str1,str2); /*調用函數strcmp()*/ if(k==0)printf("str1=str2\n"); /*相等*/ elseif(k>0)printf("str1>str2\n"); /*大于*/ elseprintf("str1<str2\n"); /*小于*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 輸入串str1:CProgram. str1>str2

請按任意鍵繼續...6.求字符串長度函數strlen()使用格式:strlen(字符數組名);功能:stringlength,求字符串的實際長度(不含字符串結束標志‘\0’)并作為函數返回值。原型: strlen(constchar*);例5.16求字符串長度函數strlen()示例。intmain(void) /*主函數main()*/{ charstr[]="CLanguage"; /*定義字符串*/ printf("串長度為%d\n",strlen(str)); /*輸出串長度*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 串長度為10

請按任意鍵繼續...5.5數組程序舉例例5.17在二維數組a中選出各行最大的元素組成一個一維數組b。編程思路是,在數組a的每一行中尋找最大的元素,找到之后把該值賦予數組b相應的元素即可。程序如下:intmain(void) /*主函數main()*/{ inta[3][4]={3,16,87,65,4,32,11,108,10,25,12,27}; /*定義二維數組a*/ intb[3]; /*定義數一組數b*/ inti,j,m; /*定義變量*/

for(i=0;i<3;i++) { /*行*/ m=a[i][0]; /*設第i行中a[i][0]最大*/ for(j=1;j<4;j++) if(m<a[i][j]) /*如果a[i][j]更大*/ m=a[i][j]; /*將a[i][j]賦值給m*/ b[i]=m; /*將m賦值給b[i]*/ }……

…… printf("數組a:\n"); /*輸出提示*/ for(i=0;i<3;i++) { /*行*/ for(j=0;j<4;j++) printf("%5d",a[i][j]);/*輸出第i行的元素a[i][j]*/ printf("\n"); /*換行*/ }

printf("數組b:\n"); /*輸出提示*/ for(i=0;i<3;i++) printf("%5d",b[i]); /*輸出b[i]*/ printf("\n"); /*換行*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 數組a: 3168765 43211108 10251227

數組b: 8710827

請按任意鍵繼續...*例5.18簡單選擇排序(SimpleSelectionSort)的第i趟是從(a[i],a[i+1],…,a[n-1])選擇第i小的元素,并將此元素放到a[i]處,也就是說簡單選擇排序是從未排序的序列中選擇最小元素,接著是次小的,依此類推,為尋找下一個最小元素,需檢索數組整個未排序部分,但只一次交換即將待排序元素放到正確位置上。對于序列(49,38,66,97,49,26),各趟簡單選擇排序過程如下圖。voidSelectionSort(inta[],intn) /*對數組a作簡單選擇排序*/{ inti,j,tem; /*定義變量*/ for(i=0;i<n-1;i++) { /*第i趟簡單選擇排序*/ intindex=i; /*記錄a[i..n-1]中最小元素小標*/ for(j=i+1;j<n;j++) if(a[j]<a[index]) index=j;/*用index存儲當前尋到的最小 元素小標*/ tem=a[i];a[i]=a[index];a[index]=tem; /*交換a[i],a[index]*/ }}intmain(void) /*主函數main()*/{ inta[6]={49,38,66,97,49,26}; /*定義數組a*/ inti; /*定義變量*/…………

printf("排序前:"); /*輸出提示*/ for(i=0;i<6;i++) printf("%6d",a[i]); /*輸出a[i]*/ printf("\n"); /*換行*/ SelectionSort(a,6); /*簡單選擇排序*/ printf("排序后:"); /*輸出提示*/ for(i=0;i<6;i++) printf("%6d",a[i]); /*輸出a[i]*/ printf("\n"); /*換行*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 排序前:493866974926

排序后:263849496697

請按任意鍵繼續...5.6指針變量的聲明和初始化指針變量存放的是變量的內存地址。也就是說,變量名直接引用一個值,而指針是通過地址間接地引用一個值。指針變量定義格式如下:

基類型*指針變量名;基類型:是指針所指向的變量的數據類型*指針變量名:在定義指針變量時表示這是一個指針變量。例如:

int*p;

表示p是一個指針變量,它的值是某個整型變量的地址。或者說p可以指向一個整型變量。5.7指針運算符運算符&一般稱為“地址運算符”,用于返回操作數的地址,比如有如下定義語句:

inta=8; int*p;這時語句

p=&a;將變量a的地址賦給指針變量p,變量p稱為“指向變量a”地址運算符的操作數必須是一個變量。運算符*一般稱為“間接引用運算符”,用于返回一個指針所指向的對象的值,例如語句:inta=8,*p=&a;

printf("%d",*p);

表示輸出指針p所指變量a的值。例5.19下面程序用于演示指針運算符的用法,從輸出結果可以發現變量a的地址與p的值是相等的,運算符&與*互為補充,將它們以任意順序連續地用在p上,其結果與p的值相同。intmain(void) /*主函數main()*/{ inta=9; /*a為一個值為9的整數*/ int*p; /*p是一個指向整數的指針*/ p=&a; /*將a的地址賦值給p*/ printf("a的地址為:%x\n",&a); /*輸出a的地址*/ printf("p的值為:%x\n",p); /*輸出p的值*/ printf("a的值為:%d\n",a); /*輸出a的值*/ printf("*p的值為:%d\n",*p); /*輸出*p的值*/

printf("演示*和&的互補特性:\n&*p=%x\n*&p=%x\n",&*p,*&p); /*輸出*和&的互補特性*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下:

a的地址為:13ff7c p的值為:13ff7c a的值為:9 *p的值為:9

演示*和&的互補特性: &*p=13ff7c *&p=13ff7c

請按任意鍵繼續...5.8指向void的指針在ANSIC新標準中,允許基類型為void的指針變量,這樣的指針變量不指向確定的類型設有如下的變量聲明:int*p; /*指向int的指針*/void*q; /*指向void的指針*/下面是合法的賦值語句:p=NULL; /*NULL表示空值,表示p不指向任何對象*/p=(int*)q; /*通過強制類型轉換可將指向void的指針賦給指向其向類型的指針*/p=q; /*作者經過實驗證實,指向void的指針可通過隱式類型轉換直接賦給指向其向類型的指針(教材第1版第1次印刷版已作了勘誤)*/5.9函數參數的引用傳遞將變量作為函數實參數的傳遞方式有兩種:值傳遞(賦值)引用傳遞(復制地址)值傳遞指將實參的值復制給對應的函數形參,在函數調用環境中實參的值并不發生變化引用傳遞指將實參的地址復制到對應形參指針,也就是實參與形參指向同一個內存單元,這樣對形參的操作與對實參的操作是等價在C語言中所有函數參數的傳遞都是值傳遞的,要實現引用傳遞只能用指針和間接引用運算符*實現。在調用某個函數并且以變量作為參數時,如果需要修改變量的值,這時應給函數傳遞參數的地址,一般在需要修改值的變量前面使用地址運算符&。當將變量的地址傳遞給函數參數時,可以在函數體中用間接引用運算符*修改內存單元中此變量的值。函數參數的引用傳遞的操作步驟如下:將函數參數聲明為指針;在函數體內使用間接引用運算符*訪問指針;當調用函數時,將地址作為參數傳遞。例5.20使用函數參數的引用傳遞實現交換兩個變量的值。voidSwap(int*,int*); /*交換兩個變量的值*/intmain(void) /*主函數main()*/{ intx=6,y=9; /*定義變量*/ printf("調用函數前:x=%d,y=%d\n",x,y);/*輸出交換前x,y的值*/ Swap(&x,&y); /*調用函數時,將地址作為參數傳遞*/ printf("調用函數后:x=%d,y=%d\n",x,y);/*輸出交換后x,y的值*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}voidSwap(int*p,int*q) /*將函數參數聲明為指針*/{ inttmp; /*臨時變量*/ /*在函數體內使用間接引用運算符*訪問指針*/ tmp=*p;*p=*q;*q=tmp; /*循環賦值實現交換*p與*q*/}程序運行時屏幕輸出如下: 調用函數前:x=6,y=9

調用函數后:x=9,y=6

請按任意鍵繼續...函數體中下語句:

tmp=*p;*p=*q;*q=tmp; /*循環賦值實現交換*p與*q*/的執行過程圖示如下:例5.21使用指針作形參實現求一個數的平方。函數Square()用傳地址方式傳遞給函數,用指向int的指針p作參數,函數體中間接引用指針所指的變量并計算了

p所指變量的值的平方,改變了main()函數中變量n的值,程序源代碼如下:voidSquare(int*p) { *p=*p**p; /*采用間接引用運算符*訪問指針*/}intmain(void) /*主函數main()*/{ intn=6; /*定義變量*/ printf("用指針作參數變量的平方:\n"); /*提示信息*/ printf("函數調用前n的值:%d\n",n); /*輸出調用前n的值*/ Square(&n); /*調用Square()函數求平方*/ printf("函數調用后n的值:%d\n",n); /*輸出調用后n的值*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下: 用指針作參數變量的平方:

函數調用前n的值:6

函數調用后n的值:36

請按任意鍵繼續...5.10指針變量和數組5.10.1指針變量與一維數組1.指向數組元素的指針變量一個數組由一片連續內存單元組成。數組名就是這片內存單元的首地址。數組名實質是地址常數每個數組元素占有幾個連續的內存單元。一個數組元素的地址也是指它所占有的內存單元的首地址。數組名的值就為0號元素的地址,一個指針變量可以指向一個數組,也可以指向數組的一個元素,可將數組名或0號元素的地址賦予它。如要使指針變量指向第i號元素,可以把i元素的首地址賦予它或把數組名加i賦予它。設有如下聲明:#defineN60 /*定義常量N*/inta[N],*p; /*定義數組a和指針p*/語句:p=a; /*將數組名(首地址)賦值給p*/與語句:p=&a[0]; /*將數組元素a[0]的地址賦值給p*/等價,都是將數組的起始地址,也是a[0]的地址賦值給p,這樣賦值后p,a,&a[0]都指向同一存儲單元,它們都是數組a的首地址,也是0號元素a[0]的首地址p+1,a+1,&a[1]均指向1號元素a[1]同樣p+i,a+i,&a[i]都指向i號元素a[i]引入指針變量后,可以用兩種方法來訪問數組元素。下標法,用a[i]或p[i]形式訪問數組元素。指針法,即采用*(p+i)或*(a+i)形式,用間接訪問的方法來訪問數組元素。從上面的說明可知,a[i],p[i]

,*(a+i)和*(p+i)等價。例5.22斐波那契數列定義如下:a0=0,a1=1,a2=1,a3=2,ai=ai-1+ai-2,…試采用數組的指針表示法輸出a0~a19。在程序中數列用數組a表示,同時定義指向數組元素的指針p,具體程序實現如下:#defineN20 /*定義常量*/intmain(void) /*主函數main()*/{ inta[N],*p=a; /*聲明數組和指針變量*/ inti; /*臨時變量*/ *p=0;*(p+1)=1; /*賦初值*/ for(i=2;i<N;i++) { /*通指針間接訪問數組元素方式實現a[i]=a[i-1]+a[i-2]*/ *(p+i)=*(p+i-1)+*(p+i-2); /*a[i]=*(p+i),a[i-1]=*(p+i-1),a[i-1]=*(p+i-2)*/ } for(i=0;i<N;i++) { /*輸出數組,每行輸出10個元素,共10行*/ if(i%5==0)printf("\n");/*換行*/ printf("%10d",*(p+i)); /*輸出*(p+i),也就是輸出a[i]*/ } printf("\n"); /*換行*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出如下:

01123 58132134 5589144233377 610987159725844181

請按任意鍵繼續...2.一維數組作為函數參數數組名就是數組的首地址。當把數組名作為實參來調用函數時,這就是傳址調用。在被調用函數中,C語言編譯器以指針變量作為形參接收數組的地址,該指針指向了數組的存儲空間。設a是一個以“inta[M];”(M是一個常量)定義的一維整型數組,假設函數f()無返回值,則調用函數為f(a)對應的f()函數首部可以有以下三種形式:

voidf(int*p); voidf(inta[]); voidf(inta[M]);對于后兩種形式,C編譯系統都將a處理成第一種的指針形式,函數對實參進行操作。例5.23用指針變量作函數形參,數組名作實參,試編寫程序求N個數的平均值。在主函數中定義數組a[N],在主程序中為數組輸入元素值后,用函數Average求平均值,具本程序代碼如下:#defineN10 /*定義常量*/floatAverage(float*p,intn) /*求p[0]~p[n-1]的平均值*/{ inti; /*定義整型變量i*/ floatsum=0; /*定義實型變量sum*/ for(i=0;i<n;i++)

sum+=*(p+i); /*累加求和*/

returnsum/n; /*返回平均值*/}…………intmain(void) /*主函數main()*/{ floata[N],av; /*定義變量與數組*/ inti; /*定義整型變量i*/

for(i=0;i<N;i++)

{ /*輸入數組元素值*/ printf("請輸入%d號元素值:",i); /*輸入提示*/ scanf("%f",a+i); /*輸入a[i]*/ }

av=Average(a,N); /*求平均值*/ printf("平均值:%f\n",av); /*輸出平均值*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出參考如下: 請輸入0號元素值:35

請輸入1號元素值:18.9

請輸入2號元素值:26.8

請輸入3號元素值:56.7

請輸入4號元素值:89.6

請輸入5號元素值:98.1

請輸入6號元素值:88.2

請輸入7號元素值:108.2

請輸入8號元素值:168

請輸入9號元素值:198

平均值:88.750000

請按任意鍵繼續...*5.10.2指針變量與二維數組1.二維數組元素的不同表示形式設有整型二維數組a[3][4]如下:

1 2 3 4 5 6 7 8 9 10 11 12 設用C語言可表示為:inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};例如a[0]數組,含有a[0][0],a[0][1],a[0][2],a[0][3]四個元素由于b[j]與*(b+j)等價,對于二維數組元素a[i][j],將分數組名a[i]當作b代入*(b+j)得到*(a[i]+j),也就是a[i][j]與*(a[i]+j)等價,再將a[i]替換為*(a+i)得到*(*(a+i)+j),這樣可知 a[i][j]、*(a[i]+j)與*(*(a+i)+j) 三者等價。C語言允許把一個二維數組分解為多個一維數組來處理,也就是數組a可分解為三個一維數組,即a[0],a[1],a[2],每一個一維數組又含有4個元素。例5.24求二維數組各元素之和。intmain(void) /*主函數main()*/{ inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}},i,j,s=0; /*定義數組與變量*/

for(i=0;i<3;i++) /*行*/ for(j=0;j<4;j++) /*列*/ s=s+a[i][j]; /*累加求和*/ printf("和為:%d\n",s); /*輸出各元素之和*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出參考如下: 和為:78

請按任意鍵繼續...讀者可將“s=s+a[i][j];”中的“a[i][j]”替換為“*(a[i]+j)”與“*(*(a+i)+j)”,并上機測試程序2.通過指向二維數組元素的指針變量來引用二維數組的元素每個二維數組元素就是一個類型為基類型的變量。指向二維數組元素的指針變量與指向基類型的指針變量相同。指向二維數組元素的指針變量定義的一般格式如下:基類型*指針變量名;例如:inta[3][4],*p=&a[0][0];例二維數組在內存中是按行連續存放的,當用指針變量指向二維數組的0行0列元素后,利用此指針變量就可以處理二維數組的任一個元素。例5.25求二維數組各元素之最大值。intmain(void) /*主函數main()*/{ inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}},i,*p= &a[0][0],m=a[0][0]; /*定義數組與變量*/

for(i=1;i<12;i++) { /*遍歷a[0][0]的其它元素*/ ++p; /*p移向下一個元素*/ if(*p>m)m=*p; /*比較求最大值*/ } printf("最大值為:%d\n",m); /*輸出各元素之最大值*/ system("PAUSE"); /*輸出系統提示信息*/ return0; /*返回值0,返回操作系統*/}程序運行時屏幕輸出參考如下: 最大值為:12

請按任意鍵繼續...3.通過指向行數組的行指針變量來引用二維數組的元素指向二維數組行數組的行指針變量一般的定義格式如下:基類型(*指針變量)[整型表達式]其中“整型表達式”指二維數組中的一維數組的元素個數,即對應二維數組定義中的“常量表達式2”。

行數組指針又稱為“數組指針”,意為:指向具有[整型表達式]個元素的數組的指針。定義:inta[3][4],(*p)[4];在這里,對于(*p)[4],“*”首先與p結合,表示p是一個指針變量,然后再與標識符“[4]”結合,表示指針變量p的基類型是一個包含有四個int元素的數組。數組a可分解為三個一維數組,即a[0],a[1],a[2],每一個一維數組又含有四個元素,也就是數組a可看成基類型為包含有四個int元素的數組的數組,所以p與a的基類型相同。如下語句:p=a;或p=&a[0];是合法的賦值語句。*(p+i)、*(a+i)與a[i]等價,而p[i]與*(p+i)等價,所以p[i]與a[i]等價,a[i][j]和p[i][j]等價。進一步可知*(*(a+i)+j)、*(*(p+i)+j)、*(a[i]+j)、*(p[i]+j)、a[i][j]和p[i][j]等價。例5.26求二維數組各元素之小值。intmain(void) /*主函數main()*/{ inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}},(*p)[4]=a; /*定義數組與行

溫馨提示

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

評論

0/150

提交評論