C++起始(內聯函數,宏的優缺點,const關鍵字,auto關鍵字(C++11)基于范圍的for循環(C++11). 指針空值nullptr(C++11))

內聯函數

概念
以inline修飾的函數叫做內聯函數,編譯時C++編譯器會在調用內聯函數的地方展開,沒有函數壓棧的開銷, 內聯函數提升程序運行的效率

  1. 函數前增加inline關鍵字將其改成內聯函數,在編譯期間編譯器會用函數體替換函數的調用。

在這里插入圖片描述
在這里插入圖片描述

反匯編中依舊有call指令語句
為什么?
因為代碼在Debug模式下,把它調回release模式
所以需要在release模式下,查看編譯器生成的匯編代碼中是否存在call Add
在這里插入圖片描述
在這里插入圖片描述
因為代碼在實際中沒有什么作用,所以編譯器把代碼忽略掉了。
并沒有出現call語句。

  1. 在debug模式下,需要對編譯器進行設置,否則不會展開(因為debug模式下,編譯器默認不會對代碼進行 優化,以下給出vs2013的設置方式)
    在這里插入圖片描述
    然后再轉到反匯編就可以看到了。

特性
4. inline是一種以空間換時間的做法,省去調用函數額開銷。所以代碼很長或者有循環/遞歸的函數不適宜使 用作為內聯函數。
5. inline對于編譯器而言只是一個建議,編譯器會自動優化,如果定義為inline的函數體內有循環/遞歸等 等,編譯器優化時會忽略掉內聯。
6. inline不建議聲明和定義分離,分離會導致鏈接錯誤。因為inline被展開,就沒有函數地址了,鏈接就會找 不到。

宏的優缺點

宏:可以定義

		常量函數

優點:

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

缺點:

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

C++有哪些技術替代宏?

  1. 常量定義 換用const
  2. 函數定義 換用內聯函數

const關鍵字

auto簡介
在c語言中const修飾的是內容不能修改的變量
c++中const關鍵字修飾是把一個變量變量變成一個常量。而且此常量具有宏的屬性,就是替換。在代碼編譯期間進行替換。

下列程序中*pa和a的值各是多少?

const	int	a=10;
int	*pa	=	(	int *	)&a;
*pa=100;
cout<<a<<endl;
cout<<*pa<<endl;

在這里插入圖片描述

auto關鍵字(C++11)

auto簡介

在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動存儲器的局部變量(具有自動銷毀功能 ),但遺憾的是一直沒有人 去使用它,大家可思考下為什么?
因為函數體的局部變量本身就在函數返回時自己銷毀,不需要多此一舉。

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

int TestAuto(){return 10; }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;return 0;
}
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190513180901378.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdXl1Y2hlbjI4MjgyOA==,size_16,color_FFFFFF,t_70)

定義了一個a的變量并賦了一個10.結構默認為int類型。
在這里插入圖片描述
而定義一個變量b,并賦值3.14,結果類型為double。

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

auto的使用細則

auto與指針和引用結合起來使用
用auto聲明指針類型時,用auto和auto*沒有任何區別,但用auto聲明引用類型時則必須加&

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

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

auto不能推導的場景

  1. auto不能作為函數的參數
    // 此處代碼編譯失敗,auto不能作為形參類型,因為編譯器無法對a的實際類型進行推導

    void TestAuto(auto a)
    {}

  2. auto不能直接用來聲明數組

    void TestAuto()
    {
    int a[] = {1,2,3};
    auto b[] = {4,5,6};
    }

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

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

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

  6. 實例化模板時不能使用auto作為模板參數

基于范圍的for循環(C++11)

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

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;} 

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

int array[] = { 1, 2, 3, 4, 5 }; 
for(auto& e : array)    e *= 2;for(auto e : array)     cout << e << " ";

在這里插入圖片描述

在這里插入圖片描述
而用auto e 則不會改變數組中的內容,因為e只是拷貝,而要想改變,必須用引用。
在這里插入圖片描述

范圍for的使用條件
1. for循環迭代的范圍必須是確定的
對于數組而言,就是數組中第一個元素和后一個元素的范圍;對于類而言,應該提供begin和end的方法, begin和end就是 for循環迭代的范圍。

在這里插入圖片描述
2. 迭代的對象要實現++和==的操作。

. 指針空值nullptr(C++11)


平常我們一般把沒有明確指向的指針指空。
NULL可能被定義為字面常量0,或者被定義為無類型指針(void)的常量。*
在這里插入圖片描述
nullptr 與 nullptr_t
:為了避免混淆,C++11提供了nullptr, 即:nullptr代表一個指針空值常量。nullptr是有類型的,其類型為nullptr_t,僅僅可以被隱式轉化為指針類 型,nullptr_t被定義在頭文件中:

**typedef   decltype(nullptr)   nullptr_t;** 

注意:

  1. 在使用nullptr表示指針空值時,不需要包含頭文件,因為nullptr是C++11作為新關鍵字引入的。
  2. 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所占的字節數相同。
  3. 為了提高代碼的健壯性,在后續表示指針空值時建議好使用nullptr。

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

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

相關文章

linux內核中的匯編語言

在Linux內核代碼中&#xff0c;有一部分是用匯編語言編寫的。其大部分是關于中斷與異常處理的底層程序&#xff0c;還有就是與初始化有關的程序&#xff0c;以及一些核心代碼中調用的公用子程序。 用匯編語言編寫內核代碼中的部分代碼&#xff0c;大體上是出于如下幾個方面考慮…

數據結構課程設計---c語言實現通訊錄(動態擴容+文件存儲)

1 題目一 &#xff1a; 通訊錄 1.1問題描述 編寫一個通訊錄管理系統&#xff0c;以把所學數據結構知識應用到實際軟件開發中去。每條信息至包含 &#xff1a;姓名&#xff08;NAME &#xff09;街道&#xff08;STREET&#xff09;城市&#xff08;CITY&#xff09;郵編&#…

linux內核panic

1. Linux Kernel Panic的產生的原因 panic是英文中是驚慌的意思&#xff0c;Linux Kernel panic正如其名&#xff0c;linux kernel不知道如何走了&#xff0c;它會盡可能把它此時能獲取的全部信息都打印出來。 有兩種主要類型kernel panic&#xff0c;后面會對這兩類panic做詳細…

數據結構課程設計------c實現散列表(二次探測再哈希)電話簿(文件存儲)

題目二 &#xff1a;散列表的設計與實現 2.1問題描述 設計散列表實現電話號碼查找系統&#xff0c;使得平均查找長度不超過2基本要求 &#xff08;1&#xff09;設每個記錄有下列數據項&#xff1a;電話號碼、用戶名、地址&#xff1b; &#xff08;2&#xff09;從鍵盤輸入各…

科技論文----論搜索引擎現狀及發展趨勢

搜索引擎現狀及發展趨勢 【摘要】 隨著最近10年中國互聯網的快速發展菜互聯網已經徹底改變了人們的生活方式&#xff0c;而在互聯網的發展過程中。搜索引擎發揮了巨大的推動作用。本文對搜索引擎的發展歷史采用的技術&#xff0c;發展現狀出現的問題以及未來發展方向進行了綜述…

inittab文件格式

/etc/inittab文件是Linux系統第一個進程init的配置文件。其每個記錄占一行&#xff0c;每行最多512個字符。該文件的每個記錄的格式為&#xff1a; id:runlevel:action:process 其中&#xff0c;id是一個不超過4個字符的標識&#xff0c;用來唯一標識一條記錄。runlevel表明該條…

數據結構課程設計------掃雷游戲(升級版,可展開)

本程序由團隊中的一個人所寫&#xff0c;本人看懂并寫下此文章 題目&#xff1a;掃雷 3.1問題描述 掃雷游戲 [基本要求] &#xff08;1&#xff09;完成棋盤的初始化并在標準顯示器中顯示 &#xff08;2&#xff09;通過輸入行列值確定用戶輸入 &#xff08;3&#xff09;游…

C語言的編譯鏈接過程的介紹

發布時間: 2012-11-08 10:17 作者: 未知 來源: 51Testing軟件測試網采編 字體: 小 中 大 | 上一篇 下一篇 | 打印 | 我要投稿 | 推薦標簽&#xff1a; DotNet 軟件開發 | 感言十年 C語言的編譯鏈接過程要把我們編寫的一個c程序&#xff08;源代碼&#x…

vs2013鏈接Mysql時出現 (由于找不到libmysql.dll,無法繼續執行代碼。重新安裝程序可能會解決此問題)

將MySQL安裝目錄下的lib文件夾中 的libmysql.dll文件拷貝到C:\Windows\System32目錄下即可

gcc 優化選項 -O1 -O2 -O3 -Os 優先級,-fomit-frame-pointer

少優化->多優化&#xff1a; O0 -->> O1 -->> O2 -->> O3 -O0表示沒有優化,-O1為缺省值&#xff0c;-O3優化級別最高 英文解析&#xff1a; -O -O1 Optimize. Optimizing compilation takes somewhat more time, an…

const 和 #define 區別總結

const有類型&#xff0c;可進行編譯器安全檢查&#xff0c;#define 無類型&#xff0c;不可進行類型檢查const 有作用域&#xff0c;而#define 不重視作用域&#xff0c;默認定義在指定作用域下有效的常量&#xff0c;那么#define 就不能用&#xff08;可以用#undef結束宏定義生…

Eclipse : Unresolved inclusion

Eclipse 中新建C 或C 到項目時&#xff0c;頭文件報警&#xff0c;顯示“Unresolved inclusion:<stdio.h>” 雖然不影響項目到編譯和運行&#xff0c;確也無法查看頭文件&#xff0c;讓人感覺實在不爽。下面是在國外到網站上看到解決方案&#xff0c;自己整理了一下拿來分…

c++對const增強 和cosnt分配內存情況

const增強 c語言中const是偽常量&#xff0c;可以通過指針修改 c中const會放到符號表中 c語言中const默認是外部連接&#xff0c;c中const默認是內部鏈接 #include<iostream> using namespace std;const int m_a 10; //在全局區域里&#xff0c;受到保護&…

Linux下crontab命令的用法

任務調度的crond常駐命令 crond 是linux用來定期執行程序的命令。當安裝完成操作系統之后&#xff0c;默認便會啟動此任務調度命令。crond命令每分鍾會定期檢查是否有要執行的工作&#xff0c;如果有要執行的工作便會自動執行該工作。而linux任務調度的工作主要分為以下兩類&am…

c++中引用的作用

引用的基本語法 用途起別名 Type &別名原名 引用必須初始化 一旦初始化后&#xff0c;不能修改 對數組建立引用 #include<iostream>using namespace std;//1.引用基本語法 Type &別名原名void test01(){int a 10;int &b a;cout << "a"…

LVM (Logic Volume Management,邏輯卷管理)

是傳統商業Unix就帶有的一項高級磁盤管理工具&#xff0c;異常強大。后來LVM移植到了Linux操作系統上&#xff0c;盡管不像原來Unix版本那么強大&#xff0c;但瘦死的駱駝比馬大&#xff0c;Linux的LVM仍然非常強大&#xff0c;可以在生產運行系統上面直接在線擴展硬盤分區&…

cpu中的MMU的作用

虛擬內存與物理內存之間的映射 用戶空間映射到物理內存是獨立的&#xff0c;提高安全性修改內存訪問級別 &#xff08;0是最高級&#xff09;

Linux命令行與Shell腳本編程大全讀書筆記

Linux內核4大主要功能&#xff1a; 內存管理 進程管理 設備管理 文件系統管理 Linux系統啟動的進程和腳本管理 1./etc/inittab 管理系統開機時會自動啟動的進程 2./etc/init.d 管理開機時啟動或停止某個應用的腳本放在這個目錄下&#xff0c;/etc/rcX.d目錄在啟動時&…

拷貝構造函數的總結

構造函數的分類及調用 按照參數分類 1.無參構造&#xff08;默認構造&#xff09; 2.有參構造按照類型分類 1.普通構造函數2.拷貝構造函數無參構造寫法和調用 Person p1; 注意不能寫Person (),因為編譯器認為這個是函數聲明有參構造函數寫法 和調用 Person p2(10) 或者Per…

技術與技巧札記

Linux常用命令及技巧&#xff1a; &#xff08;1&#xff09;cat /proc/version 查看當前內核的版本 (2) 掛載nfs文件夾&#xff1a;需要先確認在&#xff0f;etc&#xff0f;exports文件&#xff0c;可以用于開發板掛載的文件夾 mount -o nolock 10.0.22.30:/root/sharednfs …