亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

趣味 C++ 進階

難度初級
時長 8小時 0分
學習人數
綜合評分9.60
10人評價 查看評價
10.0 內容實用
8.8 簡潔易懂
10.0 邏輯清晰
  • a是int型變量a的地址

    (char *)將int型指針(指向4個字節)轉換成char型指針(指向一個字節)

    char *p聲明一個char型指針變回量,答接受轉換的地址。

    #include <stdio.h>

    int main()
    {
    ? ?int i = 0x1122;
    ? ?char * p = (char *)&i;
    ? ?if (p[0] == 0x22 && p[1] == 0x11) {
    ? ? ? ?printf("Little Endian\n");
    ? ?}
    ? ?else if (p[0] == 0x11 && p[1] == 0x22) {
    ? ? ? ?printf("Big Endian\n");
    ? ?}
    }

    查看全部
    3 采集 收起 來源:強者爭霸

    2021-08-13

  • 計算機硬件有兩種儲存數據的方式:大端字節序(big endian)和小端字節序(little endian)。

    如果一個使用小端字節序的電腦上,這個整數的高字節就會存放在高地址上:

    現在大部分的機器,都采用了小端字節序。但是在 IO 方面,則大部分使用大端字節序。例如,你要使用網絡發送一個 int 類型的變量,要先把 int 轉換成大端字節序,然后通過網絡發送。

    大端字節序又被稱之為網絡細節序。

    查看全部
  • ^ 異或

    若參加運算的兩個二進制位值相同則為0,否則為1。

    << 左移

    各位全部左移若干位,高位丟棄,低位補 0 。

    >> 右移

    各二進位全部右移若干位,對無符號數,高位補 0 ,有符號數,各編譯器處理方法不一樣,有的補符號位,有的補 0 。

    查看全部
  • 你知道大端字節序和小端字節序嗎?

    字節序,就是 大于一個字節類型的數據在內存中的存放順序。

    計算機硬件有兩種儲存數據的方式:大端字節序(big endian)和小端字節序(little endian)。

    我們現在有一個整數是258。用16進制表示是0x0102,然后我們把這個整數拆分成兩個字節,第一個字節為 0000 0001,第二個字節為 0000 0010。

    如果在一個使用大端字節序的電腦上,這個整數會被這樣存放:

    http://img1.sycdn.imooc.com//61097ae60001b04704660158.jpg

    如果一個使用小端字節序的電腦上,這個整數的高字節就會存放在高地址上:

    http://img1.sycdn.imooc.com//61097af30001e1f404750162.jpg

    現在大部分的機器,都采用了小端字節序。但是在 IO 方面,則大部分使用大端字節序。例如,你要使用網絡發送一個 int 類型的變量,要先把 int 轉換成大端字節序,然后通過網絡發送。

    大端字節序又被稱之為網絡細節序。

    查看全部
  • 不一樣的const關鍵字

    C++ 中的 const 千變萬化,之前我們已經學過使用 const 來做一個常量。const 在 C++ 中整體表示的語意是“不變的”,但是 const 申明在不同位置,卻會有不一樣的效果。這一小節,我們來集中學習一下 const。

    const 修飾普通變量

    例如:

    const int a = 20;

    則表示 a 是一個常量,你不可以在后續對其進行修改。因為 a 不可修改,所以在創建的時候就要對 a 進行賦值,不對其進行賦值則會報錯。例如,下面的代碼就會報錯

    const int a;

    const 修飾指針

    const 修飾指針可以分為多種情況:

    只有一個 const,如果 const 位*左側,表示指針所指數據是常量,不能通過解引用修改該數據;指針本身是變量,可以指向其他的內存單元

    int aaa = 20; int bbb = 30; const int * constPoint = &aaa; constPoint = &bbb; *constPoint = 80; // 這行代碼會報錯

    只有一個 const,如果 const 位于*右側,表示指針本身是常量,不能指向其他內存地址;指針所指的數據可以通過解引用修改

    int aaa = 20; int bbb = 30; int * const constPoint = &aaa; constPoint = &bbb; // 這行代碼會報錯 *constPoint = 80;

    兩個 const,*左右各一個,表示指針和指針所指數據都不能修改

    int aaa = 20; int bbb = 30; const int * const constPoint = &aaa; constPoint = &bbb; // 這行代碼會報錯 *constPoint = 80; // 這行代碼會報錯

    const 修飾函數參數

    const 修飾函數參數和修飾普通函數是一樣的。但是要注意的時候 const 修飾函數參數的時候,其作用域僅僅限制在函數內部。也就是說,你可以把一個不用 const 修飾的參數傳入到 const 修飾的參數中去。而只要在函數中保持其不變性就可以了。

    const 修飾成員函數

    const 修飾的成員函數不能修改任何的成員變量

    class A { public: ? ? int aaa; ? ? int funcA() const ? ? { ? ? ? ? aaa = 20; // 這行代碼會報錯 ? ? ? ? return 0; ? ? } }

    const 成員函數不能調用非 const 成員函數

    class A { public: ? ? int aaa; ? ? int funcA() const ? ? { ? ? ? ? funcB(); // 這行代碼會報錯 ? ? ? ? return 0; ? ? } ? ? int funcB() ? ? { ? ? ? ? return 0; ? ? } }


    const 修飾函數返回值

    修飾返回值要分成兩種情況

    址傳遞,返回指針,引用。

    在 C++ 中有時我們會寫這樣的代碼:

    A aaa; A & getA(){ ? ? return aaa; } int main(int argc,char **argv) { ? ? A bbb; ? ? getA() = bbb; ? ? return 0; }

    上面的代碼運行之后,aaa 變量就會被 bbb 所賦值,但是有些時候這樣做會造成一些混亂

    例如:

    getA() == a

    有時候會有筆誤:

    getA() = a

    這種情況下,就會有問題,而且不容易被找到這個錯誤。

    所以在大多數情況下,我們可以給返回值加一個 const ,這樣可以防止返回值被調用。

    A aaa; const A & getA(){ ? ? return aaa; } int main(int argc,char **argv) { ? ? A bbb; ? ? getA() = bbb; // 這行代碼會報錯 ? ? return 0; }

    值傳遞。

    值傳遞就簡單多了,因為值傳遞的時候,返回值會被復制一份,所以加不加 const 都可以。

    查看全部
  • C++ 中的空指針

    我們之前的課程中曾經講過空指針的問題,知道在 C++ 中,有使用 NULL 和 nullptr 兩種方式表示空指針的方法。

    int * p = NULL; int * p = nullptr;

    這一小節來看看兩者的區別。

    NULL

    首先看 NULL,在 C++ 中,NULL 其實就是 0。

    例如:

    int * p = NULL;

    等價于:

    int * p = 0;

    因為在 C++ 中,0 地址通常是被保護起來的,不可訪問的。因此用 0 地址來指代這個指針哪里都不指,是可以的。但是這里面卻存在一些問題。因為 NULL 就是 0,所以我們可以把 NULL 用在其他地方。

    例如:

    int a = NULL;

    我們可以將一個 int 變量賦值成 NULL,你永遠無法阻止有人這么干。而在某些情況下,甚至會在不經意間釀成慘劇。

    例如:

    class A { public: ? ? void func(void * t) ? ? { ? ? } ? ? void func(int i) ? ? { ? ? } }

    這個類中,func 函數有兩個重載。這個時候,我們嘗試用 NULL 調用一下:

    int main(int argc,char **argv) { ? ? A a; ? ? a.func(NULL); ? ? return 0; }

    猜猜這個函數到底調用的哪個重載?

    nullptr

    正是由于 NULL 會導致這樣的混亂,所以在 C++11 標準之后,C++ 標準委員會為 C++ 添加了 nullptr 關鍵字。我們可以將 NULL 賦值給一個普通變量,而 nullptr 卻不能。

    int a = nullptr;

    這樣是會直接報錯的。

    nullptr 只能賦值給指針,所以不會有 NULL 那樣的問題。

    所以,只要你的編譯器兼容 C++11 標準,那么你應該使用 nullptr。

    查看全部
    0 采集 收起 來源:C++ 中的空指針

    2021-08-03

  • 霸道總裁眼中的命令員工:父類和子類的相互轉換

    我們在之前的課程中學習過數據類型之間的轉換,某些可以隱式轉換,某些需要顯式轉換。

    例如,我們可以把 int 轉成 long long。

    int a = 100; long long b = a;

    由于是小類型轉大類型,所以這里使用隱式轉換就可以了。

    再比如,我們可以把 long long 轉成 int。

    long long a = 100; int b = (int)a;

    這里是大類型轉小類型,所以要顯式轉換。這種轉換可能會損失精度,是需要我們程序員掌控的。

    類的轉換

    同樣,類之間也可以相互轉換。類的轉換主要是在父類和子類之間的轉換。

    首先,我們先來看看父類和子類之間的邏輯關系

    class Staff { public: ? ? std::string name; ? ? int age; } ?class Coder : public Staff { public: ? ? std::string language; };

    這里有兩個類,一個類是 Staff 員工類,里面包括兩個屬性,name 和 age。Coder 程序員類繼承自員工類,所以其包含了 Staff 的屬性,除此之外,還有一個 language 屬性,表示其使用的編程語言。

    我們其實可以把一個員工強行轉化成程序員,但是這就有可能出問題,就如同我們把 long long 轉成 int 就有可能出現問題。

    int main(int argc,char **argv) { ? ? Coder * coder = new Coder(); ? ? Staff * staff = coder; // 隱式轉換就可以 ? ? Coder * coder = (Coder *)staff; // 必須顯式轉換 ? ? return 0; }

    查看全部
  • 動態編聯和靜態編聯

    上一小節,我們介紹了父類和子類的轉換,也簡單介紹了多態,從這節開始,我們詳細介紹多態。

    class Base { public: ? ? void func(){ ? ? ? ? printf("this is Base\n"); ? ? } } class Child : public Base { public: ? ? void func(){ ? ? ? ? printf("this is Child\n"); ? ? } } ?int main(int argc,char **argv) { ? ? Child * obj = new Child(); ? ? Base * baseobj = (Base *)obj; ? ? baseobj->func(); ? ? delete obj; ? ? return 0; }

    我們之前講述了什么是多態,還用了一個例子,將一個指針的類型做成強轉,然后調用 func 函數,就會發現, func 函數會隨著被強轉的類型的變換而變換,這種函數的關聯過程稱為編聯。按照聯編所進行的階段不同,可分為兩種不同的聯編方法:靜態聯編和動態聯編。

    靜態編聯

    Child * obj = new Child(); Base * baseobj = (Base *)obj; baseobj->func(); delete obj; return 0;

    再來看看這個例子,我們通過強制轉換來指定 func 執行的是哪個。這個過程是在編譯階段就將函數實現和函數調用關聯起來,因此靜態聯編也叫早綁定,在編譯階段就必須了解所有的函數或模塊執行所需要檢測的信息。

    動態編聯

    除了靜態編聯之外,C++ 還支持動態編聯。動態聯編是指聯編在程序運行時動態地進行,根據當時的情況來確定調用哪個同名函數,實際上是在運行時虛函數的實現。當然,我們現在所學的知識還沒辦法完成動態編聯,接下來,我們將要學習虛函數,來實現動態編聯。

    查看全部
  • 引用和指針用法的區別。

    查看全部
  • 引用和指針功能一樣,引用必須要初始化,賦值nullptr。

    int &ra = a;

    引用只能指向一個地址,而指針可以變化自己的指向地址。

    查看全部
  • 純虛函數只可以被繼承。

    將父類的析構函數聲明為虛函數,作用是用父類的指針刪除一個派生類對象時,派生類對象的析構函數會被調用。例如:

    class Staff
    {
    public:
    ? ?std::string name;
    ? ?int age;

    ? ?virtual ~Staff()
    ? ?{

    ? ?}
    }

    class Coder : public Staff
    {
    public:
    ? ?std::string language;

    ? ?virtual ~Coder()
    ? ?{

    ? ?}
    };

    int main(int argc,char **argv)
    {
    ? ?Staff * s = new Coder();

    ? ?delete s;

    ? ?return 0;
    }

    此時如果析構函數不加 virtual,那么 delete 父類指針的時候,子類的析構就不會被調用,某些情況下會導致內存泄漏。

    查看全部
    0 采集 收起 來源:強者爭霸

    2021-08-02

  • 純虛函數只可以被繼承。

    將父類的析構函數聲明為虛函數,作用是用父類的指針刪除一個派生類對象時,派生類對象的析構函數會被調用。例如:

    class Staff
    {
    public:
    ? ?std::string name;
    ? ?int age;

    ? ?virtual ~Staff()
    ? ?{

    ? ?}
    }

    class Coder : public Staff
    {
    public:
    ? ?std::string language;

    ? ?virtual ~Coder()
    ? ?{

    ? ?}
    };

    int main(int argc,char **argv)
    {
    ? ?Staff * s = new Coder();

    ? ?delete s;

    ? ?return 0;
    }

    此時如果析構函數不加 virtual,那么 delete 父類指針的時候,子類的析構就不會被調用,某些情況下會導致內存泄漏。

    查看全部
    0 采集 收起 來源:強者爭霸

    2021-08-02

  • 給員工分部門:類的繼承

    類,就像是對某一類事物的抽象模版,我們可以根據這個模版生產出具有相同屬性的對象。例如,我們之前將員工抽象成了 Staff 類。

    而在某些場景下,我們希望對抽象的內容進行擴增,或者說更加具體化。例如,我們之前定義了員工,但是員工只是很抽象的一個概念,員工和員工是不一樣的,例如,程序員和會計都是員工,他們都具有員工應有的屬性,但是除此之外,他們還有額外屬于自己的東西。

    為了完成這種關系,我們來學習一下繼承。

    例如,我們可以來寫一個程序員類,名字叫做 Coder

    class Coder { };

    這個 Coder 是員工的一種,他具有員工的所有屬性,所以,我們可以讓 Coder 繼承自 Staff

    class Coder : public Staff { };

    當然,除了具有 Staff 的所有內容之外,Coder 還有屬于自己的動作,那就是寫代碼,我們就可以這樣寫:

    class Coder : public Staff { public: ? ? void code() ? ? { ? ? ? ? printf("Coding!!!\n"); ? ? } };

    這樣,Coder 這個類,除了具有 Staff 的所有成員變量和成員函數之外,還有了一個屬于自己的函數。

    查看全部
  • 面向過程的結構化編程:把數據放入到動作當中。采用自頂向下的方法構建程序,包含順序,選擇和循環三種結構。按照程序執行的時序步驟來完成。

    類由成員函數和成員變量組成,可以通過實例化,得出很多的對象。

    查看全部
  • 運算符重載

    RMB.h

    class RMB { public: ? ? RMB(int _yuan, int _jiao, int _fen); ? ? ~RMB(); private: ? ? int yuan = 0; ? ? int jiao = 0; ? ? int fen = 0; };

    RMB.cpp

    #include "RMB.h" RMB::RMB(int _yuan, int _jiao, int _fen) { ? ? yuan = _yuan; ? ? jiao = _jiao; ? ? fen = _fen; } RMB::~RMB() { }

    為這個類寫了些必要的部分之后,我們要完成一個功能,加法功能,1塊9毛加2塊3毛,用程序應該怎么寫呢?我們可以添加一個 Add 函數,如下:

    RMB.h

    class RMB { public: ? ? RMB(int _yuan, int _jiao, int _fen); ? ? ~RMB(); ? ? RMB Add(const RMB & rmb); private: ? ? int yuan = 0; ? ? int jiao = 0; ? ? int fen = 0; };

    RMB.cpp

    #include "RMB.h" RMB::RMB(int _yuan, int _jiao, int _fen) { ? ? yuan = _yuan; ? ? jiao = _jiao; ? ? fen = _fen; } RMB::~RMB() { } RMB RMB::Add(const RMB & rmb) { ? ? RMB rmbRes(0, 0, 0); ? ? // 分 ? ? int f = rmb.fen + fen; ? ? int f_ = f / 10; ? ? rmbRes.fen = f % 10; ? ? // 角 ? ? int j = rmb.jiao + jiao + f_; ? ? int j_ = j / 10; ? ? rmbRes.jiao = j % 10; ? ? // 元 ? ? int y = rmb.yuan + yuan + j_; ? ? int y_ = y / 10; ? ? rmbRes.yuan = y % 10; ? ? return rmbRes; }

    這樣,我們就實現了一個 Add 函數,如果想要把兩個人民幣加起來,就可以這樣用:

    int main(int argc,char **argv) { ? ? RMB rmbA(1, 9, 0); ? ? RMB rmbB(2, 5, 0); ? ? RMB rmbC = rmbA.Add(rmbB); ? ? return 0; }

    但是這樣看上去好像有點別扭,事實上,在很多不支持運算符重載的語言里,我們都是這樣干的。但是在 C++ 里,有一種更好的方式,可以把 + 號進行重載。

    我們可以把這個 Add 函數修改成 + 號的重載:

    RMB.h

    class RMB { public: ? ? RMB(int _yuan, int _jiao, int _fen); ? ? ~RMB(); ? ? // RMB & Add(const RMB & rmb); ? ? RMB operator + (const RMB & rmb); private: ? ? int yuan = 0; ? ? int jiao = 0; ? ? int fen = 0; };

    RMB.cpp

    #include "RMB.h" RMB::RMB(int _yuan, int _jiao, int _fen) { ? ? yuan = _yuan; ? ? jiao = _jiao; ? ? fen = _fen; } RMB::~RMB() { } // RMB & RMB::Add(const RMB & rmb) RMB RMB::operator + (const RMB & rmb) { ? ? RMB rmbRes(0, 0, 0); ? ? // 分 ? ? int f = rmb.fen + fen; ? ? int f_ = f / 10; ? ? rmbRes.fen = f % 10; ? ? // 角 ? ? int j = rmb.jiao + jiao + f_; ? ? int j_ = j / 10; ? ? rmbRes.jiao = j % 10; ? ? // 元 ? ? int y = rmb.yuan + yuan + j_; ? ? int y_ = y / 10; ? ? rmbRes.yuan = y % 10; ? ? return rmbRes; }

    在這樣修改之后,使用的時候,我們就可以寫出來更優雅的代碼了。

    int main(int argc,char **argv) { ? ? RMB rmbA(1, 9, 0); ? ? RMB rmbB(2, 5, 0); ? ? RMB rmbC = rmbA + rmbB; ? ? return 0; }

    可以看到我們直接把兩個對象用 + 號加了起來,這比之前使用函數看起來會好得多。

    在 C++ 中,有很多符號都可以重載,也有一些不能被重載。

    查看全部
    1 采集 收起 來源:運算符重載

    2021-07-31


  • 類,是 C++ 實現面向對象最基礎的部分。類其實和之前學過的結構體十分相似,你可以認為類是結構體的升級版。

    類的申明

    在 C++ 中,可以用下面的代碼申明一個員工類:

    class Staff { };

    可以像使用結構體一樣使用這個類:

    #include <stdio.h> class Staff { }; int main(int argc,char **argv) {? ? ?Staff st;? ? ?return 0; }

    分文件編程

    我們在此之前都是把代碼放到一個文件里,但是這樣在實際工程中肯定是不行的,我們不可能把所有的代碼都寫到一個文件夾里面。而在 C++ 中我們就常常把類定義到不同的文件里面,把每個類都獨立起來,這樣代碼的耦合性就會降低,方便維護。

    在 C++ 中,我們可以把一個類寫到兩個文件里面,一個是后綴為 .h 或者 .hpp 的頭文件,一個是后綴為 .cpp 的實現文件。我們先在開發環境里新建一個類。輸入類名是 Staff。

    可以看到 VS 為我們創建類兩個文件,Staff.h 和 Staff.cpp。Staff.h 文件為定義,Staff.cpp 為實現。

    在分了文件之后,我們想要在 main 函數中引用這個類,就需要使用 #include “Staff.h” 將頭文件引入進來。

    實例化

    在新建了一個類之后,我們就可以根據這個類產生對象了。根據類產生對象的過程叫做實例化。

    #include "Staff.h"?

    int main(int argc,char **argv)?

    {? ? ?// 我們就這樣實例化了三個員工? ? ?

    Staff st1;? ? ?

    Staff st2;? ? ?

    Staff st3;? ??

    return 0;?

    }

    這樣分配,我們將這三個“員工”分配到了棧上,同樣的,可以把他們分配到堆內存上面去。

    new delete

    要將對象分配到堆上,需要用到另外兩個關鍵字,new 和 delete。new 用來分配對象,delete 用來刪除對象。new 會返回一個指針,在使用完畢后,要通過 delete 把這個指針指向的地址釋放掉。

    #include "Staff.h"?

    int main(int argc,char **argv) {? ??

    Staff * st1 = new Staff();? ? ?

    Staff * st2 = new Staff();? ? ?

    Staff * st3 = new Staff();? ? ?

    // 記得釋放? ??

    ?delete st1;? ? ?

    delete st2;? ? ?

    delete st3;? ? ?

    return 0;

    ?}


    查看全部
  • 霸道總裁的員工:類


    我們上一小節中介紹了面向對象的思想,這一小節開始,我們來具體看看在 C++ 中應該如何實現面向對象。



    類,是 C++ 實現面向對象最基礎的部分。類其實和之前學過的結構體十分相似,你可以認為類是結構體的升級版。


    類的申明


    在 C++ 中,可以用下面的代碼申明一個員工類:


    class Staff { };


    可以像使用結構體一樣使用這個類:


    #include <stdio.h> class Staff { }; int main(int argc,char **argv) {? ? ?Staff st;? ? ?return 0; }


    分文件編程


    我們在此之前都是把代碼放到一個文件里,但是這樣在實際工程中肯定是不行的,我們不可能把所有的代碼都寫到一個文件夾里面。而在 C++ 中我們就常常把類定義到不同的文件里面,把每個類都獨立起來,這樣代碼的耦合性就會降低,方便維護。


    在 C++ 中,我們可以把一個類寫到兩個文件里面,一個是后綴為 .h 或者 .hpp 的頭文件,一個是后綴為 .cpp 的實現文件。我們先在開發環境里新建一個類。輸入類名是 Staff。


    可以看到 VS 為我們創建類兩個文件,Staff.h 和 Staff.cpp。Staff.h 文件為定義,Staff.cpp 為實現。


    在分了文件之后,我們想要在 main 函數中引用這個類,就需要使用 #include “Staff.h” 將頭文件引入進來。


    實例化


    在新建了一個類之后,我們就可以根據這個類產生對象了。根據類產生對象的過程叫做實例化。


    #include "Staff.h"?

    int main(int argc,char **argv)?

    {? ? ?// 我們就這樣實例化了三個員工? ? ?

    Staff st1;? ? ?

    Staff st2;? ? ?

    Staff st3;? ??

    return 0;?

    ? ??

    }


    這樣分配,我們將這三個“員工”分配到了棧上,同樣的,可以把他們分配到堆內存上面去。


    new delete


    要將對象分配到堆上,需要用到另外兩個關鍵字,new 和 delete。new 用來分配對象,delete 用來刪除對象。new 會返回一個指針,在使用完畢后,要通過 delete 把這個指針指向的地址釋放掉。


    #include "Staff.h"?


    int main(int argc,char **argv) {? ??


    Staff * st1 = new Staff();? ? ?


    Staff * st2 = new Staff();? ? ?


    Staff * st3 = new Staff();? ? ?


    // 記得釋放? ??


    ?delete st1;? ? ?


    delete st2;? ? ?


    delete st3;? ? ?


    return 0;


    ?}


    查看全部
  • 霸道總裁的員工:類

    我們上一小節中介紹了面向對象的思想,這一小節開始,我們來具體看看在 C++ 中應該如何實現面向對象。

    類,是 C++ 實現面向對象最基礎的部分。類其實和之前學過的結構體十分相似,你可以認為類是結構體的升級版。

    類的申明

    在 C++ 中,可以用下面的代碼申明一個員工類:

    class Staff { };

    可以像使用結構體一樣使用這個類:

    #include <stdio.h> class Staff { }; int main(int argc,char **argv) { ? ? Staff st; ? ? return 0; }

    分文件編程

    我們在此之前都是把代碼放到一個文件里,但是這樣在實際工程中肯定是不行的,我們不可能把所有的代碼都寫到一個文件夾里面。而在 C++ 中我們就常常把類定義到不同的文件里面,把每個類都獨立起來,這樣代碼的耦合性就會降低,方便維護。

    在 C++ 中,我們可以把一個類寫到兩個文件里面,一個是后綴為 .h 或者 .hpp 的頭文件,一個是后綴為 .cpp 的實現文件。我們先在開發環境里新建一個類。輸入類名是 Staff。

    可以看到 VS 為我們創建類兩個文件,Staff.h 和 Staff.cpp。Staff.h 文件為定義,Staff.cpp 為實現。

    在分了文件之后,我們想要在 main 函數中引用這個類,就需要使用 #include “Staff.h” 將頭文件引入進來。

    實例化

    在新建了一個類之后,我們就可以根據這個類產生對象了。根據類產生對象的過程叫做實例化。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff st1; ? ? Staff st2; ? ? Staff st3; ? ? return 0; }

    這樣分配,我們將這三個“員工”分配到了棧上,同樣的,可以把他們分配到堆內存上面去。

    new delete

    要將對象分配到堆上,需要用到另外兩個關鍵字,new 和 delete。new 用來分配對象,delete 用來刪除對象。new 會返回一個指針,在使用完畢后,要通過 delete 把這個指針指向的地址釋放掉。

    #include "Staff.h"?

    int main(int argc,char **argv) {? ??

    Staff * st1 = new Staff(); ? ??

    Staff * st2 = new Staff(); ? ??

    Staff * st3 = new Staff(); ? ??

    // 記得釋放 ? ?

    ?delete st1; ? ??

    delete st2; ? ??

    delete st3; ? ??

    return 0;

    ?}

    查看全部
  • 霸道總裁的員工:類

    我們上一小節中介紹了面向對象的思想,這一小節開始,我們來具體看看在 C++ 中應該如何實現面向對象。

    類,是 C++ 實現面向對象最基礎的部分。類其實和之前學過的結構體十分相似,你可以認為類是結構體的升級版。

    類的申明

    在 C++ 中,可以用下面的代碼申明一個員工類:

    class Staff { };

    可以像使用結構體一樣使用這個類:

    #include <stdio.h> class Staff { }; int main(int argc,char **argv) { ? ? Staff st; ? ? return 0; }

    分文件編程

    我們在此之前都是把代碼放到一個文件里,但是這樣在實際工程中肯定是不行的,我們不可能把所有的代碼都寫到一個文件夾里面。而在 C++ 中我們就常常把類定義到不同的文件里面,把每個類都獨立起來,這樣代碼的耦合性就會降低,方便維護。

    在 C++ 中,我們可以把一個類寫到兩個文件里面,一個是后綴為 .h 或者 .hpp 的頭文件,一個是后綴為 .cpp 的實現文件。我們先在開發環境里新建一個類。輸入類名是 Staff。

    可以看到 VS 為我們創建類兩個文件,Staff.h 和 Staff.cpp。Staff.h 文件為定義,Staff.cpp 為實現。

    在分了文件之后,我們想要在 main 函數中引用這個類,就需要使用 #include “Staff.h” 將頭文件引入進來。

    實例化

    在新建了一個類之后,我們就可以根據這個類產生對象了。根據類產生對象的過程叫做實例化。這個過程就像是公司招聘員工一樣,幸運的是,我們作為程序的老板,并不需要和現實中一樣去張貼招聘啟示。在 C++ 中,“招聘“員工,只需要用以下的代碼就可以了。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff st1; ? ? Staff st2; ? ? Staff st3; ? ? return 0; }

    這樣分配,我們將這三個“員工”分配到了棧上,同樣的,可以把他們分配到堆內存上面去。

    new delete

    要將對象分配到堆上,需要用到另外兩個關鍵字,new 和 delete。new 用來分配對象,delete 用來刪除對象。new 會返回一個指針,在使用完畢后,要通過 delete 把這個指針指向的地址釋放掉。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff * st1 = new Staff(); ? ? Staff * st2 = new Staff(); ? ? Staff * st3 = new Staff(); ? ? // 記得釋放 ? ? delete st1; ? ? delete st2; ? ? delete st3; ? ? return 0; }

    查看全部
  • 霸道總裁的員工:類

    我們上一小節中介紹了面向對象的思想,這一小節開始,我們來具體看看在 C++ 中應該如何實現面向對象。

    類,是 C++ 實現面向對象最基礎的部分。類其實和之前學過的結構體十分相似,你可以認為類是結構體的升級版。之后的學習中你會更加理解類?,F在,我們只簡單得來介紹一下類。

    類的申明

    在 C++ 中,可以用下面的代碼申明一個員工類:

    class Staff { };

    可以像使用結構體一樣使用這個類:

    #include <stdio.h> class Staff { }; int main(int argc,char **argv) { ? ? Staff st; ? ? return 0; }

    分文件編程

    我們在此之前都是把代碼放到一個文件里,但是這樣在實際工程中肯定是不行的,我們不可能把所有的代碼都寫到一個文件夾里面。而在 C++ 中我們就常常把類定義到不同的文件里面,把每個類都獨立起來,這樣代碼的耦合性就會降低,方便維護。

    在 C++ 中,我們可以把一個類寫到兩個文件里面,一個是后綴為 .h 或者 .hpp 的頭文件,一個是后綴為 .cpp 的實現文件。我們先在開發環境里新建一個類。輸入類名是 Staff。

    可以看到 VS 為我們創建類兩個文件,Staff.h 和 Staff.cpp。Staff.h 文件為定義,Staff.cpp 為實現。

    在分了文件之后,我們想要在 main 函數中引用這個類,就需要使用 #include “Staff.h” 將頭文件引入進來。

    實例化

    在新建了一個類之后,我們就可以根據這個類產生對象了。根據類產生對象的過程叫做實例化。這個過程就像是公司招聘員工一樣,幸運的是,我們作為程序的老板,并不需要和現實中一樣去張貼招聘啟示。在 C++ 中,“招聘“員工,只需要用以下的代碼就可以了。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff st1; ? ? Staff st2; ? ? Staff st3; ? ? return 0; }

    這樣分配,我們將這三個“員工”分配到了棧上,同樣的,可以把他們分配到堆內存上面去。

    new delete

    要將對象分配到堆上,需要用到另外兩個關鍵字,new 和 delete。new 用來分配對象,delete 用來刪除對象。new 會返回一個指針,在使用完畢后,要通過 delete 把這個指針指向的地址釋放掉。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff * st1 = new Staff(); ? ? Staff * st2 = new Staff(); ? ? Staff * st3 = new Staff(); ? ? // 記得釋放 ? ? delete st1; ? ? delete st2; ? ? delete st3; ? ? return 0; }

    查看全部
  • 霸道總裁的員工:類

    我們上一小節中介紹了面向對象的思想,這一小節開始,我們來具體看看在 C++ 中應該如何實現面向對象。

    類,是 C++ 實現面向對象最基礎的部分。類其實和之前學過的結構體十分相似,你可以認為類是結構體的升級版。之后的學習中你會更加理解類?,F在,我們只簡單得來介紹一下類。

    類的申明

    在 C++ 中,可以用下面的代碼申明一個員工類:

    class Staff { };

    可以像使用結構體一樣使用這個類:

    #include <stdio.h> class Staff { }; int main(int argc,char **argv) { ? ? Staff st; ? ? return 0; }

    分文件編程

    我們在此之前都是把代碼放到一個文件里,但是這樣在實際工程中肯定是不行的,我們不可能把所有的代碼都寫到一個文件夾里面。而在 C++ 中我們就常常把類定義到不同的文件里面,把每個類都獨立起來,這樣代碼的耦合性就會降低,方便維護。

    在 C++ 中,我們可以把一個類寫到兩個文件里面,一個是后綴為 .h 或者 .hpp 的頭文件,一個是后綴為 .cpp 的實現文件。我們先在開發環境里新建一個類。輸入類名是 Staff。

    可以看到 VS 為我們創建類兩個文件,Staff.h 和 Staff.cpp。Staff.h 文件為定義,Staff.cpp 為實現。

    在分了文件之后,我們想要在 main 函數中引用這個類,就需要使用 #include “Staff.h” 將頭文件引入進來。

    實例化

    在新建了一個類之后,我們就可以根據這個類產生對象了。根據類產生對象的過程叫做實例化。這個過程就像是公司招聘員工一樣,幸運的是,我們作為程序的老板,并不需要和現實中一樣去張貼招聘啟示。在 C++ 中,“招聘“員工,只需要用以下的代碼就可以了。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff st1; ? ? Staff st2; ? ? Staff st3; ? ? return 0; }

    這樣分配,我們將這三個“員工”分配到了棧上,同樣的,可以把他們分配到堆內存上面去。

    new delete

    要將對象分配到堆上,需要用到另外兩個關鍵字,new 和 delete。new 用來分配對象,delete 用來刪除對象。new 會返回一個指針,在使用完畢后,要通過 delete 把這個指針指向的地址釋放掉。

    #include "Staff.h" int main(int argc,char **argv) { ? ? // 我們就這樣實例化了三個員工 ? ? Staff * st1 = new Staff(); ? ? Staff * st2 = new Staff(); ? ? Staff * st3 = new Staff(); ? ? // 記得釋放 ? ? delete st1; ? ? delete st2; ? ? delete st3; ? ? return 0; }

    查看全部
  • #include <stdio.h>

    #include <stdlib.h>

    #include <iostream>



    const int arrLength = 20;? ?// 數組長度


    double* getStusGrade()

    {

    ? ? // 學生成績數組

    ? ? double gradeArr[arrLength] = {

    ? ? 60.5, 62.5, 67.5, 40, 50, 60, 70, 80, 90, 100,

    ? ? 90.5, 12, 13.5, 84, 65, 76, 87, 88, 99, 20.5

    ? ? };


    ? ? // 堆內存上分配160個字節的內存空間 20×8個字節

    ? ? double* arrP = (double*)malloc(arrLength * sizeof(double));


    ? ? // 將棧內存上的數組數據添加到堆內存空間中

    ? ? for (int index = 0; index < arrLength; index++)

    ? ? {

    ? ? ? ? arrP[index] = gradeArr[index];

    ? ? }


    ? ? return arrP;

    }



    int main(int argc, char** argv)

    {

    ? ? double* ptr = getStusGrade();


    ? ? // 輸出學生成績

    ? ? for (int index = 0; index < arrLength; index++)

    ? ? {

    ? ? ? ? std::cout << "學生" << index + 1 << "的數學成績是:" << ptr[index] << std::endl;

    ? ? }


    ? ? free(ptr);

    ? ? ptr = nullptr;


    ? ? return 0;

    }

    查看全部
    2 采集 收起 來源:強者爭霸

    2021-07-30

  • 指針變量其實和普通變量沒有什么區別,一個函數也是可以正常返回一個指針的。

    char * func()
    {
    ? ?char * p = nullptr;
    ? ?return p;
    }

    int main(int argc,char **argv)
    {
    ? ?return 0;
    }

    但是我們需要思考的是,什么情況下我們要返回一個指針,返回指針的時候需要我們注意些什么?

    通常情況下,我們是希望為函數外提供一片內存,例如,我們可以給函數外面提供一個數組。

    int * func()
    {
    ? ?int arr[] = {1, 2, 3, 4};
    ? ?return arr;
    }

    但是這樣寫得話,程序會崩潰掉。原因是,arr 數組是一個局部變量,在 func 結束之后,其內存就被銷毀掉了。此時在函數外面對其進行操作,自然會出問題。所以,要完成這類操作,我們需要把內存分配到堆內存上面。

    int * func()
    {
    ? ?int * arr = (int *)malloc(4 * sizeof(int));
    ? ?return arr;
    }

    這樣就沒有問題了,當然,既然是分配在了堆內存上,就要記得手動銷毀。

    int main(int argc,char **argv)
    {
    ? ?int * p = func();
    ? ?free(p);
    ? ?return 0;
    }

    查看全部
  • 代碼塊中定義的變量被稱之為局部變量。它們在其他函數的語句中是不可見的,也無法訪問它們。

    全局變量是在所有函數體的外部定義的,程序的所有部分都可以使用。全局變量不受作用域的影響,其生命周期一直到程序的結束。

    int a = 2;

    int main(int argc,char **argv)
    {
    ? ?return 0;
    }

    靜態變量受作用域的影響,其生命周期一直到程序的結束。

    例如:

    void func()
    {
    ? ?static int a = 0;
    }

    我們可以在函數中申明一個靜態變量。值得注意的是,這個變量的作用域雖然是在函數內,但是他并不會隨著函數結束而被銷毀,它會一直存在到程序的結束。

    查看全部

舉報

0/150
提交
取消
課程須知
你需要具備基礎的 C++ 語法知識,在學習本課程之前,建議先學習《趣味 C++ 入門》,快速認識 C++,熟悉 C++ 基本語法,更加快速入手進階課程!
老師告訴你能學到什么?
在本門課程中,你將學習到:計算機存儲數據的原理、指針的進階、面向對象編程、內存管理技巧等 C++ 高級語法。在課程的最后,將帶領大家使用 C++ 編寫一個五子棋游戲,通過實踐,加深理解,鞏固學習成果。

微信掃碼,參與3人拼團

微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

友情提示:

您好,此課程屬于遷移課程,您已購買該課程,無需重復購買,感謝您對慕課網的支持!