日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

【C++复习总结回顾】—— 【五】数组与指针

發(fā)布時(shí)間:2023/12/15 c/c++ 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++复习总结回顾】—— 【五】数组与指针 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

需要更好的閱讀的體驗(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í)例

class Point{public:Point(float xx = 0,float yy = 0):x(xx),y(yy){ }float getX() const {return x;}float getY() const {return y;}private:float x,y; }; //直線(xiàn)線(xiàn)性擬合,number為點(diǎn)數(shù) float lineFit(const Point points[], int number){float avgx = 0, avgy = 0;float lxx = 0,lyy = 0, lxy = 0;for(int i =0;i<number;i++){avgx += points[i].getX()/number;avgy += points[i].getY()/number;}for(int i = 0;i<number;i++){lxy += (points[i].getX() - avgx) * (points[i].getY() - avgy);lyy += (points[i].getY() - avgy) * (points[i].getY() - avgy);lxx += (points[i].getX() - avgx) * (points[i].getX() - avgx);}cout<<"This line can be fitted by y=ax+b."<<endl;//輸出回歸系數(shù)a,bcout<<"a = "<<lxy/lxx<<" "<<"b = "<<avgy-lxy*avgx/lxx<<endl;return (float)(lxy/sqrt(lxx*lyy)); //線(xiàn)性相關(guān)的密切程度 } int main(){Point points[10] = {Point(6,10),Point(14,20),Point(26,30),Point(33,40),Point(46,50),Point(54,60),Point(67,70),Point(75,80),Point(84,90),Point(100,100)};float r = lineFit(points,10);cout<<"Line coefficient r = "<<r<<endl; }

二、指針

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ū)。


#include <iostream> using namespace std; int compute(int a, int b, int (*func)(int, int)) {return func(a, b); } int max(int a, int b) // 求最大值 {11return ((a > b) ? a : b); } int min(int a, int b) // 求最小值 {return ((a < b) ? a : b); } int sum(int a, int b) // 求和 {return a + b; } int main() {int a, b, res;cout << "請(qǐng)輸入整數(shù)a:";cin >> a;cout << "請(qǐng)輸入整數(shù)b:";cin >> b;res = compute(a, b, &max);cout << "Max of " << a << " and " << b << " is " << res << endl;res = compute(a, b, &min);cout << "Min of " << a << " and " << b << " is " << res << endl;res = compute(a, b, &sum);cout << "Sum of " << a << " and " << b << " is " << res << endl; }

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)的空間

int *p = new int; *p = 5; delete p; delete p; //wrong; 同一片空間不能被delete兩次

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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。