【C++复习总结回顾】—— 【五】数组与指针
需要更好的閱讀的體驗(yàn)請(qǐng)移步 👉 小牛肉的個(gè)人博客 👈
文章目錄
- 一、數(shù)組
- 1. 數(shù)組的存儲(chǔ)與初始化
- 一維數(shù)組
- 二維數(shù)組
- 2. 數(shù)組作為函數(shù)參數(shù)
- 3. 對(duì)象數(shù)組
- 二、指針
- 1. 指針運(yùn)算符 * 和 &
- 2. 指針變量的賦值運(yùn)算
- 3. 指針的類(lèi)型
- 指向常量的指針 const int * p
- 指針類(lèi)型的常量 int * const p
- 4. 指針的算法運(yùn)算、關(guān)系運(yùn)算
- 5. 用指針訪(fǎng)問(wèn)數(shù)組元素
- 6. 指針數(shù)組 Point *p[2]
- 7. 指針與函數(shù)
- 指針作為函數(shù)參數(shù)
- 指針類(lèi)型的函數(shù)
- 函數(shù)類(lèi)型的指針
- 8. 對(duì)象指針
- 9. this 指針
- 10. 動(dòng)態(tài)內(nèi)存分配
- new 動(dòng)態(tài)分配
- delete 釋放動(dòng)態(tài)分配的內(nèi)存
- 三、自定義動(dòng)態(tài)數(shù)組類(lèi) ArrofPoints
- 四、Vector類(lèi)模板(C++標(biāo)準(zhǔn)庫(kù)中的)
- 五、深復(fù)制與淺復(fù)制
- 淺復(fù)制
- 深復(fù)制(重新編寫(xiě)復(fù)制構(gòu)造函數(shù))
- 六、字符串
- 七、手?jǐn)]String類(lèi)
一、數(shù)組
1. 數(shù)組的存儲(chǔ)與初始化
一維數(shù)組
二維數(shù)組
2. 數(shù)組作為函數(shù)參數(shù)
3. 對(duì)象數(shù)組
對(duì)象數(shù)組——線(xiàn)性回歸方程實(shí)例
二、指針
1. 指針運(yùn)算符 * 和 &
- * 稱(chēng)為指針運(yùn)算符,也稱(chēng)解析;
- & 稱(chēng)為取地址運(yùn)算符;
2. 指針變量的賦值運(yùn)算
3. 指針的類(lèi)型
指向常量的指針 const int * p
* 在const的右邊
指針類(lèi)型的常量 int * const p
* 在const的左邊
4. 指針的算法運(yùn)算、關(guān)系運(yùn)算
5. 用指針訪(fǎng)問(wèn)數(shù)組元素
6. 指針數(shù)組 Point *p[2]
7. 指針與函數(shù)
指針作為函數(shù)參數(shù)
為什么需要用指針做參數(shù)?
- 需要數(shù)據(jù)雙向傳遞時(shí)(引用也可以達(dá)到此效果);
用指針作為函數(shù)的參數(shù),可以使被調(diào)函數(shù)通過(guò)形參指針存取主調(diào)函數(shù)中實(shí)參指針指向的數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的雙向傳遞 - 需要傳遞一組數(shù)據(jù),只傳首地址運(yùn)行效率比較高 ;
實(shí)參是數(shù)組名時(shí),形參可以是指針
引用和指針有何區(qū)別?何時(shí)只能用指針而不能使用引用
- 引用是一個(gè)別名,不能為空,不能被重新分配;指針是一個(gè)存放地址的變量。
- 當(dāng)需要對(duì)變量重新賦以另外的地址或賦值為NULL時(shí)只能使用指針
指針類(lèi)型的函數(shù)
若函數(shù)的返回值是指針,該函數(shù)就是指針類(lèi)型的函數(shù)
int * function(){ }函數(shù)類(lèi)型的指針
即指向函數(shù)的指針
定義:數(shù)據(jù)類(lèi)型 (* 函數(shù)指針名)(形參表)
int (*func)(int, int)
含義:函數(shù)指針指向的是程序代碼存儲(chǔ)區(qū)。
8. 對(duì)象指針
定義形式:類(lèi)名 *對(duì)象指針名
Point *ptr; Point a(5,10); ptr = &a;對(duì)象指針通過(guò) -> 訪(fǎng)問(wèn)對(duì)象成員
ptr->getx() 相當(dāng)于 (*ptr).getx();
9. this 指針
10. 動(dòng)態(tài)內(nèi)存分配
首先我們需要分清幾個(gè)概念
int *point = new int(5); //用5初始化
int *point = new int(); //用0初始化
int *point = new int; //不分配初值
int *point = new int[5] //表示為該指針?lè)峙浒畟€(gè)元素的地址空間
同一個(gè)程序有可能會(huì)處理很大的數(shù)據(jù),有時(shí)處理很小,若總是以最大的空間內(nèi)存分配,難免會(huì)造成浪費(fèi)。
- 在C語(yǔ)言中,用 malloc 進(jìn)行動(dòng)態(tài)內(nèi)存分配;
- 在C++中,用 new 語(yǔ)句
new 動(dòng)態(tài)分配
動(dòng)態(tài)分配一個(gè)變量
p = new T; //T代表int,double,float等等 //p類(lèi)型為T(mén)*的指針 //該語(yǔ)句動(dòng)態(tài)分配了一片大小為 sizeof(T) 字節(jié)的內(nèi)存空間,并將起始地址賦給了p int *pn; pn = new int; *pn = 5; //往剛開(kāi)辟的空間中寫(xiě)入了數(shù)據(jù)5動(dòng)態(tài)分配一個(gè)數(shù)組
p = new T[N]; //動(dòng)態(tài)分配了一片大小為 sizeof(T)*N 字節(jié)的內(nèi)存空間,并將起始地址賦給了p int *pn; int i = 5; pn = new int[i*20]; //100個(gè)元素,最大合法下標(biāo)為99 pn[0] = 20; pn[100] = 30; // 編譯沒(méi)問(wèn)題,運(yùn)行時(shí)數(shù)組越界注:new運(yùn)算符返回值類(lèi)型都是 T*
delete 釋放動(dòng)態(tài)分配的內(nèi)存
delete總是和new成對(duì)出現(xiàn) :即動(dòng)態(tài)分配的內(nèi)存一定要釋放掉,否則占用的內(nèi)存就會(huì)越來(lái)越多。
delete指針
該指針必須指向new出來(lái)的空間
delete [ ]指針
int *p = new int[20]; p[0] = 1; delete []p; //若delete p 則只刪除了一部分,沒(méi)有刪干凈三、自定義動(dòng)態(tài)數(shù)組類(lèi) ArrofPoints
將數(shù)組的建立和刪除過(guò)程封裝起來(lái),數(shù)組下標(biāo)越界檢查
四、Vector類(lèi)模板(C++標(biāo)準(zhǔn)庫(kù)中的)
為什么需要vector
- 封裝任何類(lèi)型的動(dòng)態(tài)數(shù)組,自動(dòng)創(chuàng)建和刪除
- 數(shù)組下標(biāo)越界檢查
vector對(duì)象的定義
vector<元素類(lèi)型> 數(shù)組對(duì)象名(數(shù)組長(zhǎng)度)
- vector<int> arr(5) 建立大小為5的int數(shù)組
- vector<int> arr(5,2) 大小為5的int類(lèi)型數(shù)組,所有元素用2初始化
vector對(duì)象的使用
- 對(duì)數(shù)組元素的引用 :
與普通數(shù)組具有相同形式: vector對(duì)象名 [ 下標(biāo)表達(dá)式 ]
vector數(shù)組對(duì)象名不表示數(shù)組首地址 ,因?yàn)閿?shù)組對(duì)象不是數(shù)組,而是封裝了數(shù)組的對(duì)象 - 獲得數(shù)組長(zhǎng)度 :用size函數(shù) 數(shù)組對(duì)象名.size()
vector應(yīng)用舉例:
五、深復(fù)制與淺復(fù)制
以上面的自定義動(dòng)態(tài)數(shù)組類(lèi) ArrayOfPoints 為例
淺復(fù)制
ArrayOfPoints pointsArray2(pointsArray1); //創(chuàng)建副本
- pointsArray1和pointsArray2有相同的值,表面上好像完成了復(fù)制,但是指向的是同一個(gè)內(nèi)存空間,并沒(méi)有形成真正的副本,當(dāng)程序中改變pointsArray1時(shí)也會(huì)改變pointsArray2。
- 而且,在程序結(jié)束之前,pointsArray1和pointsArray2的析構(gòu)函數(shù)會(huì)自動(dòng)調(diào)用,動(dòng)態(tài)分配的內(nèi)存空間被釋放,由于兩個(gè)對(duì)象給公用了同一塊內(nèi)存空間,因此該空間被釋放兩次,導(dǎo)致運(yùn)行錯(cuò)誤。
深復(fù)制(重新編寫(xiě)復(fù)制構(gòu)造函數(shù))
核心思想:重新new一個(gè)存儲(chǔ)空間進(jìn)行值的復(fù)制操作
六、字符串
詳見(jiàn)第一章 【C++復(fù)習(xí)總結(jié)回顧】—— 【一】基礎(chǔ)知識(shí)+字符串/string類(lèi)
七、手?jǐn)]String類(lèi)
設(shè)計(jì)一個(gè)字符串類(lèi)MyString,具有構(gòu)造函數(shù)、析構(gòu)函數(shù)、復(fù)制構(gòu)造函數(shù)、并重載運(yùn)算符 +、=、+=、[ ],盡可能的完善它,使之能滿(mǎn)足各種需要。
#include<iostream> #include<cstring> using namespace std; class Mystring{private:char* mystring; //字符指針int len; //字符串長(zhǎng)度Mystring(int clen){ //私有構(gòu)造,防止其他類(lèi)進(jìn)行調(diào)用創(chuàng)建實(shí)例,只使用一次(在+重載)mystring = new char[clen + 1];for (int i = 0; i < clen; i++)mystring[i] = '\0';len = clen;}public:Mystring(); //無(wú)參構(gòu)造Mystring(const char* const cmystring); //帶參構(gòu)造Mystring(const Mystring& rhs); //復(fù)制構(gòu)造~Mystring(); //析構(gòu)int getLen() const{ //獲取長(zhǎng)度return this->len;}const char *GetMyString() const{ //獲取字符串return mystring;}char & operator[](int offset); //重載下標(biāo)運(yùn)算符,作為左值可被修改,需返回引用char operator [](int offset) const; //重載下標(biāo)運(yùn)算符,作為右值僅能訪(fǎng)問(wèn)Mystring operator +(const Mystring& rhs); //a+b a的值并不會(huì)被修改,不需要返回引用void operator +=(const Mystring& rhs); //a+=b 無(wú)返回值Mystring& operator =(const Mystring& rhs); //a=b a的值會(huì)被修改,需要返回引用 }; //無(wú)參構(gòu)造 Mystring::Mystring(){mystring = new char[1];mystring[0] = '\0';len = 0; } //帶參構(gòu)造 Mystring::Mystring(const char* const cmystring){len = strlen(cmystring);mystring = new char[len+1];for(int i = 0; i<len; i++)mystring[i] = cmystring[i];mystring[len] = '\0'; } //復(fù)制構(gòu)造 Mystring::Mystring(const Mystring& rhs){len = rhs.getLen();mystring = new char[len+1];for(int i = 0; i<len;i++)mystring[i] = rhs[i];mystring[len] = '\0'; } //析構(gòu) Mystring::~Mystring(){delete[] mystring;len = 0; } char& Mystring::operator[](int offset){if(offset>len) //若超出最大長(zhǎng)度,返回最后一位字符return mystring[len-1];elsereturn mystring[offset]; } char Mystring::operator[](int offset) const {if (offset > len) //若超出最大長(zhǎng)度,返回最后一位字符return mystring[len - 1];elsereturn mystring[offset]; } //字符串連接+重載 Mystring Mystring :: operator +(const Mystring& rhs){int totallen = len + rhs.getLen();Mystring str(totallen);int i = 0;for(;i<len;i++)str[i] = mystring[i];for(int j = 0;j<rhs.getLen();i++,j++)str[i] = rhs[j];str[totallen] = '\0';return str; } void Mystring::operator+=(const Mystring& rhs){int totallen = len + rhs.getLen();Mystring str(totallen);int i = 0;for(;i<len;i++)str[i] = mystring[i];for (int j = 0; j < rhs.getLen(); i++, j++)str[i] = rhs[j];str[totallen] = '\0';*this = str; } Mystring &Mystring ::operator=(const Mystring &rhs) {delete[] mystring;len = rhs.getLen();mystring = new char[len + 1];for (int i = 0; i < len; i++)mystring[i] = rhs[i];mystring[len] = '\0';return *this; }測(cè)試:
int main(){Mystring s1("initial test");cout << "S1:\t" << s1.GetMyString() << endl;char *temp = "Hello World";s1 = temp;cout << "Now,S1 is replaced by Hello World" << endl;cout << "S1:\t" << s1.GetMyString() << endl;char s2[20];strcpy(s2, "; I like you!");cout << "S2:\t" << s2 << endl;s1 += s2;cout << "S1+S2:\t" << s1.GetMyString() << endl;cout << "S1[4]:\t" << s1[4] << endl;s1[4] = 'x';cout<<"now s1[4] is repalced by x"<<endl; cout << "S1:\t" << s1.GetMyString() << endl;cout << "S1[999]:\t" << s1[999] << endl;Mystring s3(" Another myString");cout << "S3:\t" << s3.GetMyString() << endl;Mystring s4;s4 = s1 + s3;cout << "S1+S3:\t" << s4.GetMyString() << endl;return 0;}總結(jié)
以上是生活随笔為你收集整理的【C++复习总结回顾】—— 【五】数组与指针的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android 地图相册,时光地图相册a
- 下一篇: QT学习-----按钮弹起效果的实现