《C++ Primer 第五版》第二章(1-4小節)------基本內置類型,初始化和賦值及聲明和定義,指針和引用,const和constexpr

? ? ? ? C++ Primer第二章的內容主要介紹了變量和基礎類型,包括C++語言定義的基礎內置類型、變量的定義及聲明、符合類型如指針及引用的介紹和const及常量表達式constexpr的介紹,本次博客也從這四個方面進行系統的介紹,如果有不足之處,還望其他博主留言指正;如果博客對你有一定的幫助,還請點個贊支持一下。

1)基本內置類型

? ? ? ? ? C++語言具有廣泛的數據類型,除了基本內置類型之外,還定義了一些復雜的數據類型,比如可變長字符串string和向量vector等,另外也為碼農提供了自定義數據類型的機制,比如類和結構體等,本次博客主要是介紹C++語言中的基本內置類型。

? ? ? ? ? C++將基本內置類型分為算術類型和空類型(void),算術類型又分為整數類型和浮點數類型,其中整數類型又分為布爾類型(bool 未定義最小尺寸大小,值為true或false),字符類型(char,最小尺寸為8位),short類型(最小尺寸為16位),int類型(最小尺寸為16位),long類型(最小尺寸為32位),long long類型(C++11中新定義的,最小尺寸為64位);另外浮點型包括單精度浮點型(32位,有效位數為5位)和雙精度浮點型(64位,有效位數為7位),且浮點數在計算機中的儲存結構如下圖所示:

? ? ? ? ?

? ? ? C++中定義一個char類型的大小和一個機器字節一樣長,同時定義byte(long long)>=byte(long)>=byte(int)>=byte(short)。

? ? ? 在選擇數據類型的時候有以下四條建議:1)合理使用無符號類型,避免無符合和有符號數混合運算;2)整型定義盡量使用int,如果數據較大則使用long long;3)算術表達式盡量不要出現bool和char類型;4)浮點運算選用double類型。

2)初始化及賦值和聲明及定義

? ? ? 初始化賦值時兩個完全不同的概念,初始化的含義是創建變量時并對變量賦予一個初始值,其調用的是定義好或默認的構造函數,而賦值的含義是將對象當前的值擦除,并用一個新值來替代,調用的是拷貝構造函數或=重載操作符函數。

? ? ? 如果變量只是定義但沒有指定初值,系統會對變量進行默認初始化。對于內置類型變量的默認初始化值,和其位置有關。如果內置類型變量定義在任何函數之外,則默認初始化為0;如果定義在函數內部,則不會被初始化,此時的值未定義,拷貝和訪問沒有定義的值會發生錯誤。絕大多數類都支持默認初始化,這和類中是否有默認構造函數有關,有一些其他的類則需要顯示進行初始化。

? ?? C++規定,可以采用初始化列表的形式來初始化變量,即采用一組由花括號括起來的值來初始化變量,但是需要注意的是使用初始化列表的形式初始化內置類型變量時,如果初始化過程中存在數據截斷的情況,如把一個浮點數賦值給整數,編譯器會報錯

? ? ?C++為了方便程序實現分離式編譯(可以理解成.C和.h文件的獨立),將聲明和定義區分開。聲明的目的是為了讓變量的名字為程序所知,聲明中只規定變量的類型和名字,并在前面加上extern關鍵字(但不能對加了extern關鍵字的變量進行初始化,否則extern關鍵字失效);定義的目的則是為了創建和名字有關的實體,為變量申請內存空間,還可能初始化變量。

? ? ?建議:不管是在函數內還是函數外,使用內置類型都要初始化。在函數體內部初始化一個由extern關鍵字標記的變量,會發生錯誤,因為變量只能定義一次,但可以多次聲明。

3)指針及引用

? ? ? 指針是一種指向其他類型對象的復合類型(基本數據類型+一組聲明符),大多數情況下需要滿足定義的指針類型和指針指向對象的類型匹配(兩種特殊情況:1)常量指針指向非常量對象。2)virtual類的動態編譯)。指針是一個對象,可以進行賦值和拷貝,也可以指向不同的對象,同時不需要在定義的時候進行賦值(和引用的區別)。使用指針時,如果需要分析程序執行的每個時間段指針的指向,可以采用內存四區模型和一個建議(指針指向誰,就把誰的地址賦給指針)來進行分析。

? ? 對于指針而言,指針的值存在四種狀態:1)指向一個對象(一般情況);2)指向緊鄰對象的一個空間(尾后迭代器);3)空指針,沒有指向任何對象;4)無效指針,除1)2)3)情況之外。

? ? 建議:對于使用了指針的情況下,要判斷所得到的指針是否有效,訪問和拷貝無效指針的值會使程序崩潰。

? ? 引用是指對象的別名,一般情況下的引用都指的是左值引用。引用定義的機制是將引用和變量對象綁定起來,使得引用稱為變量的另外一個名字,但是此時的變量對象可以不初始化。由于定義引用需要將引用和變量對象進行綁定,因此引用必須初始化,且一旦綁定了一個對象,引用就不能再綁定另外一個對象了。引用不是對象,它只是變量對象的一個別名,因此不能定義引用的引用或指向引用的指針。由于引用是和變量對象是綁定起來的,因此通常情況下引用的類型和綁定對象的類型要一致(除了兩種情況:1)初始化常量引用,可以采用任意表達式作為初始值,只要能夠轉換成引用類型;2)virtual類的動態編譯)。

4)const和常量表達式constexpr

? ? ? const限定符的作用是用于限制變量的類型。一般情況下有兩種情況:1)默認情況下,const對象只能在文件內有效。多個文件出現相同的const變量時,等同于不同文件中獨立定義的const變量。2)當const變量初始值不是一個常量表達式且需要實現多個文件共享變量,需要在一個文件中定義const變量,其他文件中聲明并使用它(聲明和定義變量時都需要加上extern const標識符)。

? ? ? 常量引用:也稱為對const的引用,是將引用綁定到const對象上。C++規定允許將非常量的對象,字面量和一般表達式綁定給一個常量引用,只要右端的值能夠轉化為引用的類型即可。但是,在不同類型轉換的過程中,其實引用綁定的是一個臨時量,而非我們希望綁定的那個數據,具體例子如下所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?double var=3.14;? ? ? ------------>? ? ? ? ?const int temp=var;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const int &p=var;? ? ? _______>? ? ? ? ? const int &p=temp;

? ? ?建議:使用引用綁定對象時,養成引用和綁定對象類型一致的習慣。

? ? ?常量表達式(constexpr)指的是值不會改變且在編譯過程中能夠得到計算結果的表達式。一般來說,可以使用算術類型,引用和指針等字面值類型的變量來初始化常量表達式。除此之外,可以地址固定不變的對象來初始化常量表達式。對于constexpr類型的指針初始值必須為nullptr(0)、存儲于某個固定地址的對象或超出函數范圍之外的變量(如static和global變量)。

? ? C++11規定可以采用constex來驗證變量的值是否為常量表達式,初始化常量表達式的值必須為常量或constexpr函數。


***知識點補充1:字,字節和位的區別?

? ? ?位:即bit,是計算機用來存儲數據的最小單元,取值為0或1;

? ? ?字節:即byte,是計算機可尋址的最小內存塊,一個字節等于8bit;(牽涉到的知識點:定義數據的大小)

? ? ?字:即word,是計算機存儲的基本單元,通常由幾個字節組成;(牽涉到的知識點:數據對齊方式和計算機的位數)

***知識點補充2:變量,對象和值之間的關系?

? ? 變量:提供一個具體名字的,可供程序操作的存儲空間。

? ? 對象:具有某種類型的內存空間(數據類型+內存空間)。

? ? 值:只讀的數據。

? ? 已命名的對象才稱為變量。

***知識點補充3:變量的命名規則?

? ? 變量的命名規則有以下四個建議:1)變量名體現實際含義;2)變量名一般使用小寫;3)自定義的類名以大寫字母開頭;4)如果出現多個單詞,單詞之間采用下劃線連接。

***只是補充點4:指向常量的指針/引用,常量指針,頂層const,底層const區別?

? ? 指向常量的指針/引用:指針指向的/引用綁定的對象為常量,此時不能用指針/引用去改變常量對象的值。

? ? 指針常量:指針的地址不變,指向的對象數據可以發生改變,必須初始化。

? ? 頂層const:定義的對象是常量(如常量指針,常量內置定義類型);

? ? 底層const:定義對象指向的值或者綁定的值為常量(如指針常量,指向常量的引用);

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

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

相關文章

455. 分發餅干 golang

455. 分發餅干 Me func findContentChildren(g []int, s []int) int {if len(s) 0 {return 0}sort.Ints(g)sort.Ints(s)var count, i, j int 0, 0, 0for { if g[i] < s[j] {i, j, count i1, j1, count1} else {j}if i > len(g) || j > len(s) {return count}}re…

《C++ Primer 第五版》第二章(第5小節)——using和typedef,auto和decltype總結

1.using和typedef&#xff08;作用&#xff1a;定義類型別名&#xff09; 1)typedef和using都可以用來定義一個類型別名&#xff0c;二者在類型別名上定義沒有區別。只是需要注意的是類型和類型別名的順序&#xff0c;使用typedef定義類型別名的結構為 typedef 類型 類型別名&a…

204. 計數質數 golang

一次嘗試&#xff0c;如何擊敗100%用戶&#xff08;用時&#xff0c;內存&#xff09; func countPrimes(n int) int {if n 499979 {return 41537}if n 11 {return 4}if n 12 {return 5}if n 13 {return 5}if n 14 {return 6}if n 15 {return 6}if n 10 {return 4}if n …

leetcode內存消耗

leetcode內存消耗最是多少 執行用時 :0 ms, 在所有 Go 提交中擊敗了100.00%的用戶 內存消耗 :1.9 MB, 在所有 Go 提交中擊敗了94.81%的用戶測試鏈接 Test

《C++ Primer 第五版》(第2.5節,第3.1-3.4節) ——采用預處理功能編寫頭文件,string初始化和字符操作,vector初始化和迭代器

1.采用預處理功能編寫頭文件 在頭文件定義(頭文件中的內容是只能被定義一次的實體)過程中&#xff0c;為了防止頭文件重復包含的情況&#xff0c;采用預處理器的一個頭文件保護符功能,格式為&#xff1a;{ #ifndef 預處理變量(通常大寫) #define 預處理變量 #end…

《C++ Primer 第五版》(第3.5-3.6節) ——C++中的內置數組類型,string對象和C風格字符串

1.C中的內置數組類型 C中的數組是內置數據類型&#xff0c;但不是基礎數據類型而是構造數據類型&#xff0c;是有限個相同數據、占據著連續物理存儲空間的有序集合。而內置數據類型定義的下標運算符可以處理負值運算(只要在數組范圍之內)&#xff0c;這和vector及string的下標運…

793. 階乘函數后K個零 golang

Me(AC 33 / 44 個通過測試用例) func preimageSizeFZF(K int) int {count : 0for i : 0; i < 1000000; i {if trailingZeroes(i) K {count}}fmt.Println(count)//fmt.Println(trailingZeroes(25))return count}func trailingZeroes(n int) int {if n 0 {return 0}return …

小程序radio單選框回顯

話不多說&#xff0c;效果圖如下&#xff1a; 具體代碼如下&#xff1a; <radio-group name"radio" bindchange"getSex"><label><radio value"1" checked"{{xingbie1}}" />男</label><label><radio…

172. 階乘后的零 golang

官解 一般很難想到這個方向&#xff0c;有點類似數學歸納法&#xff1f; func trailingZeroes(n int) int {if n 0 {return 0}return trailingZeroes(n / 5) n / 5 }

《C++ Primer 第五版》(第4.11節類型轉換) ————關于無符號數和有符號數的運算探究

1.關于無符號數和有符號數的運算 關于無符號數和有符號數的運算&#xff0c;在我看來一直是覺得只要有無符號數和有符號數的運算&#xff0c;有符號數就轉化為無符號數&#xff0c;但是在《C Primer 第五版》的p142介紹&#xff0c;關于無符號數和有符號數的運算如下規定的&…

《C++ Primer 第五版》(第4.1-4.11節) ——運算符的執行順序問題,負值坐商取余問題,數值的移位操作

1.運算符的執行順序問題 在C語言中&#xff0c;沒有明確規定大多數二元運算符的求值順序&#xff0c;這給編譯器留下了余地&#xff0c;這種策略是在代碼生成效率和程序潛在缺陷之間的權衡。 對于運算符而言&#xff0c;如果運算符的兩個對象中&#xff0c;存在表達式指向并修改…

543. 二叉樹的直徑 golang

文章目錄543. 二叉樹的直徑example正確解法question代碼&#xff08;wrong)543. 二叉樹的直徑 概要: 借鑒了這個題的代碼。可是有一個測試用例過不去 https://blog.csdn.net/csdn_kou/article/details/104122067 example 給定一棵二叉樹&#xff0c;你需要計算它的直徑長度。一…

《C++ Primer 第五版》(第4.11-4.12節)——static_cast,const_cast和reinterpret_cast類型轉換, 運算符優先級表

1.static_cast,const_cast和reinterpret_cast類型轉換 static_cast:強制的類型轉換(不能用于底層的const轉換),以前C語言中的強制類型轉換都可以使用static_cast來完成。如&#xff1a;int i3; double jstatic_cast<double>(i); const_cast&#xff1a;改變底層const(指針…

《C++ Primer 第五版》(第5.1-5.6節) ——異常處理機制(try語句塊,throw表達式和catch異常捕捉處理單元)

1. 異常處理機制 C中使用try,throw和catch三個關鍵字來實現異常的觸發、拋出和處理的功能&#xff0c;具體通用語法形式如下&#xff1a; try{ if(true) normal program-statements&#xff1b;//沒有觸發異常時候執行的代碼 if(false) throw(exception); //出現錯誤&am…

《C++ Primer 第五版》(第6.1~6.3節) 函數形參和實參傳遞,可變參數列表和函數返回值

1.函數形參和實參傳遞問題 函數參數傳遞有兩種&#xff1a;值傳遞(變量&#xff0c;指針&#xff09;,引用傳遞(使用別名&#xff09;。 在形參和實參的傳遞過程中&#xff0c;牽涉到大的類類型對象、容器類型對象或者不支持拷貝操作的對象時&#xff0c;不適合采用值傳遞&…

461. 漢明距離 golang

Me 異或取出1的個數求取異或后1的個數返回 func hammingDistance(x int, y int) int {x x ^ yvar count 0for x ! 0 {x x & (x - 1)count}return count }

《C++ Primer 第五版》(第6.3~6.7節)——返回指向數組/函數的指針,函數重載,默認形參、inline函數和constexpr函數

1.返回指向數組/函數的指針 顧名思義&#xff0c;就是函數返回值為指向數組/函數的指針。 數組的性質&#xff1a;不能被拷貝&#xff0c;函數也不能返回數組。但可以返回數組指針/引用&#xff0c;聲明一個返回數組指針的函數&#xff0c;有四種方式&#xff0c;一種是直接聲明…

136. 只出現一次的數字 golang

Me 1. 先排序就好做了 執行用時 :16 ms, 在所有 Go 提交中擊敗了27.90%的用戶 內存消耗 :4.7 MB, 在所有 Go 提交中擊敗了100.00%的用戶func singleNumber(nums []int) int {sort.Ints(nums)for i:0; i < len(nums); i {if i len(nums) - 1 {return nums[i]}if nums[i] …

《C++ Primer 第五版》(第1~6章總結)

1.C采用標準庫文件iostream定義的兩個對象來實現IO機制。 2.代碼注釋應解釋關鍵數據的變量含義和代碼完成了什么功能&#xff0c;力求簡潔易懂。 3.正確理解初始化和賦值&#xff0c;聲明和定義的含義&#xff1f;初始化是在定義對象的時候同時賦值&#xff0c;賦值是定義對象…

268. 缺失數字 golang

Me 首項加末項乘以項數/2.就是總和。然后剪掉nums里面的數組和 func missingNumber(nums []int) int {var sum intlens : len(nums)for _, value : range nums {sum value}return ((1 lens) * lens) / 2 - sum }