C++入門

C 是面向過程的語言,而 C ++ 是面向對象的語言。

C ++ 在某種程度上,可以理解為 C 語言強化版。兩種語言有不少相似之處,且大部分時候,C ++ 可以兼容 C 語言。C ++ 可以直接運行 C 語言函數,但 C 語言不能調用 C ++。

C ++ 中,const 常量的不可變性得到了支持,而在 C 中,函數定義的 const 常量,可以通過指針修改。

C ++ 支持函數重載(同名函數,不同參數),C 不支持(C 函數名稱不可重復);C++ 的函數支持默認參數,C 和java 都不支持。

C ++ 有 string、bool 類型,而 C 中沒有專門的string、bool;但二者都是非 0 即 true

命名空間

命名空間,作用類似于 java 中的包名,為了在引用時區分不同庫中定義的同名函數或變量。

命名空間可以用雙冒號(::)表示;也可以直接在文件中用using指示進行聲明,使得特定命名空間的所有名字可見

#include <stdio.h>
#include <iostream>
int main() {
    // C ++ 中,可以調用 C 語言的輸出方法
    printf("this is a C output in C++\n");
    // C ++ 自己的輸出方法
    // << 運算符被重載,此處并不是左移,而是輸出流拼接,可以理解為輸出格式
    std::cout << "this is a C++ couput" << std::endl;
    return 0;
}

// 直接聲明命名空間
//using namespace std;
//
//int main() {
//    //聲明命名空間后,無需再用 std:: 方式指明函數的所在
//    cout << "this is the output with namespace" << endl;
//    return 0;
//}

自定義命名空間

命名空間的定義一般置于 .hpp 的頭文件中,作為對外開放的接口聲明。

// 自定義一個命名空間
namespace bynamespace {
// 命名空間可以有變量
char * property;
// 類
class ObjectManager {
private:
    char *className;
public:
    char * getClassName();
    void setClassName(char *className);
};
// 方法
void function(ObjectManager manager);
// 方法可能與其他命名空間的方法沖突
void cout();
// 命名空間內還可以嵌套命名空間
namespace subnamespace {
void sayHello();
}
}

// 添加命名空間引用
using namespace std;
using namespace bynamespace;


int main() {
    // 由于添加了引用,可以省略命名空間的名稱
    ObjectManager manager = ObjectManager();
    bynamespace::function(manager);
    // 嵌套的命名空間,在沒有添加命名空間引用時,應為:bynamespace::subnamespace::sayHello();
    subnamespace::sayHello();
    // 當兩個命名空間內方法沖突時,不可以省略命名空間名稱,即便已經添加了引用
    bynamespace::cout();
    std::cout << "print" << endl;
    return 0;
}

函數特性

C++ 中,函數支持重載和傳參默認值,但是默認值不似 kotlin 中那般靈活。C++ 中函數的參數默認值,必須從右往左進行默認值設置;在調用時,必須從左到右,傳入參數。

且在函數聲明時,需注意,要避開默認值可能帶來的函數重載。

using namespace std;

// 全賦值默認參數;此方法在調用時,無法跳過 a、b 直接給 c、d 賦值
int sum(string s, int a = 0, int b = 0, int c = 0, int d = 0) {
    // sum(); -> a: 0, b: 0, c: 0, d: 0
    // sum(1, 2); -> a: 1, b:2, c:0, d:0
    // sum(1, 2, 3, 4); -> a: 1, b:2, c:3, d:4
    cout << "a: " << a << ", b:" << b << ", c:" << c << ", d:" << d << endl;
    return a + b + c + d;
}

// 不能這樣賦值默認值,必須從右到左填充,填充完 a,之后才可以填充 s
// int sum(string s = "abc", int a, int b = 0, int c = 0, int d = 0)

// 此方法無法再進行聲明,因為在上面的sum中,已經包含了兩個 int 參數的重載
// 但在聲明方法時,并不會報錯,而是在使用方法時報錯
// int sum(string a, int b);

// 此方法可以重載,因為上面默認值的方法第一個參數是 string,重載的方法,需從左到右保留參數 
int sum(int a, int b);


int main() {
    int t1 = sum("test1");
    int t2 = sum("test2", 1, 2);
    int t3 = sum("test3", 1, 2, 3, 4);
    // 如果上面聲明了 int sum(string a, int b) 方法,則會報錯:Call to 'sum' is ambiguous
    // int t4 = sum("test4", 1);
    cout << "t1: " << t1 << ", t2:" << t2 << ", t3:" << t3 << endl;
    return 0;
}

此外,在 C 或者 C++ 中,函數的參數聲明,可能只有類型,而沒有參數名。

一般這種沒有參數名的函數聲明,只是用于 .h 的聲明中,在后續的實現函數中還是需要填寫名稱的,否則沒有參數名的形參無法在函數體內被使用。

// 在參數聲明時,只有類型 int,沒有參數名
void printInfo(const int &, int);
// 調用時需要傳入一個 string 類型,但是并沒有任何用處,不建議這么寫
void printInfo(string) {
    cout << endl;
}
int main() {
    int a = 100;
    // 調用時,必須傳遞該 int 類型參數
    printInfo(a, 0);
    return 0;
}
void printInfo(const int &value, int level) {
    cout << "value: " << value << ", level: " << level << endl;
}

靜態變量

靜態變量可以直接在函數外部進行定義,全局可用。

static int DEBUG = 1;

在類中,需要先聲明的靜態變量,然后再初始化

class Test {
  public:
    // 先聲明
    const int a;
}
// 再初始化
int Test::a = 10;

可變參數

C 和 C++ 中,都支持 ... 可變參數。
但與java 不同的是,無法自動識別參數個數。
因而一般在定義時,都會在參數前添加 int cout 參數聲明接下來的 ...包含幾個變量。
... 參數必須位于最后一個位置。
... 支持傳入不同基本類型(不支持自定義類型),但需要在解析的時候按順序解析。

在使用 ... 參數時,需要先創建 va_list 類型變量用于存儲這一系列參數。
通過 va_start(args, count) 將變量的值轉移到 va_list 中;其中 count 變量需要傳值 ... 的前一個函數入參。
通過 va_arg(ags, int) 方法,將 args 中的參數取出,其中int 為對應參數的類型。
最后需要用 va_end(args) 結束 args 的讀取。

int sum(int count, ...) {
    int result = 0;
    // 創建存儲入參的變量
    va_list args;
    // va_start 將入參讀取到 args 中,需要 ... 參數的前一個參數作為讀取錨點
    va_start(args, count);
    for (int i = 0; i < count; i++) {
        // va_arg 讀取 args 中的參數,需要傳入對應的數據類型
        result += va_arg(args, int);
    }
    // 結束讀取后,需要調用 var_end 方法
    va_end(args);
    return result;
}

int main() {
    cout << sum(2, 10, 20) << endl;
    return 0;
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容