C++動(dòng)態(tài)分配和撤銷內(nèi)存以及結(jié)構(gòu)體類型作為函數(shù)參數(shù)
C++動(dòng)態(tài)分配內(nèi)存(new)和撤銷內(nèi)存(delete)
在軟件開發(fā)過程中,常常需要?jiǎng)討B(tài)地分配和撤銷內(nèi)存空間,例如對動(dòng)態(tài)鏈表中結(jié)點(diǎn)的插入與刪除。在C語言中是利用庫函數(shù)malloc和free來分配和撤銷內(nèi)存空間的。C++提供了較簡便而功能較強(qiáng)的運(yùn)算符new和delete來取代malloc和free函數(shù)。
注意: new和delete是運(yùn)算符,不是函數(shù),因此執(zhí)行效率高。
雖然為了與C語言兼容,C++仍保留malloc和free函數(shù),但建議用戶不用malloc和free函數(shù),而用new和delete運(yùn)算符。new運(yùn)算符的例子:
new int; //開辟一個(gè)存放整數(shù)的存儲(chǔ)空間,返回一個(gè)指向該存儲(chǔ)空間的地址(即指針) new int(100); //開辟一個(gè)存放整數(shù)的空間,并指定該整數(shù)的初值為100,返回一個(gè)指向該存儲(chǔ)空間的地址 new char[10]; //開辟一個(gè)存放字符數(shù)組(包括10個(gè)元素)的空間,返回首元素的地址 new int[5][4]; //開辟一個(gè)存放二維整型數(shù)組(大小為5*4)的空間,返回首元素的地址 float *p=new float (3.14159); //開辟一個(gè)存放單精度數(shù)的空間,并指定該實(shí)數(shù)的初值為//3.14159,將返回的該空間的地址賦給指針變量p
new運(yùn)算符使用的一般格式為:
new 類型 [初值];
用new分配數(shù)組空間時(shí)不能指定初值。如果由于內(nèi)存不足等原因而無法正常分配空間,則new會(huì)返回一個(gè)空指針NULL,用戶可以根據(jù)該指針的值判斷分配空間是否成功。
delete運(yùn)算符使用的一般格式為:
delete [ ] 指針變量
例如要撤銷上面用new開辟的存放單精度數(shù)的空間(上面第例,應(yīng)該用
delete p;
前面用“new char[10];”開辟的字符數(shù)組空間,如果把new返回的指針賦給了指針變量pt,則應(yīng)該用以下形式的delete運(yùn)算符撤銷該空間:
delete [] pt; //在指針變量前面加一對方括號,表示是對數(shù)組空間的操作
【例】開辟空間以存放一個(gè)結(jié)構(gòu)體變量。
#include <iostream> #include <string> using namespace std; struct Student //聲明結(jié)構(gòu)體類型Student { string name; int num; char sex; }; int main( ) { Student *p; //定義指向結(jié)構(gòu)體類型Student的數(shù)據(jù)的指針變量 p=new Student; //用new運(yùn)算符開辟一個(gè)存放Student型數(shù)據(jù)的空間 p->name="Wang Fun"; //向結(jié)構(gòu)體變量的成員賦值 p->num=10123; p->sex='m'; cout<<p->name<<endl<<p->num <<endl<<p->sex<<endl; //輸出各成員的值 delete p; //撤銷該空間 return 0; }
運(yùn)行結(jié)果為:
Wang Fun 10123 m
圖為new student開辟的空間。
在動(dòng)態(tài)分配/撤銷空間時(shí),往往將這兩個(gè)運(yùn)算符和結(jié)構(gòu)體結(jié)合使用,是很有效的??梢钥吹剑?br />
要訪問用new所開辟的結(jié)構(gòu)體空間,無法直接通過變量名進(jìn)行,只能通過指針p進(jìn)行訪問。如果要建立一個(gè)動(dòng)態(tài)鏈表,必須從第一個(gè)結(jié)點(diǎn)開始,逐個(gè)地開辟結(jié)點(diǎn)并輸入各結(jié)點(diǎn)數(shù)據(jù),通過指針建立起前后相鏈的關(guān)系。
C++結(jié)構(gòu)體類型作為函數(shù)參數(shù)
將一個(gè)結(jié)構(gòu)體變量中的數(shù)據(jù)傳遞給另一個(gè)函數(shù),有下列3種方法:
用結(jié)構(gòu)體變量名作參數(shù)。一般較少用這種方法。
用指向結(jié)構(gòu)體變量的指針作實(shí)參,將結(jié)構(gòu)體變量的地址傳給形參。
用結(jié)構(gòu)體變量的引用變量作函數(shù)參數(shù)。
下面通過一個(gè)簡單的例子來說明,并對它們進(jìn)行比較。
【例】有一個(gè)結(jié)構(gòu)體變量stu,內(nèi)含學(xué)生學(xué)號、姓名和3門課的成績。要求在main函數(shù)中為各成員賦值,在另一函數(shù)print中將它們的值輸出。
1) 用結(jié)構(gòu)體變量作函數(shù)參數(shù)。
#include <iostream> #include <string> using namespace std; struct Student//聲明結(jié)構(gòu)體類型Student { int num; char name[20]; float score[3]; }; int main( ) { void print(Student); //函數(shù)聲明,形參類型為結(jié)構(gòu)體Student Student stu; //定義結(jié)構(gòu)體變量 stu.num=12345; //以下5行對結(jié)構(gòu)體變量各成員賦值 stu.name="Li Fung"; stu.score[0]=67.5; stu.score[1]=89; stu.score[2]=78.5; print(stu); //調(diào)用print函數(shù),輸出stu各成員的值 return 0; } void print(Student st) { cout<<st.num<<" "<<st.name<<" "<<st.score[0] <<" " <<st.score[1]<<" "<<st.score[2]<<endl; }
運(yùn)行結(jié)果為:
12345 Li Fung 67.5 89 78.5 (2)
2)用指向結(jié)構(gòu)體變量的指針作實(shí)參在上面程序的基礎(chǔ)上稍作修改即可。
#include <iostream> #include <string> using namespace std; struct Student { int num; string name; //用string類型定義字符串變量 float score[3]; }stu={12345,"Li Fung",67.5,89,78.5}; //定義結(jié)構(gòu)體student變量stu并賦初值 int main( ) { void print(Student *); //函數(shù)聲明,形參為指向Student類型數(shù)據(jù)的指針變量 Student *pt=&stu; //定義基類型為Student的指針變量pt,并指向stu print(pt); //實(shí)參為指向Student類數(shù)據(jù)的指針變量 return 0; } //定義函數(shù),形參p是基類型為Student的指針變量 void print(Student *p) { cout<<p->num<<" "<<p->name<<" "<<p->score[0]<<" " << p->score[1]<<" "<<p->score[2]<<endl; }
調(diào)用print函數(shù)時(shí),實(shí)參指針變量pt將stu的起始地址傳送給形參p(p也是基類型為student的指針變量)。這樣形參p也就指向stu,見圖。
在print函數(shù)中輸出p所指向的結(jié)構(gòu)體變量的各個(gè)成員值,它們也就是stu的成員值。在main函數(shù)中也可以不定義指針變量pt,而在調(diào)用print函數(shù)時(shí)以&stu作為實(shí)參,把stu的起始地址傳給實(shí)參p。
3) 用結(jié)構(gòu)體變量的引用作函數(shù)參數(shù)
#include <iostream> #include <string> using namespace std; struct Student { int num; string name; float score[3]; }stu={12345,"Li Li",67.5,89,78.5}; int main( ) { void print(Student &); //函數(shù)聲明,形參為Student類型變量的引用 print(stu); //實(shí)參為結(jié)構(gòu)體Student變量 return 0; } //函數(shù)定義,形參為結(jié)構(gòu)體Student變量的引用 void print(Student &stud) { cout<<stud.num<<" "<<stud.name<<" "<<stud.score[0] <<" " <<stud.score[1]<<" "<<stud.score[2]<<endl; }
程序(1)用結(jié)構(gòu)體變量作實(shí)參和形參,程序直觀易懂,效率是不高的。
程序(2)采用指針變量作為實(shí)參和形參,空間和時(shí)間的開銷都很小,效率較高。但程序(2)不如程序(1)那樣直接。
程序(3)的實(shí)參是結(jié)構(gòu)體Student類型變量,而形參用Student類型的引用,虛實(shí)結(jié)合時(shí)傳遞的是stu的地址,因而效率較高。它兼有(1)和(2)的優(yōu)點(diǎn)。
引用變量主要用作函數(shù)參數(shù),它可以提高效率,而且保持程序良好的可讀性。在本例中用了string方法定義字符串變量,在某些C++系統(tǒng)中目前不能運(yùn)行這些程序,讀者可以修改程序,使之能在自己所用的系統(tǒng)中運(yùn)行。
- C++中結(jié)構(gòu)體的類型定義和初始化以及變量引用
- C++中聲明類的class與聲明結(jié)構(gòu)體的struct關(guān)鍵字詳解
- C++結(jié)構(gòu)體struct和類class區(qū)別詳解
- C++結(jié)構(gòu)體與類指針知識點(diǎn)總結(jié)
- C++關(guān)于類結(jié)構(gòu)體大小和構(gòu)造順序,析構(gòu)順序的測試詳解
- C++類結(jié)構(gòu)體與json相互轉(zhuǎn)換
- C++結(jié)構(gòu)體與類的區(qū)別詳情
- C++?中的?JSON?序列化和反序列化及結(jié)構(gòu)體與枚舉類型的處理方法
- C++ 中類(class)和結(jié)構(gòu)體(struct)的區(qū)別
相關(guān)文章
VC++實(shí)現(xiàn)CStdioFile寫入及讀取文件并自動(dòng)換行的方法
這篇文章主要介紹了VC++實(shí)現(xiàn)CStdioFile寫入及讀取文件并自動(dòng)換行的方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08C語言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解
單向鏈表(單鏈表)是鏈表的一種,其特點(diǎn)是鏈表的鏈接方向是單向的,對鏈表的訪問要通過順序讀取從頭部開始。本文將為大家詳細(xì)講講單向鏈表的實(shí)現(xiàn)與使用,需要的可以參考一下2022-08-08C++11的future和promise、parkged_task使用
這篇文章主要介紹了C++11的future和promise、parkged_task使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04詳解Qt中的雙緩沖機(jī)制與實(shí)例應(yīng)用
所謂雙緩沖機(jī)制,是指在繪制控件時(shí),首先將要繪制的內(nèi)容繪制在一個(gè)圖片中,再將圖片一次性地繪制到控件上。本文主要為大家介紹了Qt中的雙緩沖機(jī)制與實(shí)例應(yīng)用,希望對大家有所幫助2023-03-03C語言 ffmpeg與sdl實(shí)現(xiàn)播放視頻同時(shí)同步時(shí)鐘詳解
使用ffmpeg和sdl實(shí)現(xiàn)播放視頻后,需要再實(shí)現(xiàn)時(shí)鐘同步才能正常的播放視頻,尤其是有音頻的情況,我們通常需要將視頻同步到音頻來確保音畫同步2022-09-09