C++速成(1)__C++

來源:互聯網
上載者:User

轉載自:
http://www.cnblogs.com/kkdd-2013/p/5370094.html

C起航1h 1 C簡介 2 CIDE環境搭建 3 C之初體驗 4 C語言新特性 41 C新特性 42 C輸入輸出 43 Cnamespace 5 練習題 C離港15h 1 引用 引例 基礎資料型別 (Elementary Data Type)的引用 結構體類型的引用 指標類型的引用 引用作為函數參數 2 const const與基礎資料型別 (Elementary Data Type) const與指標類型 const與引用 小結 3 函數 函數參數預設值 函數重載 內嵌函式 代碼實踐 4記憶體管理 5 練習題 C封裝上2h 1 類和對象 引例-狗 引例-電視機 2 類對象的定義 對象的執行個體化 對象成員的訪問 代碼實踐 3 string string類型 初始化string對象的方式 string的常用操作 代碼實踐 4 屬性封裝 資料的封裝 封裝的好處 代碼實踐 5 類外定義 類內定義 類內定義與內嵌函式的關係 類外定義 代碼實踐 5 對象 對象結構 對象初始化 建構函式 建構函式代碼實踐 預設建構函式 建構函式初始化列表 初始化列表代碼實踐 拷貝建構函式 解構函式 解構函式代碼實踐 6 練習題 C封裝下3h 1 對象成員於數組對象 對象數組 對象數組代碼實踐 對象成員 對象成員代碼實踐 2 深拷貝與淺拷貝 深拷貝與淺拷貝 深淺拷貝代碼實踐 3 對象指標 對象指標 對象指標代碼實踐 對象成員指標 記憶體中的對象成員指標 對象成員指標代碼實踐 this指標 this指標代碼實踐 4 const進階 5 常指標與常引用 對象的引用和對象的指標 對象的常引用和常指標 6 練習題

1.C++起航1h 1.1 C++簡介 1.2 C++IDE環境搭建 1.3 C++之初體驗 1.4 C++語言新特性 1.4.1 C++新特性 1.4.2 C++輸入輸出 1.4.3 C++namespace 1.5 練習題

#include<stdlib.h>#include<iostream>usingnamespace std;/*  *************************************************   *//* 知識點:bool類型、命名空間、輸入輸出                 *//* 題目要求:                                           *//*     使用一個函數找出數組中的最大值和最小值           *//*  *************************************************   */int getMaxOrMin(int *arr, intcount, boolisMax){    int temp = arr[0];    for(int i = 1; i <count; i++)    {        if(isMax)        {            if( temp <arr[i])            {                temp = arr[i];            }        }        else        {            if(temp >arr[i])            {                temp = arr[i];            }        }    }    return temp;}int main(){    int arr1[4] = {3,2,5,8};    bool isMax = false;    cin >> isMax;   //輸入cin和輸出cout在iostream標頭檔中,所以要在程式的開始將這個標頭檔包含進來,同時還要加上命名空間std    cout << getMaxOrMin (arr1, 4, isMax) << endl;    system("pause");//system在stdlib.h標頭檔中,所以要在程式的開始將這個標頭檔包含進來    return 0;}

下面我們再來思考一個問題,假如這個getMaxOrMin()函數是由某一家公司開發的,比如說這家公司叫CompA。如果公司CompA想要發布這個函數,並且避免與其他公司發布的同名函數,則就需要在自己的函數名字前面加一個明明空間。加好命名空間後,就會將自己的函數放進命名空間中去。在使用的時候就需要加上命名空間,整個程式如下:

#include<stdlib.h>#include<iostream>usingnamespace std;namespace CompA{    int getMaxOrMin(int *arr, intcount, boolisMax)    {        int temp = arr[0];        for(int i = 1; i <count; i++)        {            if(isMax)            {                if( temp <arr[i])                {                    temp = arr[i];                }            }            else            {                if(temp >arr[i])                {                    temp = arr[i];                }            }        }        return temp;    }}int main(){    int arr1[4] = {3,2,5,8};    bool isMax = false;    cin >> isMax;   //輸入cin和輸出cout在iostream標頭檔中,所以要在程式的開始將這個標頭檔包含進來,同時還要加上命名空間std    cout << CompA::getMaxOrMin (arr1, 4, isMax) << endl;    system("pause");//system在stdlib.h標頭檔中,所以要在程式的開始將這個標頭檔包含進來    return 0;}

運行結果說明,我們使用這種方式就能夠區分各個公司所相同重名的函數,只是在使用的時候,我們需要在函數前面加上相應的命名空間即可。 2. C++離港1.5h 2.1 引用 引例

小時候,院子裡有一個小孩,名叫羅某某,外形上來看,頭大身子小,所以院子裡的其他小朋友就給羅某某起了個外號(別名)叫蘿蔔頭。這樣,生活中,羅某某就是這個小朋友的真實姓名,蘿蔔頭就是這個小朋友的別名。

那麼,什麼叫引用呢。。。。引用就是別名。

電腦中,引用就是某個變數的別名。

思考:能不能只有別名,而沒有真實姓名呢。

生活中,如果某個人只有別名的話,是不是就變成了他的真實姓名了呢。可見,只有別名,生活中其實也是不可行的,而在電腦中,肯定也一樣的道理,也是無法成立的。 基礎資料型別 (Elementary Data Type)的引用

請看下面一段代碼:

#include <iostream>using namespace std;int main(){    int a = 3;    int&b = a; //引用必須初始化    b = 10;    cout<< a <<endl;    return 0;}

代碼解讀:

我們定義了一個基礎資料型別 (Elementary Data Type),即定義了一個整形變數a,給它賦了初值3;接著給變數a起了一個別名b(int&b = a;),這裡需要注意,如果只起別名b,後面什麼都步跟,在編譯時間就會報錯,所以,在起別名時,一定要指明給哪個變數起的別名,即引用一定要初始化。

然後,我們給b賦值10,通過輸出的方式來輸出變數a的值,我們會看到輸出結果是10。從程式運行結果來看,對別名的修改,就是對實際變數的修改。類似於生活中,我們讓小蘿蔔頭去幹活,實際就是讓羅某某去幹活是一樣的道理。 結構體類型的引用

#include <iostream>using namespace std;typedefstruct{    int x;    int y;}Coor;int main(){    Coor c1;    Coor&c = c1; //對c1起了個別名叫c    c.x = 10;    c.y = 20;    cout<< c1.x <<endl;    cout<< c1.y <<endl;    return 0;}

代碼解讀:

首先,定義一個座標類型的結構體Coor,裡麵包含橫座標x和縱座標y;接著在main函數中定義了一個結構體變數c1,然後對結構體c1起了個別名,叫c;再然後對c中的橫座標x和縱座標y分別進行了賦值操作,即用別名對相應的資料成員做了操作;最後,通過輸出函數,將實體c1的橫座標和縱座標列印出來。從列印結果來看,實體c1的橫座標為10,縱座標為20。(因為操作別名與操作實體是沒有區別的指標類型的引用

指標類型的引用的定義方式:類型* *&*指標的別名* = *指標

#include <iostream>using namespace std;int main(){    int a =10;    int *p = &a; //定義了一個指標指向整形變數a        int *&q = p; //給指標p起了一個別名q    *q = 20;    cout<< a <<endl;    return 0;}

代碼解讀:

程式中,首先定義了一個整形變數a,並且對其賦了初值10;然後定義了一個指標變數p,讓指標p指向了整形變數a(int *p = &a;);接著,我們給指標p起了一個別名叫q,並對q賦值為20(這裡相於給*p複製為20,由於p是指向a的,又相當於給a重新賦值為20);最後輸出a。從輸出結果看,a的值變為了20。 引用作為函數參數

在沒有引用之前,要交換兩個數,需要如下操作

#include <iostream>using namespace std;void fun( int *a, int *b){    int c=0;    c = *a;    *a =*b;    *b = c;}int main(){    int x=10, y=20;    fun(&x, &y);    cout<< x << ',' << y <<endl;    return 0;}

從上面的程式來看,比較繁瑣,而且需要一定的理解能力。

當我們有了引用之後,程式可以這樣來寫:

#include <iostream>using namespace std;void fun( int&a, int&b){    int c=0;    c = a;    a =b;    b = c;}int main(){    int x=10, y=20;    fun(x, y);    cout<< x << ',' << y <<endl;    return 0;}

從上面的程式來看,功能函數就簡單多了,傳入的兩個實參就會分別起別名a和b,對別名進行交換就相當於對實體的實際操作。 2.2 const const與基礎資料型別 (Elementary Data Type)

首先,沒有const關鍵字時,我們要定義一個整形變數,其在記憶體中的情況如下:

int a = 3; //變數

變數名 儲存地址 儲存內容

a &a 3

當我們在變數名前加上關鍵字const後,它就由一個變數變成了一個常量,如下:

const int a = 3; //常量

這時如果再對a重新賦值5或者其他值,電腦就會報錯,因為此時a是一個常量,不得更改。

變數名 儲存地址 儲存內容

a &a 3 const與指標類型

幾種定義方式與區別:

(1) const int *p = NULL;

(2) int const *p = NULL;

(3) int * const p = NULL;

(4) const int * const p = NULL;

(5) int const * const p = NULL;

注意:*(1)*與*(2)*完全等價,*(4)*與*(5)*完全等價

例子:

int x =3;

const int *p = &x;

//此時如果 p = &y; 正確,而如果 p = 5; 錯誤(因為此時**const*修飾的是 *p)

int x =3;

int *const p = &x;

//此時如果p = &y; 錯誤(因為此時***const*修飾的是*p*,而*p*只能指向**x

const int x =3;

const int *const p = &x;

//此時如果p = &y; *p = 5; 都是錯誤的(因為此時不能用****p修改x的值,也不能將p指向其他變數const與引用

例子:

int x =3;

const int &y = x;

//x = 10; 正確(因為此時x是一個變數,是可變的)

//y = 20; 錯誤(因為y作為x的別名,其前面加了const修飾符,不可變) 小結

(1)const int x =3; x = 5; X(因為此時x是不可變的)

(2)int x = 3; const int y = x; y = 5; X(因為此時y是常量,不可重新賦值)

(3)int x = 3; const int *y = &x; *y = 5; X(因為此時const修飾的是*y)

(4)int x = 3; z =4; int *const y = &x; y = &z; X(因為此時const修飾的是指標y,其指向不可變)

(5)const int x = 3; const int &y = x; y = 5; X(因為此時x是常量,y是x的引用且y也是常量,就不可以再對y重新賦值)

(6)const int x = 3; int *y = &x; X(因為此時x是常量,而指標y是變數,不能將可變指標指向不可變的變數。如果這樣做,電腦是有風險的,風險就是可以用*y來修改x的值)

(7)int x = 3; const int *y = &x; 2.3 函數 函數參數預設值

有如下函式宣告:

void fun(int i, int j = 10, int k = 20);

void fun(int i, int j = 10, int k) ;X

注意:有預設參數值的參數必須在參數表的最右端

在函式宣告時可以帶上參數預設值,而在定義時,不建議帶上參數預設值。如果在函數定義的時候也寫上函數參數預設值,則實際編譯時間,有的編譯器能夠編譯通過,而有的編譯器編譯不會通過。

樣本:

#include

#include 函數重載

什麼是函數重載。。。

在相同範圍內,用同一函數名定義的多個函數,但這些多個函數之間的參數個數參數類型不同,則稱這些多個函數就叫重載函數。

比如,定義以下兩個函數(功能:取最大值)

int getMax(int x, int y, int z)

{

//to do;

}

double getMax(double x, double y)

{

//to do;

}

從上面兩個函數可以看到,函數名都一樣,但函數的參數個數和參數類型不同,這樣兩個函數就是重載函數。

思考:編譯器如何識別重載的函數。。

實際編譯器編譯時間,經過如下操作:

int getMax(int x, int y, int z)經過編譯後得到getMax_int_int_int

double getMax(double x, double y)經過編譯後得到getMax_double_double

從上面的編譯結果看,編譯後會形成一個名稱*+*參數的方式形成一個新的函數名,來區分兩個重載函數;而調用過程中,電腦是採用的自動識別方式,即根據你傳入的實參類型以及實參個數自動識別後,來調用相應的函數。

注意:關於函數重載的相關內容,這篇部落格講的更加深入: C++的函數重載 內嵌函式

內嵌函式與普通函數的區別:

1、內嵌函式與普通函數在定義方面區別不大

2、內嵌函式與普通函數在調用方面區別如下:

如果使用主調函數去調用一個普通函數,將進行如下5個步驟:

去調用fun() ->找到fun()的相關函數入口->執行fun()裡的相關代碼->返回主調函數->主調函數再運行其他代碼直到結束

如果使用主調函數去調用內嵌函式時,編譯時間將函數體代碼和實參替代掉函數調用語句,這樣其實是省掉了上面的過程(2)和(4),這樣可以為調用節省很多時間,尤其對迴圈調用時,將節省更多的時間。

內嵌函式關鍵字:****inline

**inline **int max(int a, int b, int c); //聲明一個內嵌函式max

int main()

{

int i =10, j = 20, k = 30, m;

m = max(i,j,k);

cout<< “max = ” << m < 代碼實踐

使用函數的重載完成返回最大值的方法。

現在有一個數組,定義一個方法getMax(),利用函數的重載,分別實現:

1、隨意取出數組中的兩個元素,傳到方法getMax()中,可以返回較大的一個元素。

2、將整個數組傳到方法getMax()中,可以返回數組中最大的一個元素。

完整可執行程式:

#include <iostream>using namespace std;/*  *函數功能:返回a和b的最大值  *a和b是兩個整數*/int getMax(int a, int b){return a > b ? a : b;}/*  * 函數功能:返回數組中的最大值  * arr:整型數組  * count:數組長度  * 該函數是對上面函數的重載*/int getMax(int *arr,int count){    //定義一個變數並擷取數組的第一個元素int temp=arr[0];for(int i = 1; i < count; i++)    {        //比較變數與下一個元素的大小        if(temp<arr[i])        {            //如果數組中的元素比maxNum大,則擷取數組中的值            temp=arr[i];        }        }    return temp;}int main(){    //定義int數組並初始化    int numArr[3] = {3, 8, 6};    //自動調用intgetMax(int a, int b)    cout<<getMax(6,3) <<endl;    //自動調用返回數組中最大值的函數返回數組中的最大值    cout<<getMax(numArr,3) <<endl;    return 0;}
2.4記憶體管理

什麼是記憶體管理。

思考:記憶體的本質是什麼。—->資源

思考:誰掌管記憶體資源。 —->作業系統

思考:我們能做什麼。 —->申請/歸還

申請*/*歸還記憶體資源就是記憶體管理

C++中如何進行記憶體的申請和釋放。

申請 —>使用運算子new

釋放 —>使用運算子delete

即:

申請記憶體:****int *p = new int;

釋放記憶體:* delete p;*

這樣就申請和釋放一個記憶體或是某一種類型的記憶體

思考:如何申請和釋放塊記憶體呢。

int *arr = new int[10]; //申請了10個整型的塊記憶體

delete []arr; //釋放塊記憶體

思考:申請記憶體是否一定就能申請成功呢。顯然,不一定。。

因此,編碼時,就要對可能的申請記憶體失敗進行處理

int *p = new int[1000];

if(NULL == p)

{

//記憶體配置失敗

}

釋放記憶體後,要將相應的指標賦值為空白,即

delete p; delete []p;

p = NULL; p = NULL;

如果將釋放後的指標不置為空白,那麼當前的這個指標還是指向相應的那塊記憶體,如果我們不小心又調用了一次delete,那麼就會使得同一塊記憶體被重複回收,一旦被重複回收,電腦就會出現異常。

小結:

1) 使用new申請記憶體,使用delete釋放記憶體

2) 申請記憶體時需要判斷是否申請成功,釋放記憶體後需要將指標置為空白

3) new和delete要配套使用

最後看一個執行個體:

在堆中申請100個char類型的記憶體,拷貝Hello imooc字串到分配的堆中的記憶體中,列印字串,最後釋放記憶體。

完整可執行程式:

#include <string.h>#include <iostream>using namespace std;int main(void){    char *str = new char[100];//在堆中申請100個char類型的記憶體    strcpy(str, "Hello imooc"); //拷貝Hello C++字串到分配的堆中的記憶體中    cout<<str<<endl;//列印字串    delete []str;//釋放記憶體    str=NULL;    return 0;}
2.5 練習題 3. C++封裝上2h 3.1 類和對象 引例——-狗

假如我們養了一條狗,它有如下資訊:

資訊*—–*姓名:旺財、年齡:1歲、品種:大型犬

技能*——*叫、跑

當我們具體的指代一個事物的時候,它就是一個對象

可是當我們養了多條狗時,為了便於管理,會建立一張表格

姓名 年齡 品種
大壯 1
二壯 2
三壯 1
…… …… ……
…… …… ……

共有技能:叫、跑

如此,就將一群狗狗的資訊抽象出來了,這樣就可以定義一個類了。

想一想:抽象出來的是不是狗的全部資訊呢。

為什麼不定義這樣的資訊呢。

狗肉的蛋白質含量是多少。

狗的出欄周期是多少。

這是因為,我們關注的不是吃,所以這些資訊對我們沒有用。。

結論:目的不同抽象出來的資訊也不同。 引例——-電視機

假如有一台電視機,通過電視機上名牌標識,我們可以知道它的名字和型號;通過各種旋鈕,我們可以控制它的音量,還可以接通和切斷電源。那麼我們用類來描述如下:

但是仍有很多實現細節在類裡面沒有描述,這並不意味著它就不存在,而是被隱藏起來了。比如:電路板的工作過程。如果這些通通暴露給看電視的使用者,那麼看電視的人一定會瘋掉。其實呢,這就是選擇性暴露。

把實現細節封裝起來,只暴露使用者所關心的部分,這就叫做封裝。

如果我們把電視機的資訊都羅列出來,大家一定可以判斷哪些資訊是需要暴露的,哪些資訊是不需要暴露的。

可是這些資訊都在類中定義,如何才能把想暴露的資訊暴露出來,把想隱藏的資訊隱藏起來呢。

這對這一問題,C++為我們提供了一個叫做訪問限定符的東西。

訪問限定符:

public:公用的

private:私人的

protected:受保護的

希望暴露出來的資訊就使用public修飾,希望隱藏的資訊就使用private修飾。

3.2 類對象的定義 對象的執行個體化

在C++中,類就是一個模板,對象執行個體化就是電腦根據類的設計,製造出多個對象的過程。

下面定義了一個TV的類,這個電視的類中有兩個屬性或者叫資料成員,一個是電視的名字,一個是電視的類型;另外還有兩個方法或者叫成員函數,一個用來調節音量,一個用來開關電源。

執行個體化對象有兩種方式:

(1) 從棧執行個體化

如果我們要對上面的類進行執行個體化,並且想從棧中執行個體化,我們可以這樣做:

(2) 從堆執行個體化

如果我們要對上面的類進行執行個體化,並且想從堆中執行個體化,我們可以這樣做:

注意:兩種方式執行個體化的區別

從棧執行個體化對象,使用完之後,不需要我們自己去理睬,系統自動會將其佔用的記憶體釋放掉;而從堆執行個體化對象,使用完後,我們一定要將這塊記憶體釋放掉。

思考:

—-通過棧也好,通過堆也好,我們已經執行個體化出來了對象,那麼有了這些對象就算完了嗎。

—-我們執行個體化出來的這些對象就是個擺設嗎。

顯然,我們是不會這麼無聊的,我們是要通過訪問這些對象的各種成員來達到我們的目的的。 對象成員的訪問

通過不同執行個體化對象的方法,產生的對象在訪問其資料成員和成員函數的方式也各不相同。

棧執行個體化對象訪問其成員 堆執行個體化單一對象訪問其成員 堆執行個體化對象數組訪問其成員 代碼實踐

定義一個座標類,包含兩個資料成員:橫座標x和縱座標y,兩個成員函數,分別用來列印橫座標和縱座標。

#include<iostream>#include<stdlib.h>using namespace std;class Coordinate{public:    int x;    int y;    void printX()    {        cout<< x <<endl;            }    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.