C 基礎知識整理

2021-09-25 11:28:29 字數 4132 閱讀 8719

在c++98中,有63個關鍵字。(不能遺漏標準名稱,任何不帶標準名稱來說關鍵字個數都是耍流氓)

1.定義命名空間,需要用到namespace關鍵字,後面跟命名空間的名字,然後接{},{}中即為命名空間的成員。

2.命名空間的使用

namespace n

}

int main()

using n::b;

int main()

using namespace n;

int main()

1.包含標頭檔案以及std標準命名空間。

2.cout和cin完成標準輸入與標準輸出

1.預設引數概念

預設引數是宣告或定義函式是為函式的引數指定乙個預設值,在呼叫該函式時,如果沒有指定實參則採用該預設值,否則使用指定的實參。

2.預設引數分類

void testfunc(int a=10,int b=10,int c=30)

double add(double left,double right)

long add(long left,long right)

注意:如果函式僅僅是返回值型別不同,是不能構成過載函式的,因為編譯器在根據型別引數型別判斷應該使用那個函式時不能夠知道返回值型別,所以不能夠過載。

2.名字修飾

c/c++程式執行時,需要經歷:預處理,編譯,彙編,連線。而名字修飾是一種在編譯過程中,將函式、變數的名稱重新改編的機制,簡單來說就是編譯器為了區分各個函式,將函式通過某種演算法,重新修飾為全域性唯一名稱。

**c語言的名字修飾:**僅在函式名前加上下劃線,如對於add函式,會改編成_add

**c++的名字修飾:**不同的編譯器在底層的實現方式各有差異

int add(int left,int right);

double add(double left,double right);

int main()

如何解析重新修飾的名字:

?add@@yahhh@z:修飾後的名字由?開頭,後面跟函式名,並以@表示函式名的結束,下乙個@表示類名或命名空間的結束,a後面跟的是引數型別,在c++中h表示int,n表示double,最後以@z表示整個名字的結束。

3.extern c

考慮到c++是完全相容c語言的,也就是說,c語言的**在c++環境是完全可以執行的,如果在乙個c++工程下,需要新增乙個c語言實現的庫,add函式就不會被編譯成_add,導致找不到編譯後的add函式,因此,extern c的作用就是按照c語言的風格對**進行編譯。

所謂引用不是重新定義了乙個變數,而是給已經存在的變數取了乙個別名,編譯器不會因為引用變數而重新開闢空間,它和它引用的物件共用一塊記憶體位址。

使用方法:型別 &引用變數名=引用實體;

[外鏈轉存失敗(img-gyk3lepz-1563779879116)(c:\users\deorro\desktop\111.png)]

注意:引用型別必須和引用實體是同一種型別

2.引用特性

​ 引用在定義時必須初始化

​ 同乙個變數可以有多個引用

​ 引用一旦引用乙個實體,再也不能引用其他實體

3.常引用

void constref()

4.使用場景

void swap(int& left,int& right)

1.需要通過形參來改變外部的實參:t&

2.不需要通過形參來改變外部的實參:const t&

int& testrefreturn(int &a)

int &add(int a,int b)

int main()

[外鏈轉存失敗(img-rwi3yint-1563779879125)(c:\users\deorro\desktop\222.png)]

檢視**的反彙編我們可以看到引用的底層實現**與指標相同。

​ t&<>t* const constt& <> const t* const

**概念上:**引用只是其實體的別名,與實體公用一塊記憶體空間、

引用與指標的不同點:

1.引用在定義時必須初始化,指標則沒有要求。

2.引用在初始化引用乙個實體後,就不能再引用其他實體,而指標可以在任何時候指向同型別實體

3.引用沒有null,指標有null、

4.在sizeof中的含義不同:引用的結果為引用型別的大小,但指標的大小則是固定的(32位平台佔4個位元組,64位的平台佔8個位元組)

5.引用自加1則是引用的實體加一,指標自加則是向後偏移乙個型別的大小

6.有多級指標但是沒有多級引用

7.訪問實體的方式不同,指標需要進行解引用,但是引用編譯器自己就可以處理

8.引用比指標用起來相對安全

以inline函式修飾的函式成為內聯函式,在編譯器編譯期間,會在呼叫內聯函式的地方展開,沒有函式壓棧的開銷,內聯函式可以提公升程式執行的效率

特性:1.inline是一種以空間換時間的演算法,省去了呼叫函式的開銷,所以**很長或者有迴圈/遞迴的函式不適合作為內聯函式。

2.inline對於編譯器來說只是乙個建議嗎,編譯器會自動進行優化,如果定義為inline的函式體內有迴圈或遞迴,編譯器優化時會忽略掉inline

**優點:**增強了**的復用性,提高效能

**缺點:**不方便除錯巨集;導致**的可讀性差,可維護性差,容易誤用,沒有型別安全的檢查。

為了解決巨集的一些缺點,可以將常量定義換成const,加上const變數修飾後,即使在編譯期間改變了變數的值,變數的值也不會被修改,更加安全易用。

在早期的c/c++中,auto修飾的變數,是具有自動儲存器的區域性變數,在使用完成後,編譯器會自動釋放這個變數的空間,但實際上對於乙個區域性變數來說,當函式呼叫完畢後,對應空間本來就會被釋放,因此沒人使用。

在c++11中,auto有了全新的含義:auto不再是儲存型別指示符,而是作為乙個新的型別指示符來指示編譯器,auto宣告的變數必須由編譯器在編譯時期推導而得。

注意:

由auto宣告的變數必須初始化,在編譯階段編譯器需要根據初始化表示式來推導auto的實際型別,因此auto並非是一種型別的宣告,而是型別宣告時的佔位符,編譯器會在編譯期間將auto替換為變數的實際型別

1.auto與指標、引用結合使用,用auto來宣告指標型別時,用auto和auto*沒有區別,但auto宣告引用型別時則必須加上auto&

2.在**的同一行宣告多個變數時,這些變數必須是相同的型別,否則編譯器將會報錯,因為編譯器實際只對第乙個型別進行了推導,然後用推導出的型別來定義其他的變數

1.auto不能作為函式的引數

2.auto不能用來直接宣告陣列

3.為了防止與c++98中的auto混淆,c++11只保留了auto作為型別指示符的用法

4.auto最常見的優勢用法就是與c++11提供的範圍for迴圈,與lambda表示式等配合使用

5.auto不能定義類的非靜態成員變數

6.例項化模板時不能使用auto作為模板引數

for迴圈後的括號由「:」分為兩個部分,第一部分是用來迭代的變數,第二部分表示的是迭代的範圍

int array = ;

for(int i=0;i1.c++98中的指標空值

如果乙個指標沒有合法的指向,通常使用null進行初始化,null是乙個巨集,null可以被定義為字面常量0,或無型別指標(void *)常量。在c++98中,字面常量0既可以是整形資料,也可以是無型別指標(void *)常量,但是編譯器預設情況下看做整形常量,如果用作指標會被強轉為(void *)

typedef declttype(nullptr) nullptr_t;

注意:

1.在使用nullptr表示空指標時,不需要包含標頭檔案,因為nullptr是c++作為新關鍵字引入的

2.在c++中,sizeof(nullptr)與sizeof(void *)所佔的字元數相同

3.為了提高**的魯棒性,在後續表示空指標最好用nullptr

C 基礎知識整理 基礎知識(2) 類

類,是物件導向語言的基礎。類的三大特性 封裝 繼承 多型。最基本的特性就是封裝性。程式設計師用程式描述世界,將世界的所有事物都看成物件,怎麼描述這個物件?那就是類了。也就是用類來封裝物件。用書上的話說,類是具有相同屬性和行為的物件的抽象。寶馬汽車 別克汽車 五菱之光汽車.基本具有相同的屬性和行為,所...

C 基礎知識整理 基礎知識(2) 類

類,是物件導向語言的基礎。類的三大特性 封裝 繼承 多型。最基本的特性就是封裝性。程式設計師用程式描述世界,將世界的所有事物都看成物件,怎麼描述這個物件?那就是類了。也就是用類來封裝物件。用書上的話說,類是具有相同屬性和行為的物件的抽象。寶馬汽車 別克汽車 五菱之光汽車.基本具有相同的屬性和行為,所...

c 基礎知識整理(一)

一 標頭檔案 1 define保護 為防止標頭檔案被多重包含,檔案的格式應該為 h 這樣寫是為了保證其唯一性 2 內聯函式 在編譯的時候,編譯器會將它自動展開 所以合理的使用內聯函式會提高效率 內聯函式一般都是短小的,但要除for,while這類的。有些函式即使不加了inline 也不一定會變成內聯...