




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7章
指針目錄定義與引用指針指針與一維數(shù)組指針與字符串指針數(shù)組與多重數(shù)組指針與函數(shù)動態(tài)內(nèi)存分配216:12什么是指針所謂指針,就是內(nèi)存地址;所謂指針變量,也就是其值為內(nèi)存地址的變量。不同類型的變量占用不同長度的存儲空間,而不同類型的指針變量占用相同長度的存儲單元。指針可賦予不同的地址,通過指針可以間接操作其指向的變量。在C/C++語言中,指針變量存儲的內(nèi)容的是其所指向?qū)ο蟮氖椎刂?,指向的對象可以是變量、?shù)組、函數(shù)等占據(jù)存儲空間的實體。316:121.定義與引用指針程序運行時,每個變量都被存放在從某個內(nèi)存地址開始的若干字節(jié)中。所謂“指針”,也稱作“指針變量”,其存儲內(nèi)容是它所指向?qū)ο蟮氖椎刂?。指針變量的定義方法與普通變量基本相同,唯一的區(qū)別是必須在變量前加上一個“*”,表示該變量為指針變量。定義指針變量的一般格式為:類型*指針變量名;例如:inta=1; //①:定義一個整型變量a,賦初值為1int*p; //②:定義一個整型指針變量pp=&a; //③:p指向整型變量a;
②③int*p=&a;*p=3; //④:將p所指向的變量賦值為3,即將a賦值為3返回416:12例7.1:用指針方法編寫一個程序,輸入3個整數(shù),將它們按由小到大的順序輸出。
輸入:輸入以空格分隔的3個整數(shù)。
輸出:將三個整數(shù)按從小到大順序輸出。#include<iostream>usingnamespacestd;voidswap(int*pa,int*pb){ inttemp; temp=*pa; *pa=*pb; *pb=temp;}intmain(){ inta,b,c,temp;
cin>>a>>b>>c; if(a>b)swap(&a,&b); if(a>c)swap(&a,&c); if(b>c)swap(&b,&c); cout<<a<<“”<<b<<“”<<c; return0;}516:122.
指針與一維數(shù)組(2.1指針指向數(shù)組元素)一個數(shù)組的名字實際上就是一個指針,該指針指向這個數(shù)組存放的起始地址。如果定義如下數(shù)組:intarray[10];那么標識符“array”的類型就是int*,可以用array給一個int*類型的指針變量賦值。不過,數(shù)組名array代表數(shù)組的首地址,其值是編譯時已確定的常量,不允許對array賦值。返回616:12例7.2:編寫一個使用指針的函數(shù),交換數(shù)組a和數(shù)組b中的對應(yīng)元素。
輸入:輸入包括三行,第一行為一個正整數(shù)n,第二行為數(shù)組a的n個元素,第三行為數(shù)組b的n個元素。
輸出:將數(shù)組a和數(shù)組b中對應(yīng)的n個元素交換后,輸出兩行,第一行為數(shù)組a的n個元素(以空格分隔),第二行為數(shù)組b的n個元素。#include<iostream>usingnamespacestd;constintN=10;voidexchange(int*a,int*b,intn){ inttmp; for(inti=0;i<n;i++){ tmp=a[i];a[i]=b[i];b[i]=tmp; }}intmain(){ intx[N],y[N]; intn; cin>>n;716:12例7.2:編寫一個使用指針的函數(shù),交換數(shù)組a和數(shù)組b中的對應(yīng)元素。
輸入:輸入包括三行,第一行為一個正整數(shù)n,第二行為數(shù)組a的n個元素,第三行為數(shù)組b的n個元素。
輸出:將數(shù)組a和數(shù)組b中對應(yīng)的n個元素交換后,輸出兩行,第一行為數(shù)組a的n個元素(以空格分隔),第二行為數(shù)組b的n個元素。 for(inti=0;i<n;i++) cin>>x[i]; for(inti=0;i<n;i++) cin>>y[i]; exchange(x,y,n); for(inti=0;i<n;i++) cout<<x[i]<<“”; cout<<endl; for(inti=0;i<n;i++) cout<<y[i]<<“”; cout<<endl;}816:122.2指針的運算指針方式引用數(shù)組元素時,常使用指針的算術(shù)運算操作。指針可進行以下算術(shù)運算操作:(1)同類型的指針之間可以比較大??;(2)同類型的指針可以進行相減;(3)指針變量可以加減整型變量或常量;(4)指針變量可以自增、自減。如果p1、p2是兩個同類型“T*”的指針,那么當“地址p1<地址p2”時表達式“p1<p2”為真,反之為假。p1>p2、p1==p2含義類推。如果p1和p2是兩個同類型“T*”的指針,那么表達式“p2–p1”表示在地址p1和p2之間能夠存放多少個T類型的變量。即p2–p1=(地址p2-地址p1)/sizeof(T)。如果p是一個“T*”類型的指針,n是一個整型變量或常量,那么表達式“p+n”是一個類型為T*的指針,該指針指向的地址是:p+n*sizeof(T);“p-n”,“p++”,“p--”類推。916:12例7.3:編寫一個使用指針的程序,輸入一個字符串,找出其中的大寫字母,小寫字母,空格,數(shù)字,及其他字符的個數(shù)。
輸入:輸入一個字符串。
輸出:輸出該字符串中大寫字母,小寫字母,空格,數(shù)字,及其他字符的個數(shù)。#include<iostream>usingnamespacestd;intmain(){ inta=0,b=0,c=0,d=0,e=0; char*p,s[100]; cin.getline(s,100);
p=s; while(*p!=0){ if(*p>='A'&&*p<='Z')a++; elseif(*p>='a'&&*p<='z')b++; elseif(*p=='')c++; elseif(*p>='0'&&*p<='9')d++; elsee++; p++; } cout<<a<<""<<b<<""<<c<<""<<d<<""<<e; return0;}1016:122.3指針變量作為函數(shù)參數(shù)數(shù)組、動態(tài)分配的內(nèi)存等均是系列數(shù)據(jù)的集合,無法將其通過一個基本數(shù)據(jù)類型參數(shù)全部傳入函數(shù)內(nèi)部。此時可以將該系列數(shù)據(jù)的起始地址作為實參,將該實參傳遞給函數(shù)定義中的指針變量形參,然后在函數(shù)內(nèi)部通過指針運算符與指針變量訪問該系列數(shù)據(jù)。對于整數(shù)、小數(shù)、字符等基本類型數(shù)據(jù)的操作有時也必須要借助指針,一個典型的例子就是交換兩個變量的值。該例使用指針變量作為函數(shù)形參,以接收發(fā)生函數(shù)調(diào)用時從函數(shù)外部傳入的地址實參,從而可在函數(shù)內(nèi)部以指針方式間接訪問函數(shù)外部的數(shù)據(jù),這些數(shù)據(jù)不會隨著函數(shù)調(diào)用的結(jié)束而被銷毀。1116:12
≡例7.4:編寫一個使用指針作為形參的函數(shù),實現(xiàn)數(shù)組元素的逆置。
輸入:輸入兩行,第一行為一個正整數(shù)n,第二行為a數(shù)組的n個元素,以空格分隔。
輸出:將a數(shù)據(jù)元素逆置后輸出,元素間以空格分隔。#include<iostream>usingnamespacestd;constintN=10;voidinverse(int*x,intn);intmain(){ intn,a[N]; cin>>n; for(inti=0;i<n;i++)cin>>a[i]; inverse(a,n); for(inti=0;i<n;i++)cout<<a[i]<<""; return0;}voidinverse(int*x,intn){ int*p,*i,*j; intt; intm=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i<=p;i++,j--) t=*i,*i=*j,*j=t;}1216:123.指針與字符串字符串常量的類型是char*,字符數(shù)組名的類型當然也是char*。因此可以用一個字符串或一個字符數(shù)組名,給一個char*類型的指針變量賦值。返回1316:12#include<stdio.h>intmain(){ charstring[]="IloveChina!"; //定義字符數(shù)組sting printf("%s\n",string); //用%s格式聲明輸出string,可以輸出整個字符串
printf("%c\n",string[7]); //用%c格式輸出一個字符數(shù)組元素
return0;}#include<stdio.h>intmain(){ char*string="IloveChina!";
//定義字符指針變量string并初始化
printf("%s\n",string);
//輸出字符串
return0;}例7.5:編寫函數(shù)實現(xiàn)兩個字符串的比較。函數(shù)原型為:intstrcmp(char*p1,char*p2)
設(shè)置p1指向字符串s1,p2指向字符串s2。要求:當s1=s2時返回值為0;當s1不等于s2時返回它們兩者的第一個不同字符的ASCII碼差值(如”boy”與”bad”,第二個字母不同,’o’與’a’之差為79-65=14);如果s1>s2則輸出正值,如果s1<s2則輸出負值。#include<iostream>usingnamespacestd;intstrcmp(char*p1,char*p2);intmain(){ intm; chars1[100],s2[100],*p1,*p2; scanf(“%s”,str1); scanf(“%s”,str2); p1=&s1[0]; p2=&s2[0]; m=strcmp(p1,p2); cout<<m; return0;}intstrcmp(char*p1,char*p2){ inti=0; while(*(p1+i)==*(p2+i)) i++; if(*(p1+i)==0&&*(p2+i)==0)return0;
return*(p1+i)-*(p2+i);}1416:12例7.6:使用指針實現(xiàn)字符串復制函數(shù)voidstrcpy(char*s1,char*s2)。
輸入:輸入包括兩行,分別為字符串s1和s2。
輸出:將s1賦值為s2后,分兩行輸出s1和s2。#include<iostream>usingnamespacestd;voidstrcpy(char*s1,char*s2){ while(*s2!='\0'){ *s1=*s2; s1++; s2++; } *s1='\0';}intmain(){ chars1[100],s2[100]; cin.getline(s1,100); cin.getline(s2,100); strcpy(s1,s2); cout<<s1<<endl; cout<<s2<<endl; return0;}1516:12例7.7:字符串連接。用指針方式實現(xiàn)字符串連接函數(shù)char*StrCat(char*dest,char*src)。
輸入:輸入包括兩行,分別為字符串s1和s2。
輸出:把字符串s2復制到字符串s1后面(刪除s1原來末尾的“\0”),分兩行輸出s1和s2。#include<iostream>usingnamespacestd;char*StrCat(char*dest,char*src){
char*pdest=dest;while(*dest){dest++;}
while(*src){*dest=*src;dest++;src++;}*dest='\0';returnpdest;}
1616:12例7.7:字符串連接。用指針方式實現(xiàn)字符串連接函數(shù)char*StrCat(char*dest,char*src)。
輸入:輸入包括兩行,分別為字符串s1和s2。
輸出:把字符串s2復制到字符串s1后面(刪除s1原來末尾的“\0”),分兩行輸出s1和s2。
intmain(){chars1[200],s2[100];//增大s1的大小以容納連接后的字符串cin.getline(s1,100); cin.getline(s2,100);StrCat(s1,s2);cout<<s1<<endl;cout<<s2<<endl;return0;}1716:12例7.8:設(shè)計函數(shù)voidinsert(char*s1,char*s2,char*s,intn),用指針實現(xiàn)在字符串s1中的指定位置n處插入字符串s2得到字符串s。
輸入:輸入包括三行,前兩行分別為字符串s1和s2,第三行為一非負整數(shù)n。
輸出:s1在位置n處插入s2后的字符串s。#include<iostream>usingnamespacestd;voidinsert(char*s1,char*s2,char*s,intn){ intj=0; for(inti=0;i<n;i++)*s++=*s1++; while(*s2!='\0')*s++=*s2++; while(*s1!='\0')*s++=*s1++; *s='\0';}intmain(){ chars1[100],s2[100],s[200]; cin.getline(s1,100); cin.getline(s2,100); intn; cin>>n; insert(s1,s2,s,n); cout<<s<<endl; return0;}1816:12例7.9:每到月末,小明就會統(tǒng)計本月支出賬單,請編程幫助他完成任務(wù)。
輸入:第一行是整數(shù)n(n<100)。然后是n行的賬單信息,每一行由物品的名字name和對應(yīng)的花費c組成,長度不超過200。中間會有一個或多個空格,而每一行的開頭和結(jié)尾沒有空格。0.0<c<1000.0。
輸出:輸出總的花費,小數(shù)點后保留一位數(shù)字。#include<iostream>usingnamespacestd;intmain(){ inti,n; doublef,sum=0; stringstr; char*p; cin>>n; getchar(); //吸收整數(shù)后面的回車 for(i=0;i<n;i++){ getline(cin,str); p=&str[str.find_last_of("")]; //從后向前查找空格 p++; //指向空格后的數(shù)字 sscanf(p,"%lf",&f); //將字符串p轉(zhuǎn)換為實數(shù)
//f=atof(p); sum=sum+f; } cout<<sum<<endl; return0;}19輸入樣例:3Apple2.3Buyclothesforgirlfriends260.5Gotocinema30輸出樣例:292.816:12doubleatof(char*p){ doublesum=0; while(*p!='\0'&&*p!='.'){ sum=sum*10+*p-'0'; p++; } if(*p=='.'){ p++; intnum=10; while(*p!='\0'){ sum=sum+(*p-'0')*1.0/num; num=num*10; p++; } } returnsum;}sscanf(p,“%lf”,&f); //從字符串p中進行格式化輸入sprintf(str,“%d”,n);
//把格式化的數(shù)據(jù)輸出到字符串str中。
2016:124.指針數(shù)組與多重數(shù)組(4.1指向指針的指針)若一個指針變量存放的是另一個指針變量的地址,則稱其為指向指針的指針變量。定義指針的指針的一般格式為:類型**指針變量名;例如:int**p; 語句“int**p;”定義了一個指針變量p,p的類型是“int**”。在此情況下,通常稱p為“指針的指針”,因為p指向的是類型為“int*”的指針。同理,“int***p;”…,無論中間多少個“*”都是合法的定義。注意,不論p是幾級指針變量,在devc++中均占用4個字節(jié)內(nèi)存空間。返回2116:124.2指針數(shù)組一個數(shù)組的各個元素均為指針類型數(shù)據(jù),則稱該數(shù)組為指針數(shù)組。也就是說,指針數(shù)組中的每一個元素都是指針變量。定義指針數(shù)組的一般格式為:類型*數(shù)組名[常量表達式];例如:char*s[10];因為運算符[]的優(yōu)先級高于運算符*,所以上述定義也可寫成“char*(s[10]);”,即s先和[10]結(jié)合,形成s[10]形式,該形式為一個數(shù)組格式,共有10個元素;然后再和s前面的*結(jié)合,*表示指針類型,即每個數(shù)組元素均為一個指向字符數(shù)據(jù)的指針變量。2216:12例7.10:編寫程序,用指針數(shù)組在主函數(shù)中輸入n(n<10)個等長(長度<10)的字符串。用另一函數(shù)對它們排序,然后在主函數(shù)中輸出n個已排好序的字符串。
輸入:第一行為1個正整數(shù)n(n<10),然后是n行,每行一個字符串。
輸出:n行排序后的字符串。#include<iostream>#include<cstring>usingnamespacestd;voidsort(char*s[],intn){ char*temp; inti,j; for(i=0;i<n-1;i++) for(j=0;j<n-1-i;j++) if(strcmp(*(s+j),*(s+j+1))>0)temp=*(s+j),*(s+j)=*(s+j+1),*(s+j+1)=temp;}intmain(){ intn; cin>>n; charstr[10][10],*p[10]; for(inti=0;i<n;i++)p[i]=str[i]; //將第i個字符串的首地址賦給指針數(shù)組p的第i個元素 for(inti=0;i<n;i++)scanf("%s",p[i]); sort(p,n); for(inti=0;i<n;i++)printf("%s\n",p[i]); return0;}2316:124.3帶參數(shù)的main函數(shù)指針數(shù)組的一個重要應(yīng)用是用作main函數(shù)的形參,此時main()函數(shù)中允許帶2個參數(shù),一個為整型參數(shù)argc,另一個是指向字符類型的指針數(shù)組argv[]。定義帶參數(shù)的main函數(shù)頭的一般格式為:intmain(intargc,char*argv[])其中argc和argv是main函數(shù)的形參,它們是程序的命令行參數(shù):argc代表參數(shù)個數(shù),argv代表參數(shù)向量。這兩個參數(shù)可以用任何合法的標識符命名,但是習慣采用argc和argv。在調(diào)用帶參數(shù)的main()函數(shù)時加上參數(shù)即可,就如同使用DOS命令一樣。main函數(shù)由操作系統(tǒng)調(diào)用,在操作命令狀態(tài)下,實參由執(zhí)行文件時的命令給出。若在源文件file1.cpp中定義帶參數(shù)的main函數(shù)如下:#include<iostream>usingnamespacestd;intmain(intargc,char*argv[]){ for(inti=0;i<argc;i++) cout<<*(argv+i)<<endl; return0;}將file1.cpp生成可執(zhí)行文件后,若在命令狀態(tài)下輸入如下操作命令:file1chinazz則運行結(jié)果如下:file1chinazz2416:12下面程序的功能是:計算從命令行中輸入的第2個參數(shù)開始的所有參數(shù)中是回文字符串的參數(shù)個數(shù)。(順讀和倒讀都一樣的字符串稱為“回文”,如“l(fā)evel”就是回文)請?zhí)羁铡?include<stdio.h>
【1】
intsumhw(char**p,intn);charjughw(char*str);intmain(intargc,char*argv[]){ ints; if(argc<2)printf("請輸入有效參數(shù)\n"); else{ s=sumhw(
【2】
,argc-1); printf("共有%d個回文串\n",s); } return0;}intsumhw(char**p,intn){ charflag; inti,sum=0; for(i=0;i<n;i++) {flag=jughw(
【3】
); if(
【4】
)sum++;} returnsum;}charjughw(char*str){ char*p1,*p2; intn; n=strlen(str); p1=str; p2=
【5】
; while(
【6】
){ if(*p1!=*p2)break; else{p1++;
【7】
;} } if(
【8】
)return('N'); elsereturn('Y');}25#include<string.h>argv+1*(p+i)flag==’Y’str+n-1p1<p2p2--p1<p24.4指向數(shù)組的指針指向數(shù)組的指針是一個指針,該指針指向一個數(shù)組。定義指向數(shù)組的指針的一般格式為:類型(*數(shù)組名)[常量表達式];例如:int(*a)[10];因為*a處于小括號內(nèi),所以a先和*結(jié)合,形成*a形式,即a為一個指針;然后再和后面的[10]結(jié)合,即a為一個指向一維數(shù)組的指針變量,該一維數(shù)組的長度為10。2616:12例7.11:編寫一個包含指向數(shù)組的指針參數(shù)的函數(shù),將3*3矩陣轉(zhuǎn)置。
輸入:輸入一個3*3矩陣。
輸出:將該矩陣轉(zhuǎn)置后輸出。#include<iostream>usingnamespacestd;voidtrans(int(*matrix)[3]);intmain(){ inta[3][3]; for(inti=0;i<3;++i) for(intj=0;j<3;++j) cin>>a[i][j]; trans(a); for(inti=0;i<3;++i){ for(intj=0;j<3;++j) cout<<a[i][j]<<""; cout<<endl; } return0;}voidtrans(int(*matrix)[3]){ inttemp; inti,j; for(i=1;i<3;i++) for(j=0;j<i;j++){ temp=*(*(matrix+j)+i); *(*(matrix+j)+i)=*(*(matrix+i)+j); *(*(matrix+i)+j)=temp; }}2716:12例7.12:有一個班級,共n名學生,各學m門課程,請找出存在不及格課程的學生,并輸出其全部成績。
輸入:第一行為兩個正整數(shù)n(n<10)和m(n<10)。然后是n行,第i行為第i名學生的m門課程的成績,各門課程成績用空格隔開。
輸出:存在不及格課程的學生的m門課程成績,每名學生占一行,成績間用空格分隔。#include<iostream>usingnamespacestd;constintN=10,M=10;voidsearch(float(*p)[M],intn,intm){ //p是指向包含4個float型元素的一維數(shù)組的指針 inti,j,flag;
for(i=0;i<n;i++){
flag=0;
for(j=0;j<m;j++)if(*(*(p+i)+j)<60){flag=1;break;} //*(*(p+i)+j)就是score[i][j] if(flag==1){ cout<<i+1<<":"; for(j=0;j<m;j++) cout<<*(*(p+i)+j)<<""; cout<<endl; } }}intmain(){ intn,m;floatscore[N][M]; cin>>n>>m;
for(inti=0;i<n;++i) for(intj=0;j<m;++j) cin>>score[i][j]; search(score,n,m); //調(diào)用search函數(shù) return0;}2816:125.指針與函數(shù)(5.1返回指針的函數(shù))在C/C++語言中允許一個函數(shù)的返回值是一個指針(即地址),這種返回指針的函數(shù)稱為指針型函數(shù)。定義指針型函數(shù)的一般格式為:
類型*函數(shù)名(形參表)
{
……
/*函數(shù)體*/
}其中函數(shù)名之前加“*”號表明該函數(shù)是一個指針型函數(shù),即函數(shù)的返回值是一個指針,類型表示該指針所指向的數(shù)據(jù)類型。返回2916:12例7.13:有m個學生,每個學生有n門課程的成績(0<m,n<10)。要求在用戶輸入學生序號以后,能輸出該學生的全部成績。用返回指針的函數(shù)來實現(xiàn)。
輸入:第一行輸入三個正整數(shù)m,n,k;然后m行,第i行為學生序號為i的n門課程成績(以空格分隔)。
輸出:輸出序號為k的學生的n門課成績。#include<iostream>usingnamespacestd;constintM=10,N=10;float*search(float(*p)[N],intn); //函數(shù)聲明intmain(){ intm,n,k; floatscore[M][N]; cin>>m>>n>>k; for(inti=0;i<m;++i) for(intj=0;j<n;++j) cin>>score[i][j]; float*p; p=search(score,k); //調(diào)用search函數(shù),返回score[k-1][0]的地址 for(inti=0;i<n;++i) cout<<*(p+i)<<""; //輸出score[k-1][0]~score[k-1][n-1]的值 cout<<endl; return0;}float*search(float(*p)[N],intk){return*(p+k-1);}3016:125.2指向函數(shù)的指針指向函數(shù)的指針是一個指針變量,該指針指向一個函數(shù)。C/C++程序在編譯時會將每個函數(shù)的源碼轉(zhuǎn)換為可執(zhí)行代碼,并為每個函數(shù)分配一段存儲空間。因此每一個函數(shù)均有一個入口地址,當調(diào)用該函數(shù)時程序便轉(zhuǎn)入該函數(shù)的入口地址開始執(zhí)行。函數(shù)擁有地址屬性,因此可定義一個指針指向某一函數(shù)。定義指向函數(shù)的指針變量的一般格式為:類型(*指針變量名)();說明:(1)定義指向函數(shù)的指針變量,并不意味著這個指針變量可以指向任何函數(shù),它只能指向在定義函數(shù)指針時規(guī)定形式的函數(shù)。(2)將指針指向某函數(shù)后,既可通過函數(shù)名調(diào)用該函數(shù),也可通過指向該函數(shù)的指針調(diào)用該函數(shù)。(3)用函數(shù)指針變量調(diào)用函數(shù)時,只需將“(*指針變量名)”代替函數(shù)名,然后在“(*指針變量名)”之后的小括弧中根據(jù)需要寫上實參。(4)在一個程序中,一個指向函數(shù)的指針變量可以先后指向不同的函數(shù),在給函數(shù)指針變量賦值時僅需給出函數(shù)名而不必給出參數(shù)。(5)對于指向函數(shù)的指針變量,“++”、“--”、“+n”之類的指針運算不再有意義。(6)用函數(shù)名調(diào)用函數(shù)只能調(diào)用指定的一個函數(shù),而通過函數(shù)指針調(diào)用函數(shù)比較靈活,可根據(jù)需要先后指向不同的函數(shù)并加以調(diào)用,但這些函數(shù)必須與該指針變量具有相同的形式。返回3116:12例7.14:使用指向函數(shù)的指針,實現(xiàn)求兩個正數(shù)中的最大值與最小值。
輸入:輸入2個整數(shù)。
輸出:最大值和最小值。#include<iostream>usingnamespacestd;intmax(inta,intb){returna>=b?a:b;}intmin(inta,intb){returna<b?a:b;}intmain(){ inta,b; cin>>a>>b; int(*p)(int,int); //定義一個指向函數(shù)的指針 p=max; //將函數(shù)max的地址賦給函數(shù)指針p cout<<(*p)(a,b)<<endl; //通過函數(shù)指針p調(diào)用函數(shù)max p=min; //將函數(shù)max的地址賦給函數(shù)指針p cout<<(*p)(a,b)<<endl; //通過函數(shù)指針p調(diào)用函數(shù)min return0;}3216:126.動態(tài)內(nèi)存分配與指向它的指針變量全局變量是分配在內(nèi)存中的靜態(tài)存儲區(qū)的,非靜態(tài)的局部變量(包括形參)是分配在內(nèi)存中的動態(tài)存儲區(qū)的,這個存儲區(qū)是一個稱為棧(stack)的區(qū)域。除此以外,C語言還允許建立內(nèi)存動態(tài)分配區(qū)域,以存放一些臨時用的數(shù)據(jù),這些數(shù)據(jù)不必在程序的聲明部分定義,也不必等到函數(shù)結(jié)束時才釋放,而是需要時隨時開辟,不需要時隨時釋放。這些數(shù)據(jù)臨時存放在一個特別的自由存儲區(qū),稱為堆(heap)區(qū)??梢愿鶕?jù)需要,向系統(tǒng)申請所需大小的空間。由于未在聲明部分定義它們?yōu)樽兞炕驍?shù)組,因此不能通過變量名或數(shù)組名去引用這些數(shù)據(jù),只能通過指針來引用。33返回怎樣建立內(nèi)存的動態(tài)分配malloc函數(shù)開辟動態(tài)存儲區(qū)函數(shù)原型為:作用是在內(nèi)存的動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間。形參size的類型定為無符號整型(不允許為負數(shù))。此函數(shù)的值(即“返回值”)是所分配區(qū)域的第一個字節(jié)的地址,或者說,此函數(shù)是一個指針型函數(shù),返回的指針指向該分配域的第一個字節(jié)。指針的基類型為void,即不指向任何類型的數(shù)據(jù),只提供一個純地址。如果此函數(shù)未能成功地執(zhí)行(例如內(nèi)存空間不足),則返回空指針(NULL)。34void*malloc(unsignedintsize);malloc(100); //開辟100字節(jié)的臨時分配域,函數(shù)值為其第1個字節(jié)的地址怎樣建立內(nèi)存的動態(tài)分配用calloc函數(shù)開辟動態(tài)存儲區(qū)函數(shù)原型為作用是在內(nèi)存的動態(tài)存儲區(qū)中分配n個長度為size的連續(xù)空間,這個空間一般比較大,足以保存一個數(shù)組。用calloc函數(shù)可以為一維數(shù)組開辟動態(tài)存儲空間,n為數(shù)組元素個數(shù),每個元素長度為size。這就是動態(tài)數(shù)組。函數(shù)返回指向所分配域的第一個字節(jié)的指針;如果分配不成功,返回NULL。35p=calloc(50,4); //開辟50×4個字節(jié)的臨時分配域,把首地址賦給指針變量pvoid*calloc(unsignedn,unsignedsize);怎樣建立內(nèi)存的動態(tài)分配用realloc函數(shù)重新分配動態(tài)存儲區(qū)函數(shù)原型為如果已經(jīng)通過malloc函數(shù)或calloc函數(shù)獲得了動態(tài)空間,想改變其大小,可以用realloc函數(shù)重新分配。用realloc函數(shù)將p所指向的動態(tài)空間的大小改變?yōu)閟ize。p的值不變。如果重分配不成功,返回NULL。36realloc(p,50); //將p所指向的已分配的動態(tài)空間改為50字節(jié)void*realloc(void*p,unsignedintsize);怎樣建立內(nèi)存的動態(tài)分配用free函數(shù)釋放動態(tài)存儲區(qū)函數(shù)原型為作用是釋放指針變量p所指向的動態(tài)空間,使這部分空間能重新被其他變量使用。p應(yīng)是最近一次調(diào)用calloc或malloc函數(shù)時得到的函數(shù)返回值。
free函數(shù)無返回值。37free(p);
//釋放指針變量p所指向的已分配的動態(tài)空間voidfree(void*p);注意:以上函數(shù)的聲明在stdlib.h頭文件中,在用到這些函數(shù)時應(yīng)當用“#include<stdlib.h>”指令把stdlib.h頭文件包含到程序文件中。void指針類型C99允許使用基類型為void的指針類型??梢远x一個基類型為void的指針變量(即void*型變量),它不指向任何類型的數(shù)據(jù)。在將它的值賦給另一指針變量時由系統(tǒng)對它進行類型轉(zhuǎn)換,使之適合于被賦值的變量的類型。int*pt;pt=(int*)malloc(100);
//mcaloc(100)是void*型,把它轉(zhuǎn)換為int*型38注意不要把“指向void類型”理解為能指向“任何的類型”的數(shù)據(jù),而應(yīng)理解為“指向空類型”或“不指向確定的類型”的數(shù)據(jù)。6.動態(tài)內(nèi)存分配(6.1分配單個元素空間)數(shù)組的長度是預(yù)先定義好的,在整個程序中固定不變。C/C++中不允許定義元素個數(shù)不確定的數(shù)組。例如:intn;inta[n]; //此定義不允許在實際的程序設(shè)計中,常遇到暫時無法確定所需內(nèi)存空間大小的情形。如果定義一個盡可能大的數(shù)組,又會造成空間浪費。為此,C++提供了一種“動態(tài)內(nèi)存分配”的機制,使得程序可以在運行期間,根據(jù)實際需要,要求系統(tǒng)臨時分配一片內(nèi)存空間用于存放數(shù)據(jù)。此種內(nèi)存分配是在程序運行中進行的,而不是在編譯時就確定的,故稱為“動態(tài)內(nèi)存分配”。在C++中通過“new”運算符來實現(xiàn)動態(tài)內(nèi)存分配。new運算符的一般使用格式為:p=newT;其中,T是任意類型名,p是類型為T*的指針。執(zhí)行該語句后,系統(tǒng)會動態(tài)分配出一片大小為sizeof(T)字節(jié)的內(nèi)存空間,并且將該內(nèi)存空間的起始地址賦值給P。例如:int*p;p=newint; //①*p=5;語句①動態(tài)分配了一片4字節(jié)大小的內(nèi)存空間,整型指針p指向這片空間的起始地址。返回3916:126.2分配多個元素空間new運算符還可以用來動態(tài)分配一個任意大小的數(shù)組:p=newT[n];T是任意類型名,p是類型為T*的指針,n代表“元素個數(shù)”,它可以是任何值為正整數(shù)的表達式,表達式中可以包含變量、函數(shù)調(diào)用。該語句成功執(zhí)行后,系統(tǒng)動態(tài)分配n*sizeof(T)個字節(jié)的連續(xù)內(nèi)存空間,并將這片連續(xù)內(nèi)存空間的起始地址賦給p。如果要求分配的空間太大,系統(tǒng)無法滿足,那么動態(tài)內(nèi)存分配就會失敗。因此,通常在進行較大的動態(tài)內(nèi)存分配時,要判斷該內(nèi)存分配是否成功。判斷的方法如下:int*p=newint[400]; //int*p=(int*)malloc(100*sizeof(int));if(p==NULL)printf(“內(nèi)存分配失敗”);elseprintf(“內(nèi)存分配成功”);4016:126.3釋放空間使用完系統(tǒng)動態(tài)分配的內(nèi)存空間后,程序應(yīng)及時釋放該空間,以便其他程序能夠動態(tài)申請使用。C++提供“delete”運算符釋放動態(tài)分配的內(nèi)存空間。delete運算符的基本用法是:delete指針;該指針必須已指向動態(tài)分配的內(nèi)存空間,否則運行時很可能會出錯。例如:int*p=newint;*p=5;deletep;deletep; //本句會導致程序異常以上第一條delete語句正確地釋放了動態(tài)分配的4個字節(jié)內(nèi)存空間。第二條delete語句會導致程序出錯,因為p所指向的空間已經(jīng)釋放。4116:12如果使用new運算符動態(tài)分配了一個數(shù)組,那么釋放該數(shù)組時應(yīng)以如下形式使用delete運算符:delete[]指針;例如:int*p=newint[20];p[0]=1;delete[]p;同樣要求被delete的指針p必須是已指向動態(tài)分配的內(nèi)存空間的指針,否則會報錯。如果動態(tài)分配了一個數(shù)組,但是卻用“delete指針”的方式釋放,則程序編譯時不會報錯,程序運行時也不會發(fā)現(xiàn)異常,但實際上該動態(tài)分配的內(nèi)存空間沒有被完全釋放。使用new運算符動態(tài)分配的內(nèi)存空間,一定要使用delete運算符及時予以釋放。否則,即便程序運行已經(jīng)結(jié)束,系統(tǒng)也不會收回該內(nèi)存空間。若可用內(nèi)存被大量消耗,則會導致操作系統(tǒng)運行速度變得越來越慢,甚至無法再啟動新的程序運行。4216:12例7.15:有n個整數(shù),使前面各數(shù)順序向后移動k個位置,移出的數(shù)再從開頭移入。
輸入:輸入分2行,第一行是兩個整數(shù)n,k,第二行是n個整數(shù),用空格隔開。
輸出:輸出占一行,為移動之后的n個數(shù)組元素,由空格分隔。#include<iostream>usingnamespacestd;voidringShift(int*a,intn,intk){ int*b=newint[k]; for(inti=0;i<k;i++) b[i]=a[n-k+i]; for(inti=n-1;i-k>=0;i--) a[i]=a[i-k]; for(inti=0;i<k;i++) a[i]=b[i]; delete[]b;}intmain(){ intn,k; cin>>n>>k; int*a=newint[n]; for(inti=0;i<n;i++)
cin>>a[i];
ringShift(a,n,k); for(inti=0;i<n;i++)
cout<<a[i]<<""; delete[]a; return0;}4316:12例7.16:數(shù)組a中有m個按升序序排列的元素,數(shù)組b中有n個降序排列的元素,編程將所有元素按降序存入數(shù)組c中。
輸入:輸入有兩行,第一行首先是一個正整數(shù)m,然后是m個整數(shù);第二行首先是一個正整數(shù)n,然后是n個整數(shù),m,n均小于等于1000000。
輸出:輸出合并后的m+n個整數(shù),數(shù)據(jù)之間用空格隔開。輸出占一行。#include<iostream>usingnamespacestd;intmain(){ intm,n,i,j,k; cin>>m; int*a=newint[m]; for(i=0;i<m;i++)
cin>>a[i]; cin>>n; int*b=newint[n]; for(i=0;i<n;i++)
cin>>b[i]; i=m-1;j=0;k=0; int*c=newint[m+n]; while(i>=0&&j<n){ if(a[i]>b[j])c[k++]=a[i--]; elsec[k++]
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- DB31/T 1181-2019天然飾面石材加工單位產(chǎn)品能源消耗限額
- DB31/ 283-2015戶外廣告設(shè)施設(shè)置技術(shù)規(guī)范
- 草原割草與草原文化傳承考核試卷
- 跨境環(huán)保公交車融資項目考核試卷
- 糖果市場滲透策略與市場占有率考核試卷
- 2024年電子液壓萬能試驗機資金申請報告代可行性研究報告
- 2025年Web技術(shù)相關(guān)性分析試題及答案
- 2025年中國保鮮劑行業(yè)市場規(guī)模調(diào)研及投資前景研究分析報告
- 資產(chǎn)評估機構(gòu)與金融機構(gòu)股權(quán)合作投資管理協(xié)議
- 音樂節(jié)現(xiàn)場臨時舞臺搭建及現(xiàn)場管理服務(wù)合同
- 2024年上海市高考語文真題現(xiàn)代文二《斑鳩》簡析及相關(guān)常規(guī)題型歸納
- 七年級下冊英語語法填空專項訓練100題含答案5篇
- 配電室火災(zāi)應(yīng)急處置預(yù)案
- 2024年高考英語考前押題密卷(全國卷1)(含答案與解析)
- 遼寧省盤錦市遼河油田實驗中學2023-2024學年九年級下學期開學考試數(shù)學試題(原卷版)
- 中小學-預(yù)防性騷擾與性侵害-1-課件
- xx市體育中心設(shè)計說明
- 2024年江蘇省南通市如皋市中考一模語文試題
- 2024-2030年中國納米抗體藥物行業(yè)運行現(xiàn)狀及發(fā)展行情監(jiān)測研究報告
- 2023年高考物理分題型多維刷題練專題19熱學中的變質(zhì)量氣體問題(原卷版+解析)
- 如何喚醒孩子學習的內(nèi)驅(qū)力
評論
0/150
提交評論