廣告公司做網(wǎng)站寧波seo網(wǎng)絡(luò)推廣代理公司
🌟🌟作者主頁:ephemerals__
🌟🌟所屬專欄:C++
目錄
前言
一、手搓一個Hello World
二、命名空間namespace
1.命名空間的定義
2.命名空間的使用
3.命名空間補(bǔ)充知識
三、c++中的輸入和輸出
四、缺省參數(shù)
五、函數(shù)重載
六、內(nèi)聯(lián)函數(shù)
七、空指針
總結(jié)
前言
? ? ? ? c++是在c語言的基礎(chǔ)上,增加了面向?qū)ο缶幊?、引用、函?shù)重載、模板庫STL等新特性,使得c++成為一門功能強(qiáng)大、靈活多變的語言。c++在語法上兼容大部分c語言,因而學(xué)習(xí)了c語言之后,會對c++學(xué)習(xí)有一定的幫助。相比java,c++語法的學(xué)習(xí)難度較高,但是它難學(xué)易用,也有利于我們理解底層,是一門十分值得深入學(xué)習(xí)的語言。
? ? ? ? 接下來我們會重點(diǎn)介紹一些c++的前置基礎(chǔ)知識,便于我們快速入門c++語法。
一、手搓一個Hello World
? ? ? ? 那么就讓我們從HelloWorld開始,進(jìn)入c++的知識海洋。代碼如下:
//c語言版本
#include <stdio.h>int main()
{printf("Hello World\n");return 0;
}
//c++版本
#include <iostream>
using namespace std;int main()
{cout << "Hello World" << endl;return 0;
}
由于c++兼容c語言語法,所以這兩段代碼在c++編譯器中都是可以完成運(yùn)行的。
運(yùn)行結(jié)果:
可以看到,c++的基本語法和c語言還是有較大區(qū)別的??床欢疀]關(guān)系,我們將會逐一講解這里的細(xì)節(jié)。
二、命名空間namespace
? ? ? ? 在c++當(dāng)中,由于變量、函數(shù)、類等數(shù)量龐大,難免會出現(xiàn)重名的情況,它們都存在與全局域當(dāng)中,使用時就會出現(xiàn)沖突。而命名空間的出現(xiàn)就解決了這個問題。命名空間會對標(biāo)識符的名稱進(jìn)行本地化,本質(zhì)上是使它們位于不同的作用域中,避免了沖突的情況。
? ? ? ? 接下來我們嘗試定義命名空間。
1.命名空間的定義
????????舉個例子:
namespace xxx
{int x = 5;int func(int a){return a * a;}struct A{int m;char n;};
}
1.定義命名空間使用的關(guān)鍵字是namespace,后面加上該空間的名字,在之后的 { } 中定義變量、函數(shù)或類等等。
2.命名空間只能定義在全局,不能定義在函數(shù)體或者類中。
3.命名空間可以嵌套定義。
4.一個項(xiàng)目的多文件中定義的同名命名空間,編譯器會認(rèn)為是同一個命名空間,不會發(fā)生沖突。
2.命名空間的使用
? ? ? ? 接下來,我們嘗試訪問命名空間中的成員。
namespace xxx
{int x = 5;int func(int a){return a * a;}struct A{int m;char n;};
}int main()
{int x = 10;printf("%d\n", x + xxx::x);//訪問命名空間的成員時,在空間名之后加上兩個冒號,稱之為域限定操作符printf("%d\n", xxx::func(x));return 0;
}
運(yùn)行結(jié)果:
? ? ? ? 使用using關(guān)鍵字還可以將命名空間或者其成員展開。舉例:
namespace a
{int m = 5;int n = 3;
}namespace b
{int p = 10;int q = 20;
}using namespace a;//展開整個命名空間
using b::p;//展開命名空間的某成員int main()
{printf("m=%d,n=%d\n", m, n);printf("p=%d,q=%d\n", p, b::q);return 0;
}
?運(yùn)行結(jié)果:
可以看到,展開命名空間或者成員之后,在訪問時就不需要再加上“::”了。這里需要注意:在大型項(xiàng)目當(dāng)中盡量不要展開命名空間,很容易發(fā)生沖突的情況,日常練習(xí)時為了方便可以使用。
? ? ? ? 我們之前的HelloWorld代碼中,使用了語句“using namespace std;”展開了命名空間std。
3.命名空間補(bǔ)充知識
1.c++標(biāo)準(zhǔn)庫都放在叫做“std”的命名空間當(dāng)中。
2.namespace本質(zhì)上就是定義了一個域,叫做命名空間域。
3.c++中有四種域:函數(shù)局部域、全局域、命名空間域、類域;不同的域當(dāng)中的相同變量或者函數(shù)名形成域隔離,不會沖突;函數(shù)局部域和全局域會影響變量的聲明周期,命名空間域和類域不會影響變量聲明周期。
三、c++中的輸入和輸出
? ? ? ? 接下來,我們按照剛才寫的HelloWorld程序介紹c++的輸入輸出。
#include <iostream>
using namespace std;int main()
{cout << "Hello World" << endl;return 0;
}
1.可以看到,我們引入了頭文件"iostream",它是c++的標(biāo)準(zhǔn)輸入、輸出流庫,定義了標(biāo)準(zhǔn)的輸入輸出對象。
2.cout,也就是std::cout,是類ostream的對象,它主要面向窄字符的標(biāo)準(zhǔn)輸出流,與c語言中printf函數(shù)作用相似,與printf不同的是,它可以自動識別要輸出的變量的類型,在使用時不需要特別指定輸出類型。
3.endl:是一個函數(shù),它用于輸出一個換行符,與傳統(tǒng)的輸出“\n”不同的是,它可以在各種操作系統(tǒng)下正常使用,而“\n”在不同的操作系統(tǒng)中含義可能不同。
4.我們看到,“Hello World”字符串被兩個“<<”符號圍了起來,這個符號叫做“流插入操作符”,它可以理解為將該操作符之后的內(nèi)容插入到"cout"中便于輸出。當(dāng)我們需要輸出多個變量時,可以將這些變量全部用“<<”分隔開。
對于輸入操作,c++提供了"std::cin",它是類istream的對象,主要面向窄字符的標(biāo)準(zhǔn)輸入流。在使用它時,我們需要加上“>>”(流提取操作符),可以理解為將輸入的值提取到變量當(dāng)中。
接下來我們寫一段代碼測試c++中的輸入輸出:
#include <iostream>
using namespace std;int main()
{int a = 3;float b = 5.5f;char c = 'w';cout << a << ' ' << b << ' ' << c << endl;//不同的內(nèi)容之間必須用<<分割int d = 0;cin >> d;cout << d;return 0;
}
運(yùn)行結(jié)果:
四、缺省參數(shù)
????????缺省參數(shù)(默認(rèn)參數(shù)),指的是在聲明或者定義函數(shù)時,可以給函數(shù)的參數(shù)設(shè)置一個默認(rèn)值。當(dāng)調(diào)用該函數(shù)時,如果沒有傳對應(yīng)參數(shù),則使用該默認(rèn)值;否則使用傳入的參數(shù)。
1.缺省參數(shù)可分為全缺省參數(shù)和半缺省參數(shù),全缺省參數(shù)指的就是函數(shù)的參數(shù)全部設(shè)置了默認(rèn)值,半缺省參數(shù)指的就是部分參數(shù)設(shè)置了默認(rèn)值。C++標(biāo)準(zhǔn)規(guī)定:半缺省參數(shù)默認(rèn)值的設(shè)置必須按照函數(shù)參數(shù)從右往左進(jìn)行,不能跳躍。代碼示例:
#include <iostream>
using namespace std;void func1(int a = 3)//全缺省參數(shù)
{cout << a << endl;
}void func2(int a, int b = 0)//半缺省參數(shù)
{cout << a + b << endl;
}int main()
{func1();func1(1);func2(1);func2(1, 2);return 0;
}
運(yùn)行結(jié)果:
以下情況運(yùn)行就會報錯:
#include <iostream>
using namespace std;void func3(int a = 10, int b)//缺省參數(shù)只能從右往左設(shè)置
{cout << a + b << endl;
}int main()
{func3(3, 5);return 0;
}
2.調(diào)用帶缺省參數(shù)的函數(shù)時,實(shí)參的傳入必須從左到右進(jìn)行,不能跳躍。代碼示例:
#include <iostream>
using namespace std;void func(int a, int b = 3, int c = 5)
{cout << a + b + c << endl;
}int main()
{func(1, , 1);//報錯return 0;
}
3.當(dāng)函數(shù)的聲明和定義分離時,缺省參數(shù)不能同時出現(xiàn)在聲明和定義當(dāng)中,必須在聲明中設(shè)置缺省參數(shù)。
五、函數(shù)重載
? ? ? ? c++中,當(dāng)同一作用域中出現(xiàn)同名函數(shù)時,如果這些函數(shù)的形參不同(參數(shù)個數(shù)不同或者參數(shù)類型有不同),就會出現(xiàn)函數(shù)重載,這些函數(shù)之間不會發(fā)生沖突情況。相比c語言,c++中函數(shù)重載的出現(xiàn),體現(xiàn)了多態(tài)性,使得函數(shù)使用更加靈活。
舉個例子:
#include <iostream>
using namespace std;int add(int a, int b)//兩函數(shù)的參數(shù)類型不同,出現(xiàn)重載
{return a + b;
}double add(double a, double b)//兩函數(shù)的參數(shù)類型不同,出現(xiàn)重載
{return a + b;
}int main()
{cout << add(1, 2) << endl;cout << add(3.3, 5.5) << endl;return 0;
}
運(yùn)行結(jié)果:
可以看到,編譯器會根據(jù)我們調(diào)用函數(shù)時傳入的參數(shù)類型,來決定調(diào)用哪一個重載函數(shù)。
下面來看一個特殊情況:
void func()
{cout << 1 << endl;
}void func(int a = 10)
{cout << 2 << endl;
}int main()
{func();//報錯
}
兩個func函數(shù)構(gòu)成函數(shù)重載,但是當(dāng)調(diào)用函數(shù)時不傳參,就會出現(xiàn)歧義,編譯器無法確定我們調(diào)用的是哪一個函數(shù)。
六、內(nèi)聯(lián)函數(shù)
? ? ? ? 相比c語言,c++引入了“內(nèi)聯(lián)函數(shù)”這個概念,它對程序的效率提升有一定幫助。接下來我們深入了解以下內(nèi)聯(lián)函數(shù)。
1.用關(guān)鍵字“inline”修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),在程序編譯的過程中,編譯器會在調(diào)用該函數(shù)的地方將此函數(shù)展開,這樣在程序運(yùn)行時就不會創(chuàng)建函數(shù)棧幀,提高了效率。
2.由于函數(shù)的體量有別,所以并不是所有用“inline”修飾的函數(shù)都會在編譯時展開,使用“inline”修飾只是程序員的建議,最終是否展開由編譯器決定。一般代碼量較短的函數(shù)會被展開,而代碼量較大或者遞歸函數(shù)就不會被展開,展開之后反而會增加程序冗余。
3.當(dāng)一個函數(shù)被我們使用“inline”修飾時,如果該函數(shù)的聲明和定義是分離的,那么將會導(dǎo)致編譯錯誤。所以使用“inline”修飾函數(shù)時要同時進(jìn)行聲明和定義。
七、空指針
? ? ? ? 在c語言中,空指針用“NULL”來表示,它是一個宏常量,是被強(qiáng)制類型轉(zhuǎn)換為void型指針的0;而c++中的“NULL”直接替換為0。由于c++中存在函數(shù)重載,當(dāng)我們將NULL作為參數(shù)傳遞時,可能會出現(xiàn)以下情況:
#include <iostream>
using namespace std;void func(int* ptr)
{cout << 1 << endl;
}void func(int x)
{cout << 2 << endl;
}int main()
{func(NULL);return 0;
}
運(yùn)行結(jié)果:
我們傳入空指針,本意是要調(diào)用第一個函數(shù),但是結(jié)果卻調(diào)用了第二個函數(shù)。如果我們傳入被強(qiáng)制轉(zhuǎn)換為void*的0呢?
可以看到,程序出現(xiàn)了報錯,我們?nèi)匀粺o法調(diào)用第一個函數(shù)。針對這種問題,c++定義了一個關(guān)鍵字來表示空指針:nullptr。它是一種特殊類型的字面量,可以轉(zhuǎn)換為任意類型的指針。由于它只能被轉(zhuǎn)換為指針類型,所以就避免了以上問題。我們來傳入nullptr試試:
#include <iostream>
using namespace std;void func(int* ptr)
{cout << 1 << endl;
}void func(int x)
{cout << 2 << endl;
}int main()
{func(nullptr);return 0;
}
運(yùn)行結(jié)果:
可以看到,程序成功地調(diào)用了第一個函數(shù)。
總結(jié)
? ? ? ? 今天我們學(xué)習(xí)了關(guān)于c++的一些前置知識,這些新的概念和定義有效地彌補(bǔ)了c語言的一些不足。之后我們的c++程序都會以這些知識為基礎(chǔ)。如果你覺得博主講的還不錯,就請留下一個小小的贊在走哦,感謝大家的支持???