【C++入門】C++基礎

目錄

1. 命名空間

1.1 命名空間的創建和使用

2. 輸入輸出

2.1 輸出

2.2 輸入

3. 缺省參數

3.1 全缺省

3.2 半缺省

4.函數重載

4.1 為什么C++支持重載而C語言不支持?

4.1.2 編譯的四個過程

4.2 extern是什么

5.引用

5.1 引用的特性

5.1.1 引用的“隱式類型轉換”

5.2 引用的使用場景


本欄目針對于C語言已經學習完畢的讀者,只會講C++特有的特性。

1. 命名空間

? ? ? ? 命名空間是C++為了防止全局變量、函數、類,因為作用域的不同導致的沖突,從而提出的解決方案,在一個命名空間內,變量、函數、類是相對獨立的,不會對其他命名空間造成影響。

1.1 命名空間的創建和使用

命名空間內部可以創建變量和函數以及類;

命名空間可以嵌套使用;

相同的命名空間后面會被編譯器合并;

#include<iostream>// 命名空間可以定義變量和函數
namespace N1
{int a = 0;void swap(){;}}// 命名空間的嵌套
namespace N2 
{namespace N3 {// ....}
}// 相同命名空間,編譯器會進行合并
namespace N2
{int b = 1;
}

如果要使用命名空間內的變量或者函數或者類,那么一共有三種方式進行調用。

①直接使用命名空間::變量來調用;

②將某一個變量直接進行展開,后續使用變量的時候就不需要再加上命名空間了;

③將一個命名空間完全展開,命名空間內的所有內容,直接可以使用。

// 命名空間可以定義變量和函數
namespace N1
{int a = 0;void swap(){;}}// 命名空間的嵌套
namespace N2
{namespace N3{// ....int c = 1;}
}// 相同命名空間,編譯器會進行合并
namespace N2
{int b = 1;
}int main()
{// 方式1printf("%d ", N1::a);// 方式2using N2::b; // 如果經常使用a,那么就直接展開aprintf("%d ", b);// 方式3// 全部展開N2內的所有內容using namespace N1;printf("%d ",a);swap();return 0;
}

? ? ? ? 想要使用C++,就必須使用std庫,我們可以直接使用:將標準庫全部展開,到那時還是有一個缺陷,就是后續項目中如果定義一個和std庫內容相同的函數或者變量,那么就會出現重復命名的問題。

using namespace std;

2. 輸入輸出

2.1 輸出

? ? ? ? 利用上面的命名空間的知識,我們可以順便介紹一下c++的輸入輸出。首先需要包含c++的輸入輸出庫,后續才能使用相關的函數。

#include<iostream>

? ? ? ? 輸出流:cout這是在標準庫中的一個函數,也可以叫做標準輸出流利用上面所學的知識,我們可以有三種方式來完成hello world的輸出。

方式一:

? ? ? ? 在平時練習中,我們可以直接將標準庫展開,然后直接使用cout,將想要輸出的內容直接輸出到輸出流中,這里的endl,是換行的意思,我們可以使用c語言的\n來替代這個功能。

#include<iostream>
// 直接將std全部展開
using namespace std;
int main()
{cout << " hello world " << endl;cout << " hello world \n "; 
}

????????這樣做就會產生一個缺陷,如果你定義的變量中含有和std庫中相同的變量名稱,這樣就會命名混淆從而導致報錯。

方式二

? ? ? ? 在平時的項目中,為了避免命名沖突,我們直接使用std::cout的方式進行輸出,雖然一定程度避免了命名沖突,但是書寫起來比較麻煩。

#include<iostream>
int main()
{std::cout << " hello world " << std::endl;std::cout << " hello world \n ";
}

方式三

? ? ? ? 居中的辦法就是,只展開后續會用到的函數:

using std::cout;
using std::endl;
#include<iostream>
int main()
{cout << " hello world " << endl;cout << " hello world \n ";
}

注意:細心的讀者可能發現了,c++的輸出和c語言的輸出不太一樣,c++是直接根據輸出內容的類型直接判斷輸出的類型,而不是像c語言一樣,需要提前指定類型,再根據指定的類型輸出,這就是后面面向對象需要學習的函數的重載

2.2 輸入

? ? ? ? 這里用到了std庫的cin函數,這里和cout一樣,都是可以流式輸入,注意>>箭頭的方向

using std::cout;
using std::endl;
using std::cin;
#include<iostream>
int main()
{int a = 0;float b = 0.0;cin >> a >> b;cout << a << " " << b << endl;
}

3. 缺省參數

? ? ? ? 正常情況下,在函數有形參的時候需要這樣調用:

#include<iostream>
using namespace std;void Func(int a) 
{// cout << a << endl;
}int main()
{Func(10);
}

????????在c++中需要注意的是,在函數形參中提供默認參數,當沒有傳入實參的時候,就會使用默認參數。

#include<iostream>
using namespace std;void Func(int a = 0)
{// cout << a << endl;
}int main()
{Func(10);Func();
}

3.1 全缺省

? ? ? ? 顧名思義,全部形參都可以不寫,叫全缺省,也可以按照順序缺省后2個或者3個形參。

// 全缺省
void Func1(int a = 0, int b = 1, int c = 2)
{// cout << a << endl;cout << b << endl;cout << c << endl;
}int main()
{Func1();// 全缺省Func1(10); // 缺省b,c形參Func1(10,20);// 缺省c形參Func1(10,20,30);// 不缺省
}

3.2 半缺省

形參中部分參數沒有指定缺省值,例如下面代碼,a沒有指定缺省值,那么傳入實參的時候必須至少有一個參數是傳給a的,如果后面有其他參數,則繼續傳給b,c;

// 半缺省
void Func1(int a, int b = 1, int c = 2)
{// cout << a << endl;cout << b << endl;cout << c << endl;
}int main()
{Func1(10); // 缺省b,c形參,必須得傳入一個Func1(10,20);// 缺省c形參Func1(10,20,30);// 不缺省
}

這種半缺省必須是從右往左進行缺省

間隔缺省是錯誤的。

從左往右缺省是錯誤的。

傳參是從左往右依次傳參

4.函數重載

? ? ? c++允許在同一作用域中聲明幾個功能類似的同名函數,這些同名函數的形參列表(參數個數或類型或順序)必須不同,常用來處理功能類似,數據類型不同的問題。

int func() 
{
}// 參數個數不同
int func(int a)
{
}// 參數類型不同
int func(long a)
{
}// 參數順序不同
int func(long a ,int b)
{
}
int func(int b, long a)
{
}

對返回值完全沒有要求。

如何調用重載函數:

4.1 為什么C++支持重載而C語言不支持?

? ? ? ? 下面使用linux的環境來進行解釋

list.h

list.c

test.c

使用gcc命令編譯:

gcc -o listc list.c test.c

發現報錯

究其原因就是C語言的編譯器是不支持重載的:

我們使用g++命令進行編譯,發現通過編譯了;

g++ -o listcpp list.c test.c

這就涉及到編譯器編譯的四個過程:

4.1.2 編譯的四個過程

①預處理:宏替換,去掉注釋,展開頭文件,條件編譯;

②編譯:檢查語法問題,將源代碼轉換成匯編代碼;

③匯編:將匯編代碼轉換成二進制機器碼;

④鏈接:將兩個目標文件鏈接在一起,生成可執行文件。

例如在test中執行一個Func1函數,轉換成匯編指令就是:

call Func1 (0EE11DBH),括號內的是這個函數的地址,也可以說這個函數第一個變量的地址

????????回到上面的函數,同理我們只觀察匯編階段的匯編碼;在test.o文件中我們需要調用list_push_back這個函數,那么其實就是call list_push_back(函數地址),但是問題來了,此時在test函數中僅僅只包含了頭文件,也就是說僅僅對這個函數進行了聲明,那么這個函數實際的地址,這里是不知道的;每一個object文件中都在維護一個符號表,記錄每一個函數以及對應的地址,test.o這個文件的符號表僅僅只有main函數的地址。

? ? ? ? 反之在list.o文件中,我們可以看到這里是完成了兩個函數的實現,所以符號表里就存放著兩條數據,分別是這兩個函數的地址。

? ? ? ? 上面括號內的問號表示,在編譯的時候,這個函數只有聲明沒有定義。在鏈接的時候會其他目標文件的符號表中找到該函數的地址。

? ? ? ? 言歸正傳,在C語言中,函數名是必須是獨一無二的,函數的名字沒有修飾,也就是說,當去list.o的符號表去找地址的時候,突然發現ADD的地址有兩個,那么此時就不知道到底是哪一個的地址。

? ? ? ? 在C++中函數名是有修飾的,函數名由下面幾部分組成:

①前綴:_Z

②函數字符個數:例如add就是3

③函數名稱

④形參類型的首字母:add形參首字母就是ii、func形參首字母是idpi,p代表指針,pi代表int類型的指針。

????????回到上面的代碼,我們直接將生成的匯編代碼進行展示:下圖是cpp的匯編代碼,雖然函數名都是add,但是仍然可以根據命名修飾進行區分,從而找到相對應的函數地址。

? ? ? ? 那么c語言就不同了,我們可以發現下圖是c語言的匯編代碼,我們可以發現add完全沒有任何函數名修飾,這就意味著,如果有兩個相同的函數名,當在鏈接的時候,編譯器無法區分這兩個函數的地址,因為函數名都相同,那么在符號表中就無法進行區分。

4.2 extern是什么

? ? ? ? extern C就是按照C語言進行編譯,假如有一個C++編寫的程序編譯成了庫文件供別人調用,其他C++程序是可以完全調用的,但是如果C語言程序就無法調用,這是因為我們編譯的規則是不同的,如果這個程序是C++寫的,那么要求C語言能夠正確編譯,需要在函數聲明加上extern "C",如下圖綠框所示:

? ? ? ? 這里的具體意義是,按照C的形式去符號表內找這個函數的地址。

5.引用

? ? ? ? 引用就是給變量取了一個別名,不會額外開辟內存空間。

#include<iostream>
using namespace std;
int main()
{int a = 0;int& ra = a; // ra是a的引用,給a起了一個別名
}

5.1 引用的特性

①一個變量可以有多個引用,但是只會占用一個空間;

②引用聲明的時候必須初始化;

③第一次給引用初始化的時候,就永遠是這個變量的引用,后續無法改變。

#include<iostream>
int main()
{int a = 1;int& ra = a;int b = 2;ra = b; // 此時ra仍然是a的引用,a的值被改成了2}

此時ra的類型是int,而不是int&,因為ra只是a的別名,類型和a一樣。

如果代碼改成下面這樣的,就會出現問題:

#include<iostream>
int main()
{const int a = 1;int& ra = a; // 此時報錯}

const int a只是可讀的,int& ra是可讀可寫的,如果將前者直接轉換成后者,就會報錯。

那么反過來就對了,a可讀可寫,ra只可讀,類似于一個大海能填滿溪流,但是溪流不能填滿大海。

#include<iostream>
int main()
{int a = 1;const int& ra = a; // 此時ok}

5.1.1 引用的“隱式類型轉換”

? ? ? ? 首先看下面的代碼,將a賦值給double類型的引用,是不可以的,在前面加了一個const修飾就可以了,這是為什么呢?

#include<iostream>
int main()
{int a = 1;double& b= a; // 此時不行const double& c= a; // 此時ok}

? ? ? ? 當變量賦值的時候會產生一個臨時變量這個變量具有常性(只能讀不能改),那么事實上a賦值給這個臨時變量,臨時變量再賦值給double類型的引用,此時只讀賦值給可讀可寫,一定會有問題。

? ? ? ? 反之在double& 前加一個const修飾,這里的引用就會變成可讀的,那么可讀賦值給可讀就是合理的。

5.2 引用的使用場景

我們寫一個比較常見的交換函數,分別使用c語言和c++的特性,注意形參和實參的變化。

int& a其實就是取實參的引用,此時引用和實參指向一個地址,因此可以直接交換。

#include<iostream>
using namespace std;void c_swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}
void cpp_swap(int& r1, int& r2)
{int tmp = a;a = b;b = tmp;
}int main()
{int a = 10;int b = 20;c_swap(&a, &b);cpp_swap(a, b);
}

????????再舉一個例子,count1返回的是一個臨時變量,是只讀的,所以給r1的時候會報錯,此時r1需要加上const類型才能對應,(只讀-只讀),count2直接返回引用,所以類型能夠匹配,所以這是沒問題的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/97834.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/97834.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/97834.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何往mp4視頻添加封面圖和獲取封面圖?

前言&#xff1a;大家好&#xff0c;之前有給大家分享過mp4錄像的方案&#xff0c;今天給大家分享的內容是&#xff1a;如何在添加自定義的封面圖到mp4里面去&#xff0c;以及在進入回放mp4視頻列表的時候&#xff0c;怎么獲取mp4視頻里面的封面圖&#xff0c;當然這個獲取到的…

你的第一個Transformer模型:從零實現并訓練一個迷你ChatBot

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;注冊即送-H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;破除神秘感&#xff0c;擁抱核心思想 …

【20期】滬深指數《實時交易數據》免費獲取股票數據API:PythonJava等5種語言調用實例演示與接口API文檔說明

? 隨著量化投資在金融市場的快速發展&#xff0c;高質量數據源已成為量化研究的核心基礎設施。本文將系統介紹股票量化分析中的數據獲取解決方案&#xff0c;涵蓋實時行情、歷史數據及基本面信息等關鍵數據類型。 本文將重點演示這些接口在以下技術棧中的實現&#xff1a; P…

RabbitMQ如何保障消息的可靠性

文章目錄什么是消息可靠性&#xff1f;RabbitMQ消息可靠性的三個維度1. 生產者到Exchange的可靠性2. Exchange到Queue的可靠性3. Queue到消費者的可靠性核心機制詳解Publisher Confirm機制消息持久化Mandatory參數消費者確認機制&#xff08;ACK&#xff09;最佳實踐建議1. 合理…

二十、DevOps落地:Jenkins基礎入門(一)

二十、DevOps落地&#xff1a;Jenkins基礎入門&#xff08;一&#xff09; 文章目錄二十、DevOps落地&#xff1a;Jenkins基礎入門&#xff08;一&#xff09;1、DevOps初識1.1 什么是DevOps1.2 DevOps相關工具鏈1.3 什么是CICD&#xff1f;1.4 持續集成CI介紹1.5 持續交付和持…

簡單易實現的數據校驗方法Checksum

簡單易實現的數據校驗方法Checksum 在數據傳輸中&#xff0c;Checksum&#xff08;校驗和&#xff09; 扮演著 “數據完整性哨兵” 的角色。它的主要作用是 快速檢測數據在傳輸過程中是否發生了錯誤 。 下面我將詳細解釋它的作用、工作原理、優缺點以及典型應用。 核心作用&…

再次深入學習深度學習|花書筆記1

我已經兩年沒有碰過深度學習了&#xff0c;寫此文記錄學習過程&#xff0c;加深理解。 深度學習再次深入學習深度學習|花書筆記1信息論第四節 數值計算中的問題上溢出 和 下溢出病態條件優化法再次深入學習深度學習|花書筆記1 這本書說的太繁瑣了&#xff0c;如果是想要基于這…

DeerFlow實踐:華為LTC流程的評審智能體設計

目錄 一、機制設計核心邏輯 二、4 個評審點智能體機制詳解 &#xff08;一&#xff09;立項決策&#xff08;ATI&#xff09;智能體機制 1. 知識調用與匹配 2. 評審校驗流程 3. 異常處理 &#xff08;二&#xff09;投標決策&#xff08;ATB&#xff09;智能體機制 1. …

C++與Lua交互:從原理到實踐指南

核心原理&#xff1a;Lua虛擬棧機制 C與Lua能夠高效交互的核心在于Lua虛擬棧的設計&#xff0c;這是一個精巧的中立通信區&#xff0c;解決了兩種語言間的本質差異&#xff1a;特性對比CLua語言類型靜態編譯型動態解釋型數據管理明確內存布局虛擬機統一管理類型系統編譯時確定運…

CSS 編碼規范

CSS 編碼規范1 CSS1.1 編碼規范1.1.1 【強制】所有聲明必須以分號結尾1.1.2 【推薦】使用 2 個空格縮進1.1.3 【推薦】選擇器與 { 之間保留一個空格1.1.4 【推薦】屬性值規范1.1.5 【推薦】組合器規范1.1.6 【推薦】逗號分隔規范1.1.7 【推薦】注釋規范1.1.8 【推薦】右大括號規…

ORA-12514:TNS:監聽程序當前無法識別連接描述符中請求的服務

已經不止一次自己本機電腦安裝的Oracle使用plsqldev軟件登入提示這個了.一般前一天還好好的&#xff0c;今天就不行了.好好總結一下吧&#xff0c;也共大家一起借鑒.主要原因還是數據的歸檔日志因為內部內存已經耗盡&#xff0c;不能在進行歸檔導致數據庫啟動異常&#xff0c;沒…

Spring框架的JDBC模板技術和事務管理

SpringJDBCJDBC模板技術概述JDBC的模板類的使用Spring框架的事務管理配置文件方式半注解的方式純注解的方式JDBC模板技術概述 什么是 JDBC 模板技術&#xff1f; JDBC 模板技術是 Spring 框架為簡化持久層&#xff08;數據庫操作&#xff09;編程而提供的一種封裝機制&#xf…

將文件部署到受管主機

目錄 1.ansible.builtin中用于創建、更新或刪除多行文本塊的模塊是什么 2.copy模塊的作用 3.fetch模塊的作用 4.file模塊的作用 5.lineinfile模塊的作用 6.stat模塊的作用 7.要確保受管主機上存在文件&#xff0c;類似touch命令功能&#xff0c;還能設置權限等的模塊及操作是怎…

Dell PowerEdge R620 服務器內存和硬盤罷工了

文章目錄前言調查原因查找解決方案硬盤問題內存問題總結前言 月黑風高夜&#xff0c;服務宕機時。做服務端技術的&#xff0c;誰還沒半夜遇到個服務掛掉的情況&#xff0c;而像我這種半兼職網管的工作&#xff0c;遇到機器問題的概率也就更大了&#xff0c;本來周五晚上寫完總…

2025:SourceTree 啟用/禁用Mercurial 或 Git,像素級細節

最近使用Git管理工具的時候&#xff0c;發現還是SourceTree好用些&#xff0c;但是使用SourceTree帶來一個問題&#xff1a;就是每次在重新打開SourceTree的時候&#xff0c;都會重新下載Mercurial.zip文件&#xff0c;查了一下&#xff0c;一般情況下我們是不需要使用Mercuria…

安卓 Google Maps 的使用和開發步驟

文章目錄1. main2. Android 谷歌地圖3. 源碼Reference1. main 在國內選擇的SDK可以是高德、百度、騰訊、xxxx等&#xff0c;但在國外&#xff0c;你首選是谷歌&#xff0c;因此要進行Google地圖的開發你首先要解決下面三個問題 VPN Google賬號 信用卡American Express&#x…

Linux -- 應用層協議Http

1.HTTP背景知識 HTTP協議&#xff1a;HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;的本質是運行在 TCP/IP 協議族之上的 “應用層協議”&#xff0c;核心作用是定義客戶端&#xff08;如瀏覽器、APP&#xff09;與服務器之間的 “數據…

R 語言本身并不直接支持 Python 中 f“{series_matrix}.txt“ 這樣的字符串字面量格式化(f-string)語法 glue函數

R 語言本身并不直接支持 Python 中 f"{series_matrix}.txt" 這樣的字符串字面量格式化&#xff08;f-string&#xff09;語法。 在 R 中&#xff0c;要實現字符串拼接或格式化&#xff0c;你需要使用其他方法。下表對比了 Python f-string 和 R 中常見對應方法的主要…

【AI智能體】亮數據MCP Server × Dify:AI智能體獲取實時影音數據就是這么簡單

文章目錄一、引言&#xff1a;AI 應用與實時影音數據的融合價值1、傳統采集方式的痛點2、MCP Server 的創新價值二、亮數據 MCP Server 概覽1、什么是 MCP Server&#xff1f;2、支持的影音平臺和API接口3、產品特色亮點三、業務場景示例設計1、選定場景&#xff1a;競品分析與…

從《Attention Is All You Need》深入理解Transformer

2017年的《Attention Is All You Need》論文提出的Transformer架構&#xff0c;不僅徹底改變了自然語言處理的格局&#xff0c;更為現代人工智能的發展奠定了堅實基礎。本文將帶你深入解析這一劃時代模型的核心思想、技術細節及其深遠影響。&#x1f504; 一、背景與動機&#…