中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

[C++]打開新世界的大門之C++入門-創(chuàng)新互聯(lián)

🥁作者:華丞臧
📕????專欄:【C++】
各位讀者老爺如果覺得博主寫的不錯,請諸位多多支持(點贊+收藏+關注)。如果有錯誤的地方,歡迎在評論區(qū)指出。

成都創(chuàng)新互聯(lián)公司主營八宿網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,重慶APP開發(fā)公司,八宿h5微信小程序定制開發(fā)搭建,八宿網(wǎng)站營銷推廣歡迎八宿等地區(qū)企業(yè)咨詢

推薦一款刷題網(wǎng)站 👉LeetCode

目錄

一、C++關鍵字(C++98)

二、命名空間?

2.1 命名空間定義

2.2 命名空間使用

三、C++輸入&輸出

四、缺省參數(shù)

4.1 缺省參數(shù)概念

4.2 缺省參數(shù)分類

全缺省參數(shù)

半缺省參數(shù)

五、函數(shù)重載

5.1 函數(shù)重載概念

5.2 C++支持函數(shù)重載的原理--名字修飾(name mangling)

六、內(nèi)聯(lián)函數(shù)

6.1 內(nèi)聯(lián)函數(shù)概念

6.2 特性

七、auto關鍵字(C++11)

7.1 類型別名思考

7.2 auto

7.3 auto使用細則

1. auto與指針和引用結合起來使用

2. 在同一行定義多個變量

7.4 auto不能推導的場景

八、基于范圍的for循環(huán)(C++11)

8.1 范圍for的語法

8.2 范圍for的使用條件

九、指針空值nullptr(C++)

9.1 C++98中的指針空值



一、C++關鍵字(C++98)

C++總計63個關鍵字,對比C語言32個關鍵字。

二、命名空間?

在C/C++中,變量、函數(shù)和后面要學到的類都是大量存在的,這些變量、函數(shù)和類的名稱將都存在于全局作用域中,可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突或名字污染,namespace關鍵字的出現(xiàn)就是針對這種問題。

在C語言當中,不能有相同名字的變量或者函數(shù)名。

#include#includeint rand = 10;
// C語言沒辦法解決類似這樣的命名沖突問題,所以C++提出了namespace來解決
int main()
{
 printf("%d\n", rand);
return 0;
}
// 編譯后后報錯:error C2365: “rand”: 重定義;以前的定義是“函數(shù)”
2.1 命名空間定義

定義命名空間,需要使用到?namespace?關鍵字,后面跟命名空間的名字,然后接一對{}即可,{}中即為命名空間的成員。

// bit是命名空間的名字,一般開發(fā)中是用項目名字做命名空間名。
// 我們上課用的是bit,大家下去以后自己練習用自己名字縮寫即可,如張三:zs
// 1. 正常的命名空間定義
namespace bit
{
 // 命名空間中可以定義變量/函數(shù)/類型
     int rand = 10;
     int Add(int left, int right)
     {
         return left + right;
     }
     struct Node
     {
         struct Node* next;
         int val;
     };
}
//2. 命名空間可以嵌套
// test.cpp
namespace N1
{
    int a;
    int b;
    int Add(int left, int right)
    {
        return left + right;
    }
    namespace N2
    {
        int c;
        int d;
        int Sub(int left, int right)
        {
            return left - right;
        }
    };
}
//3. 同一個工程中允許存在多個相同名稱的命名空間,編譯器最后會合成同一個命名空間中。
// ps:一個工程中的test.h和上面test.cpp中兩個N1會被合并成一個
// test.h
namespace N1
{
    int Mul(int left, int right)
    {
        return left * right;
    }
}

注意:一個命名空間就定義了一個新的作用域,命名空間中的所有內(nèi)容都局限于該命名空間中

2.2 命名空間使用

命名空間中成員該如何使用呢?

#includenamespace bit
{
    //命名空間中可以定義變量/函數(shù)/類型
	int a = 0;
	int b = 1;

	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int val;
	};
}

int main()
{
    //編譯報錯:error C2065: “a”: 未聲明的標識符
	printf("%d\n", a);
    //正確使用
    printf("%d\n",bit::a);
	return 0;
}

命名空間的使用有三種方式:

  • 加命名空間名稱及作用域限定符
int main()
{
    printf("%d\n", N::a);
    return 0;    
}
  • 使用 using 將命名空間中某個成員引入,即部分展開
using N::b;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;    
}
  • 使用 using namespace 命名空間名稱 引入,即完全展開
using namespce N;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

命名空間中的變量是全局變量,命名空間不會影響變量的生命周期;只是限定變量的作用域,影響編譯查找規(guī)則;命名空間定義是在全局,所以放在靜態(tài)區(qū)。

三、C++輸入&輸出

第一個C++程序

#includeusing namespace std;

int main()
{
	cout<< "Hello world!"<< endl;
	return 0;
}

說明:

  1. 使用cout標準輸出對象(控制臺)和cin標準輸入對象(鍵盤)時,必須包含頭文件,以及按命名空間使用方法使用std.
  2. cout和cin是全局的流對象,endl是特殊的C++符號,表示換行輸出等同于‘\0’,他們都包含在頭文件中。
  3. <<是流插入運算符,>>是流提取運算符。
  4. 使用這種C++輸入輸出方式更加方便,相較于C語言C++不需要手動控制格式,C++的輸入輸出可以自動識別變量類型。
  5. 實際上cout和cin分別是ostream和istream類型的對象,<<和>>也涉及運算符重載等知識。
四、缺省參數(shù) 4.1 缺省參數(shù)概念

缺省參數(shù)是聲明或定義函數(shù)時為函數(shù)的參數(shù)指定一個缺省值。在調(diào)用這個函數(shù)時,如果用戶沒有指定實參則采用該形參的缺省值,否則使用指定實參。

4.2 缺省參數(shù)分類
  • 全缺省參數(shù)

所謂全缺省參數(shù)就是指一個函數(shù)的全部參數(shù)都指定一個缺省值。

void Func(int a = 10, int b = 20, int c = 30)
{
    cout<<"a = "<
  • 半缺省參數(shù)

所謂半缺省參數(shù)就是指函數(shù)參數(shù)中至少有一個非缺省參數(shù)。?

//錯誤
void Func(int a = 10, int b = 20, int c)
{
    cout<<"a = "<

注意:

  1. 半缺省參數(shù)必須從右往左依次給出,不能間隔著給;
  2. 缺省參數(shù)不能在函數(shù)聲明和定義中同時出現(xiàn);
  3. 缺省值必須是常量或者全局變量;
  4. 缺省參數(shù)不能在函數(shù)聲明和定義中同時出現(xiàn);當同時有聲明和定義時,缺省參數(shù)只能在.h當中。
  5. C語言不支持缺省參數(shù)(編譯器不支持)。

五、函數(shù)重載 5.1 函數(shù)重載概念

函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的形參列表(參數(shù)個數(shù)或類型或類型順序)不同,常用來處理實現(xiàn)功能類似數(shù)據(jù)類型不同的問題。

#includeusing namespace std;
// 1、參數(shù)類型不同
int Add(int left, int right)
{
	cout<< left + right<< endl;
	return left + right;
}
double Add(double left, double right)
{
	cout<< left + right<< endl;
	return left + right;
}
// 2、參數(shù)個數(shù)不同
void f()
{
	cout<< "f()"<< endl;
}
void f(int a)
{
	cout<< "f(int a)"<< endl;
}
// 3、參數(shù)類型順序不同
void f(int a, char b)
{
	cout<< "f(int a,char b)"<< endl;
}
void f(char b, int a)
{
	cout<< "f(char b, int a)"<< endl;
}
int main()
{
	Add(1, 2);
	Add(1.1, 2.2);
	f();
	f(10);
	f(10, 'a');
	f('a', 10);
	return 0;
}

5.2 C++支持函數(shù)重載的原理--名字修飾(name mangling)

為什么C++支持函數(shù)重載而C語言不支持函數(shù)重載呢?

????????在C/C++中,一個程序要運行起來,需要經(jīng)歷以下幾個階段:預處理、編譯、匯編、鏈接。在編譯階段,編譯器會匯總全局的符號,如main函數(shù)、全局變量、函數(shù)名等;然后在匯編階段,編譯器會給編譯時匯總的每個符號分配一個地址(注意如果符號只是聲明則會分配一個無效的地址),并且在對應的.o文件中形成一個符號表;各個.o文件的符號表在鏈接時會合并,并且在合并時同名的符號會選擇有效的地址進行合并。

? 在C語言當中,C語言的編譯器并不會根據(jù)函數(shù)參數(shù)的特性對函數(shù)名進行修飾;這就導致即使函數(shù)形參列表不同只要函數(shù)名相同,那么符號匯總時就會出現(xiàn)同名的符號,這時編譯器就會報錯。

? 在C++中,同名的函數(shù)只要形參列表不同,C++編譯器會根據(jù)名字修飾規(guī)則對函數(shù)名進行修飾,這時在編譯時同名但形參列表不同的函數(shù)就會形成不同的符號;既然不出現(xiàn)同名符號,編譯器自然不會報相應的錯誤。

? 如果兩個函數(shù)函數(shù)名和參數(shù)是一樣的,返回值不同是不構成重載的,因為調(diào)用是存在二義性,編譯器無法區(qū)分。

注意:不同平臺的C++編譯器的名字修飾規(guī)則不一樣,但是產(chǎn)生的效果是一樣的。

六、內(nèi)聯(lián)函數(shù) 6.1 內(nèi)聯(lián)函數(shù)概念

以inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時C++編譯器會在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開,沒有函數(shù)調(diào)用建立棧幀的開銷,內(nèi)聯(lián)函數(shù)提升程序運行的效率。

如果在上述函數(shù)前增加?inline?關鍵字將其改成內(nèi)聯(lián)函數(shù),在編譯期間編譯器會用函數(shù)體替換函數(shù)的調(diào)用。

查看方式:

  1. 在release模式下,查看編譯器生成的匯編代碼中是否存在call Add
  2. 在debug模式下,需要對編譯器進行設置,否則不會展開(因為debug模式下,編譯器默認不 會對代碼進行優(yōu)化,以下給出vs2013的設置方式)

6.2 特性
  1. inline是一種以空間換時間的做法,如果編譯器將函數(shù)當成內(nèi)聯(lián)函數(shù)處理,在編譯階段,會 用函數(shù)體替換函數(shù)調(diào)用.缺陷:可能會使目標文件變大;優(yōu)勢:少了調(diào)用開銷,提高程序運行效率。
  2. inline對于編譯器而言只是一個建議,不同編譯器關于inline實現(xiàn)機制可能不同,一般建議:將函數(shù)規(guī)模較小(即函數(shù)不是很長,具體沒有準確的說法,取決于編譯器內(nèi)部實現(xiàn))、不是遞歸、且頻繁調(diào)用的函數(shù)采用inline修飾,否則編譯器會忽略inline特性。

在《C++prime》第五版中關于inline的建議:

內(nèi)聯(lián)說明只是向編譯器發(fā)出一個請求,編譯器可以選擇忽略這個請求。

一般來說,內(nèi)聯(lián)機制用于優(yōu)化規(guī)模較小、流程直接、頻繁調(diào)用的函數(shù)。很多編譯器都不支持內(nèi)聯(lián)遞歸函數(shù),而且一個75行的函數(shù)也不太可能在調(diào)用點內(nèi)聯(lián)展開(75不是編譯器規(guī)定的)。

3.inline不建議聲明和定義分離,分離會導致鏈接錯誤。因為inline被展開,就沒有函數(shù)地址 了,鏈接就會找不到。

注意:

當內(nèi)聯(lián)函數(shù)太長,編譯不會將其在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開;此時函數(shù)相當于一個正常的函數(shù),編譯器給該函數(shù)符號分配地址合成在符號表中,然后通過符號表調(diào)用該函數(shù)。

說明:func是一個很長的函數(shù)。

如上圖所示,當內(nèi)聯(lián)函數(shù)很長時,編譯器不會在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開 ,可以看到內(nèi)聯(lián)函數(shù)會分配一個地址,然后編譯器調(diào)通過地址調(diào)用該內(nèi)聯(lián)函數(shù)。

【面試題】

1. 宏的優(yōu)缺點?

優(yōu)點:

  1. 增強代碼的復用性;
  2. 提高性能。

缺點:

  1. 不方便調(diào)試宏;(因為預編譯階段進行了替換)
  2. 導致代碼可讀性差,可維護性差,容易誤用;
  3. 沒有類型安全檢查。

2. C++有哪些技術替換宏?

  1. 常量定義換用 const enum;
  2. 短小函數(shù)定義 換用內(nèi)聯(lián)函數(shù)。
七、auto關鍵字(C++11) 7.1 類型別名思考

隨著程序越來越復雜,程序中用到的類型也越來越復雜,經(jīng)常體現(xiàn)在:

  1. 類型難于拼寫
  2. 含義不明確導致容易出錯
//這是一個例子
//下面的代碼不一定認識
//但是這是C++的代碼
#include#includeint main()
{
 std::mapm{ { "apple", "蘋果" }, { "orange", 
"橙子" }, 
   {"pear","梨"} };
 std::map::iterator it = m.begin();
 while (it != m.end())
 {
 //....
 }
 return 0;
}

可以看到上述代碼中:

//這是一個類型,但是該類型太長,容易寫錯
std::map::iterator

我們可以使用typedef給類型取別名以簡化代碼,但是typedef有會遇到新的難題:

//如:typedef std::map::iterator iterator;


typedef char* pstring;
int main()
{
 const pstring p1;    // 編譯成功還是失???
 const pstring* p2;   // 編譯成功還是失???
 return 0;
}

在編程時,常常需要把表達式的值賦值給變量,這就要求在聲明變量的時候清楚地知道表達式的 類型。然而有時候要做到這點并非那么容易,因此C++11給auto賦予了新的含義。

7.2 auto

在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動存儲器的局部變量。

C++11中,標準委員會賦予了auto全新的含義即:auto不再是一個存儲類型指示符,而是作為一 個新的類型指示符來指示編譯器,auto聲明的變量必須由編譯器在編譯時期推導而得。

#includeusing namespace std;

int TestAuto()
{
    return 10;
}

//typeid().name() 用來求變量的類型對于的字符串
int main()
{
    int a = 10;
    auto b = a;
    auto c = 'a';
    auto d = TestAuto();
    cout<< typeid(b).name()<< endl;
    cout<< typeid(c).name()<< endl;
    cout<< typeid(d).name()<< endl;
    //auto e; 無法通過編譯,使用auto定義變量時必須對其進行初始化
    return 0;
}

運行程序,可以看到下圖:??

【注意】

使用auto定義變量時必須對其進行初始化,在編譯階段編譯器需要根據(jù)初始化表達式來推導auto 的實際類型。因此auto并非是一種“類型”的聲明,而是一個類型聲明時的“占位符”,編譯器在編 譯期會將auto替換為變量實際的類型。

7.3 auto使用細則 ??1. auto與指針和引用結合起來使用

? 用auto聲明指針類型時,用auto和auto*沒有任何區(qū)別,但用auto聲明引用類型時則必須加&。

#includeusing namespace std;

int main()
{
    int x = 10;
    auto a = &x;
    auto* b = &x;
    auto& c = x;
    cout<< typeid(a).name()<< endl;
    cout<< typeid(b).name()<< endl;
    cout<< typeid(c).name()<< endl;
    *a = 20;
    *b = 30;
    c = 40;
    return 0;
}

2. 在同一行定義多個變量

當在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯,因為編譯 器實際只對第一個類型進行推導,然后用推導出來的類型定義其他變量。

void TestAuto()
{
    auto a = 1, b = 2; 
    auto c = 3, d = 4.0;  // 該行代碼會編譯失敗,因為c和d的初始化表達式類型不同
}

上述代碼編譯會出錯,如下圖所示:?

7.4 auto不能推導的場景

1. auto不能作為函數(shù)的參數(shù);

auto不能作為形參類型,因為編譯器無法對形參的實際類型進行推導。

2. auto不能直接用來聲明數(shù)組;

3.?為了避免與C++98中的auto發(fā)生混淆,C++11只保留了auto作為類型指示符的用法;

4. auto在實際中最常見的優(yōu)勢用法就是跟以后會講到的C++11提供的新式for循環(huán),還有 lambda表達式等進行配合使用。

八、基于范圍的for循環(huán)(C++11) 8.1 范圍for的語法

在C++98中如果要遍歷一個數(shù)組,可以按照以下方式進行:

void TestFor()
{
    int array[] = { 1, 2, 3, 4, 5 };

    for (int i = 0; i< sizeof(array) / sizeof(array[0]); ++i)
         array[i] *= 2;

    for (int* p = array; p< array + sizeof(array)/ sizeof(array[0]); ++p)
         cout<< *p<< endl;
}

對于一個有范圍的集合而言,由程序員來說明循環(huán)的范圍是多余的,有時候還會容易犯錯誤。因 此C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號由冒號“ :”分為兩部分:第一部分是范 圍內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍。

void TestFor()
{
    int array[] = { 1, 2, 3, 4, 5 };
    for(auto& e : array)
        e *= 2;
    //注意下面代碼中e是數(shù)組元素的拷貝,改變e不會改變數(shù)組當中的元素
    for(auto e : array)  
         cout<< e<< " ";
}

注意:與普通循環(huán)類似,可以用continue來結束本次循環(huán),也可以用break來跳出整個循環(huán)。??

上述程序同樣可以遍歷數(shù)組,使用引用可以改變數(shù)組的值;

8.2 范圍for的使用條件

1. for循環(huán)迭代的范圍必須是確定的;

對于數(shù)組而言,就是數(shù)組中第一個元素和最后一個元素的范圍;對于類而言,應該提供begin? ? ? ? ? 和end的方法,begin和end就是for循環(huán)迭代的范圍。

//注意:以下代碼就有問題,因為for的范圍不確定
void TestFor(int array[])
{
    for(auto& e : array)
        cout<< e<

2. 迭代的對象要實現(xiàn)++和==的操作。(了解一下就行)?

九、指針空值nullptr(C++) 9.1 C++98中的指針空值

在良好的C/C++編程習慣中,聲明一個變量時最好給該變量一個合適的初始值,否則可能會出現(xiàn) 不可預料的錯誤,比如未初始化的指針。如果一個指針沒有合法的指向,我們基本都是按照如下 方式對其進行初始化:

void TestPtr()
{
int* p1 = NULL;
int* p2 = 0;
// ……
}

NULL實際是一個宏,在傳統(tǒng)的C頭文件(stddef.h)中,可以看到如下代碼:?

#ifndef NULL
#ifdef __cplusplus  //C++中NULL為0,而不是空指針
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif

可以看到,NULL可能被定義為字面常量0,或者被定義為無類型指針(void*)的常量。不論采取何 種定義,在使用空值的指針時,都不可避免的會遇到一些麻煩,比如:?

#includeusing namespace std;

void f(int)
{
     cout<<"f(int)"<

程序本意是想通過f(NULL)調(diào)用指針版本的f(int*)函數(shù),但是由于NULL被定義成0,因此與程序的 初衷相悖。

在C++98中,字面常量0既可以是一個整形數(shù)字,也可以是無類型的指針(void*)常量,但是編譯器 默認情況下將其看成是一個整形常量,如果要將其按照指針方式來使用,必須對其進行強轉(void *)0。

在C++中,增加了一個關鍵字 nullptr 表示一個空指針。

注意:

1. 在使用nullptr表示指針空值時,不需要包含頭文件,因為nullptr是C++11作為新關鍵字引入 的。

2. 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所占的字節(jié)數(shù)相同。?

3. 為了提高代碼的健壯性,在后續(xù)表示指針空值時建議最好使用nullptr。?

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

分享文章:[C++]打開新世界的大門之C++入門-創(chuàng)新互聯(lián)
分享路徑:http://www.rwnh.cn/article46/copihg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、網(wǎng)站設計公司、App設計、動態(tài)網(wǎng)站網(wǎng)站建設、品牌網(wǎng)站設計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

阿城市| 台山市| 西吉县| 焦作市| 化州市| 乐至县| 兴义市| 固原市| 柘城县| 马鞍山市| 库伦旗| 定西市| 旺苍县| 濮阳县| 洛阳市| 阿勒泰市| 丽水市| 偏关县| 鹤壁市| 湾仔区| 舒城县| 苗栗县| 津南区| 雅安市| 广汉市| 蕉岭县| 美姑县| 四子王旗| 泸水县| 青浦区| 兴城市| 奉节县| 福安市| 阿瓦提县| 嘉鱼县| 福鼎市| 九台市| 尼勒克县| 临沧市| 岢岚县| SHOW|