C 與 C++

weixin_34054866發表於2018-10-21

https://www.bilibili.com/video/av18629275?p=4

C++比C多了什麼

C++比C新增資料型別

  • auto
  • long long
  • bool 布林型別
  • wchar_t 寬字元
  • class 類型別
  • & 引用型別

C++比C新增的關鍵字,C語言關鍵字32個。

物件導向特性

  • 類:封裝、繼承、多型、過載、抽象
  • 物件

泛型程式設計特性

  • 模板
  • 泛型

結構體

  • C的結構體不允許有函式的存在,C++允許有內部成員函式,且允許該函式為虛擬函式。所以C的結構體是沒有建構函式、解構函式、this指標等。
  • C的結構體對內部成員變數的訪問許可權只能是public,C++允許public、protected、private三種。
  • C語言的結構體是不可繼承的,C++的結構體是可以從其他的結構體或類繼承過來的。

typeid

typeid() 操作符的作用是獲取一個表示式的型別,返回結果是const type_info&型別。不同編譯器實現的type_info class各不相同,但C++標準保證它會實現一個name()方法,該方法返回型別名字的c-style字串。

使用方法:typeid(型別或變數或表示式).name() //返回型別名字的字串

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;

struct User
{
    string username;
    string nickname;
};

int main()
{
    //輸出型別名稱
    cout << typeid(int).name() << endl;//int
    cout << typeid(User).name() << endl;//struct User
    //輸出變數型別
    char c = 'a';
    cout << typeid(c).name() << endl;//char
    //輸出表示式型別
    cout << typeid(3.14 * 2).name() << endl;//double
    //輸出字串型別
    cout << typeid("hello").name() << endl;//char const [6]
    //輸出指標型別
    int *p = NULL;
    cout << typeid(p).name() << endl;//int *
    //輸出常量型別
    const char *pc = NULL;
    cout << typeid(pc).name() << endl;//char const *

    return 0;
}

C++新增型別

wchar_t 型別

wchar_t型別主要用在國際化程式的實現中,unicode編碼的寬字元一般以wchar_t型別儲存。

char型別與wchar_t型別的區別

4933701-17c038d2dbc7c9e0.png
區別

字母L告訴編譯器該字元作為wchar_t字串來編譯

#include <iostream>
using namespace std;

int main()
{
    //單位元組字元
    char c = 'A';
    //寬位元組字元
    wchar_t w = L'A';
    //輸出大小
    cout << c << " byte is " << sizeof(c) << endl;//1
    wcout << w << " byte is " << sizeof(w) << endl;//2
    //中文輸出
    wchar_t cn = L'中';
    wcout.imbue(locale("chs"));//預設Locale為EN_US,需設定為ch。
    wcout << cn << " byte is " << sizeof(cn) << endl;

    return 0;
}

bool型別

  • 布林型別,佔1個位元組,0表示假,非0表示真,用於條件判斷。
  • false/true是標準C++語言中新增的關鍵字,是bool型別。
#include <iostream>
using namespace std;

int main()
{

    bool flag = false;
    cout << "flag size is " <<sizeof(flag) << "byte" << endl;//1
    cout << (flag == 0) << endl;//1

    return 0;
}

long long 型別

long佔4個位元組,long long佔8個位元組,實現了32位機器上可擴充套件8位元組的資料。

引用

C++引入了“引用型別”,即一個變數是另一個變數的別名。

#include <iostream>
using namespace std;

int main()
{
    double pi = 3.1415927;
    //設定p為pi的別名
    double &p = pi;//&p表示定義引用變數
    //設定p的記憶體塊值
    p = 100;
    
    cout << p << endl; //100
    cout << pi << endl; //100

    return 0;
}

引用變數可用作函式的形式引數,表示形參和實參實際上是同一個物件。在函式中對形參的修改,也是對實參的修改。

C語言中實現變數互換值

#include <iostream>
using namespace std;

void swap(int *x, int *y)
{
    int t = *x;
    *x = *y;
    *y = t;
}

int main()
{
    int x = 100;
    int y = 200;
    swap(&x, &y);
    cout << x << " " << y << endl;
}

C++使用引用實現變數互換值

#include <iostream>

using namespace std;
// x和y表示實參的引用
void swap(int &x, int &y)
{
    int t = x; x = y; y = t;
}

int main()
{
    int x = 100, y = 200;
    swap(x, y);
    cout << x << " " << y << endl;//200 100
}

當實參佔據的記憶體比較大的時候,使用引用代替傳值(需複製)可提高效率。若不希望因此“無意中”修改了實參,可用const修改符。

#include <iostream>

using namespace std;

// &表示實參的引用,const表示不可修改。
void init(int &x, const int &y)
{
    x = 100;
}

int main()
{
    int x, y;
    init(x, y);
    cout << x << " " << y << endl;//100 6422368
}

行內函數

對於不包含迴圈的簡單函式,建議使用inline關鍵字宣告為行內函數。編譯器將行內函數呼叫使用其程式碼展開,稱為內聯展開,避免函式呼叫開銷,提高程式執行效率。即不將其作為函式而是直接作為表示式來使用。

//行內函數
inline double distance(double x, double y)
{
    return sqrt(x*x + y*y);
}

異常處理

C++通過try-catch處理異常情況,正常程式碼放在try塊,catch中捕獲try塊丟擲的異常。

#include <iostream>
using namespace std;

int main()
{
    int value = 0;

    cout << "Enter Value : ";
    cin >> value;

    try
    {
        if(value > 100){
            throw 1;
        }
        if(value < 0){
            throw 0;
        }
        throw value/2;
    }catch(int result){
        cout << "Result is " << result << endl;
    }

    return 0;
}

https://www.bilibili.com/video/av18629275/?p=5

預設形參

函式的形參可帶預設值,必須一律在最右邊。

double test(double x=0, double y=0)
{
    return x-y;
}

函式過載

C++允許函式同名,只要它們的形參不一樣,即個數或物件引數型別不同。呼叫函式時將根據實參和形參的匹配選擇最佳函式,如果有多個難以區分的最佳函式,則變化一起報錯。注意的是不能根據返回型別來區分同名函式。

運算子過載

模板函式

模板template函式,厭倦了對每種型別求最小值。

#include <iostream>

using namespace std;
// 可對任何能比較大小的型別使用該模板
// 讓編譯器自動生成一個針對該資料型別的具體函式
template<class T>
T tmin(T x, T y)
{
    return x<y ? x : y;
}

int main()
{
    int x=1, y=2;
    cout << tmin(x, y) << endl;

    double a=0.1, b=1.0;
    cout << tmin(a,b) << endl;

    return 0;
}
#include <iostream>
using namespace std;

template<class T1, class T2>
T1 tmin(T1 x, T2 y)
{
    return x<y ? x : (T1)y;
}

int main()
{
    int x=1, y=2;
    cout << tmin(x, y) << endl;

    double a=0.1, b=1.0;
    cout << tmin(a,b) << endl;

    cout << tmin(x,b) << endl;

    return 0;
}

動態分配記憶體

C++關鍵字newdelete比C語言的mallocallocreallocfree更好,可以對類物件呼叫初始化建構函式或銷燬解構函式。

堆儲存區:mallocallocreallocfree

#define _CRT_SECURE_NO_WARNINGS //windows
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    double d = 3.14; 
    double *dp; 
    dp = &d; 
    *dp = 4.14;
    cout<<"d="<<d<<"\n&d="<<&d<<"\n*dp="<<*dp<<"\ndp="<<dp<<endl;

    return 0;
}

輸出值

d=4.14
&d=0x61ff10
*dp=4.14
dp=0x61ff10

程式碼解析

 double d = 3.14; 

變數d是一塊存放double型別值的記憶體塊

double *dp;

指標變數dp表示儲存double型別的地址變數,dp值的型別是double *, dp是存放double *型別值的記憶體塊。

dp = &d; // 0x61ff10

取地址運算子&用於獲取變數的記憶體地址,將double變數d的記憶體地址(指標)儲存到double*指標變數dp中,dp&d的型別都是double *

*dp = 4.14;

解引用運算子*用於獲得指標變數指向的那個變數

https://www.bilibili.com/video/av18629275/?p=9

相關文章