C++Primer 第2章 變量和基本類型

第二章

2.1 基本類型

  1. C++的基本類型分爲空類型和算術類型,空類型就是void,算術類型就是整型,字符型,浮點型,布爾型
  2. char分爲,unsigned char,signed char和char,其中char是有符號還是無符號取決於編譯器
  3. 對於無符號類型,如果賦值超過了其表示範圍,則結果爲該無符號類型所能表示的數值個數%賦值的數。
unsigned char c = -1;
//256%-1
cout<<int(c)<<endl;//輸出爲255
c=256;
//256%256
cout<<int(c)<<endl;//輸出爲0

這個其實算是總結規律了,超過其表示範圍的正數,從二進制角度來看其值全是000000000,所以超過其表示範圍的正數結果都是0。

而超過其表示範圍的負數,則要求得補碼,然後得到結果,總結除規律。
-1的源碼爲
1000 0001
補碼
1111 11111 =255

  1. 對於有符號類型,其值超過了表示範圍的話,是未定義行爲,即,有可能報錯,有可能產生垃圾值,還有可能忽略了超過的部分。

  2. 整型轉布爾類型的時候,值爲0,表示false,爲其他值表示true,包括負數。

  3. 字面值常量都對應着一個具體的基本類型,如果寫得超過了基本類型的表示範圍則會報錯。
    在這裏插入圖片描述

2.2 變量

  1. 在任何函數體外定義的基本數據類型變量,其默認初始值爲0,但是在函數體中定義的基本數據類型變量默認初始值是未定義的。對於類的對象,則是由默認構造函數來決定
  2. extern int i;表示聲明一個來自外部的變量,但是如果寫成extern int i = 1; 則編程了定義一個變量。

2.3 複合類型

複合類型就是基本數據類型+一個*或者&,表示指針或者引用

  1. 可以使用int *a=0;來初始化指針,但是不可以使用
int zero = 0;
int* a = zero;

來初始化因爲我們不能用一個int對象來爲int變量賦值。
2. void
,可以指向任何類型的地址,但是其不能用來解引用

2.4 const限定符

  1. const定義的變量會在編譯時,把用到這個變量的地方都替換爲對應的值。
  2. const定義的變量,僅在文件內有效,如果我們在不同的文件中使用const int a,其實是定義了多個const變量!!!!!但是如果我們想在其他的文件中也使用同一個const變量,那麼在聲明這個const變量的時候,需要使用
1.cpp
extern const string hello="world";

而在調用的地方使用來調用

2.cpp
extern const string hello;

拓展:
對於全局的非const變量,他的作用域是整個程序,所以其他的文件都可以訪問到這個全局的非const變量。
我們要使用這個全局的非const遍歷時,使用

1.cpp
int dali=233;
2.cpp
extern int dali;

來調用

如果在其他文件中,以下方法,則程序會報錯,因爲重定義了。

2.cpp
extern int ali=666;
或者
int ali=66
  1. 不可以使用普通引用來綁定一個字面值常量,但是可以使用一個const引用來綁定字面值常量。

一種理解角度是:因爲const定義的變量在編譯時將在調用處替換爲其所存儲的值,雖然將其綁定爲一個字面值常量,但是在編譯時又被替換爲字面值了,所以這種綁定方式合法。

  1. const分爲低層const和頂層const,頂層const在賦值時,const可以被忽視。但是低層const不能被忽視。其中指針常量是低層const,所有的const引用都是低層const
const int i=1;//頂層
int j = i;//不報錯

const int* p = nullptr;
int* q = p;//不報錯

int* const p = nullptr;
int *q = p;//報錯

int v=  123;
const int& i = v;
int& j = i;//報錯

注意對於const引用都是低層const,其const不能忽略的前提是,初始化的對象還是const對象,如果初始化的對象是一個普通的變量,是可以的。

int v=  123;
const int& i = v;
int j = i;//合法

5.在編譯時就確定了取值和取值不會改變的變量叫做常量表達式。常量表達式要用const來修飾,但是使用const修飾的變量,不一定是常量表達式。

比如

const int v=  get_data();

該函數只有在運行時才能確定取值,所以v,不是常量表達式。
可以使用constextpr來聲明一個常量表達式,讓編譯器來驗證這個變量是否是常量表達式。

constexpr int* p = nullptr;const int*p = nullptr;

的結果是一頁的。

2.5 處理類型

  1. 對於頂層const,auto推導類型時會直接忽略,但是對於低層const則會保留。
const int*  p = nullptr;//低層const
auto a = p;//a的類型爲const int*
  1. decltype 類型指示符,用來獲取變量的類型,其會原樣的保留變量的類型。對於頂層const和低層const他都會保留。

對於一個指針解引用獲取的類型將是變量的引用的類型。因爲*p可以改變變量本身,所以得到的類型也將是引用類型。

如果decltype()中的是一個普通變量,那麼得到的類型就是變量的類型,但是如果裏面是一個表達式,那麼decltype()得到的類型取決於表達式是左值還是右值,如果表達式返回的結果是左值,那麼得到的結果是變量類型的引用。

decltype(a=b)

一個特殊的情況是,如果對一個變量使用()括起來,得到的結果也是這個變量類型的引用。
decltype並不會計算其內部的表達式,而是推斷表達式指向的結果,這和sizeof()運算符一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章