C 的那些事 資料與型別

2021-09-08 10:11:20 字數 4962 閱讀 3053

最近在看c++primer第5版,先前已經看過第4版,但是發現第5版在整個知識布局與個別知識的講解上跟第4版差別還是挺大的,尤其是新增了c++11的內容,正如孟巖老師在第5版前言中所講:「現在能夠以新的c++11風格開發實踐的人是鳳毛麟角,如果能夠純熟的運用c++11的新特徵、新機制,那麼就能夠形成一種簡潔優雅的c++程式設計風絡,開發會變得更高效,更高質」。

所以正好借助第5版來重新學習鞏固c++的知識。《c++的那些事》這個系列,將會以知識碎片的形式記錄我在學習過程中一些知識重點。

個人身為c++菜鳥,自然是沒有任何經驗之談,這裡摘錄c++primer5ed前言裡一些個人以為很有道理的觀點。

1,學習語言的乙個境界是把自己想象成編譯器。

2,使用c++語言的「兩面性」觀點。c++正在走向完美,所以,c++語言值得學習(甚至研究)。這些知識可以成為一切程式設計的基礎。然而在實踐中,不必全面地使用c++語言的各種特性,而應根據工程專案實際情況,適當取捨(譬如動態型別資訊、虛擬繼承、異常等特性的使用)。通常只鼓勵使用c++語言的乙個子集。

關於第2點,個人是相當的認同,c++的一些高階特性,確實只有在一些庫例程中才有體現,一般工程開發中很少能用得上。所以在學習c++的時候,開始不必對一些語法細節或高階技法過於追求完美,可以先知其大概,在以後工作學習中再逐漸加深認識。

1,任何一門程式語言都是由一些基本元件來構成,c++也是一樣。

c++的另外一點就是程式設計思想,通過類引入了物件導向程式設計的思想,再通過模板等技術引入了通用或泛型程式設計的思想。

2,型別是程式設計中最基本的概念,一種型別不僅定義了資料元素的內容,還定義了這類資料上可以進行的運算。內建的資料型別如此,使用者自定義的型別也是如此,c++的乙個很重要的任務就是讓使用者設計的型別像語言內建型別一樣好用。

3,程式所處理的資料都儲存在變數中,而每個變數都有自己的型別。

4,執行算術運算時,資料型別的選擇

5,在使用無符號數作為迴圈的索引時,注意unsinged int 與 int型別間的隱式資料轉換,如下面的程式,可能實際並不是你想要的結果。

1

//error 變數u永遠也不會小於0,迴圈條件一直成立

2for (unsigned u = 10; u > = 0; -- -u)

3

6,c++11定義了一種新的指標字面值nullptr,用於取代c語言中預編譯常量null

7,注意c++中初始化與賦值的區別,這一點在類的定義中更為明顯。初始化不是賦值,初始化的含義是建立變數時賦予其乙個初始值,而賦值的含義是把物件的當前值擦除,而以乙個新值來替代。

8,引用和指標都是c++定義的復合型別,引用與指標的定義是由乙個基本資料型別和緊隨其後的乙個宣告符列表組成。

1)引用是給變數另起了乙個名字,當定義引用時,程式把引用和它的初始值繫結在一起,而不是將初始化拷貝給引用。一旦初始化完成,程式把引用和它的初始值物件一直繫結在一起。因為無法令引用重新繫結到另外乙個物件,因此引用必須初始化。

實際上引用的本質是指標,而且是乙個常量指標,占用4個位元組的空間。

2)與引用不同的是,指標本身是乙個物件,允許指標拷貝和賦值,而且在指標的生命週期內,它可以先後指向幾個不同的物件。

9,常量表示式是指值不會改變並且在編譯過程中就能得到計算結果的表示式。

在乙個複雜的系統中,很難分辨乙個初始值到底是不是常量表示式。c++11允許將變數宣告為constexpr型別以便由編譯器來驗證變數的值是否是乙個常量表示式。宣告constexpr的變數一定是乙個常量,而且必須用常量表示式初始化:

1 constexpr int mf = 20

; 2 constexpr int limit = mf + 1

; 3 constexpr int sz = size(); //

只有當size是乙個constexpr函式時才是一條正確的宣告語句

用constexpr修飾的指標說明是常量指標,它本身在定義初始化後不可以再更改指向,但是所指的物件可以是個變數。

10,注意指標、常量和型別別名在一塊的時候:

1 typedef char* pstring; //

pstring是一指向字元的指標

2const pstring cstr=0; //

cstr是乙個指向字元的常量指標

3const pstring *ps; //

ps是乙個指標,它的物件是指向char的常量指標。

11,auto型別

c++11引入auto型別說明符,用它就能讓編譯器替我們去分析表示式所屬的型別。編譯器是通過初始值來推算變數的型別,顯然,auto定義的變數必須有初始值。

如果我們用乙個引用型別去初始化乙個auto型別時,得到的型別將是引用物件的型別:

1

int i = 0, &r =i;

2 auto a = r; //

a是乙個整數

其次auto一般會忽略掉頂層的const,同時底層的const則會保留下來。

1

const

int ci = i, &cr =ci;

2 auto b = ci; //

b是乙個整數

3 auto c = cr; //

cr是乙個整數(ci的頂層const特徵被忽略了)

4 auto d = &i; //

d是乙個指標(指標是指向整數的指標)

5 auto e = &ci; //

e是乙個指向整數常量的指標

如果希望auto推斷出的是auto型別是乙個頂層的const,需要明確指出:

1

const auto f = ci;

12,decltype型別指示符

有的時候想從表示式的型別推斷出要定義的變數的型別,但是不想用該表示式的值初始化變數,為些c++11引入了第二種型別說明符decltype,它的作用是選擇並返回運算元的資料型別。

decltype(f()) sum = x; //

sum的型別就是f的返回值型別,編譯器並不呼叫f

decltype在處理頂層const和引用的方式與auto不同。

1

const

int ci = 0, &cj =ci;

2 decltype(ci) x = 0; //

x的型別是const int

3 decltype(cj) y = x; //

y的型別是const int&, y繫結到變數x

4 decltype(cj) z; //

error, z是乙個引用,必須初始化

引用從來都是作為其所指物件的同義詞出現,只有用在decltype處是個例外。

delctype((variable))(注意是雙層括號)的結果永遠是引用,而decltype(variable)結果只有當variable本身就是乙個引用時才是引用。

13,標準庫定義了2種非常重要的抽象型別,一種是string用來支援可變長的字串;另一種是vector表示可變長的集合。

14,對於string和vector物件都可以有多種方式初始化,這取決於類的定義,但一般直接初始化和拷貝初始化都是存在的。如果使用等號「=」初始化乙個變數,實際上執行的是拷貝初始化,編譯器把等號右側的初始值拷貝到新建立的物件中去。與之相反,如果不使用等號,則執行的是直接初始化。

1

string s1 = "

hiya

"; //

拷貝初始化

2string s2("

hiya

"); //

直接初始化

3string s3(10, '

c'); //

直接初始化

15,string型別和標準庫容器型別都提供了一種size_type型別,它是乙個無符號的值,而且足夠存放下任何容器或string物件的大小。而在c++11中,我們可以用auto或decltype來讓編譯器自動推斷出這種型別,而不用寫很長的**,比如:

1 vectordouble>>::size_type i; //

原來的方法

2 decltype(dvv.size()) i; //

c++11用decltype

3 auto i = dvv.size(); //

c++11用auto

16,c++11中另外為vector物件提供了一種列表初始化的方法,此時,用花括號括起來的0個或多個初始化元素值被賦予vector物件。但是值得注意的是:如果用的是花括號,可以表述成我們想列表初始化該vector物件。也是就是,初始化過程會盡可能地把花括號內的值當成是元素初始化的列表來處理,只有在無法執行列表初始化時才會考慮其他初始化方式。

1 vector v1;  //

v1有乙個元素

2 vector v2("

hi"); //

error

3 vector v3; //

v3本來想用10來初始化vector,但是發現10不是strring物件,所以把v3初始化為10個元素。

4 vector v4; //

v4本來想用10和「hi」初始化vector,但發現10不是string物件,所以就把v4定義為10個元素的vector

17,陣列,與vector類似,陣列也是存放型別相同的物件的容器,這些物件本身沒有名字,需要通過其所在的位置訪問。而且陣列是在定義的時候就分配了大小,中間不能變化,這就給使用時帶來很大的不便。

18,指標其實與迭代器具有相同的功能,在遍歷陣列的情況下,用指標操作就像在容器上使用迭代器一樣。類似於容器型別的begin和end迭代器,c++11定義了兩個函式begin和end用來獲取序列的首指標和尾指標,這兩個函式定義在iterator標頭檔案中。

1

int ia=;

2int *beg = begin(ia); //

指向ia首元素的指標

3int *end = end(ia); //

指向ia尾元素的下一位置的指標

C 的那些事

面試總結一 1.sizeof的題 沒找到原題,找到乙個類似的如下 char str new char 100 sizeof str 答 在c c 裡陣列作為引數時傳遞的實際上是指向陣列第乙個元素的指標,因此sizeof str 返回的是指標的大小,即4。推薦於2016 11 04 03 14 03最...

Redis 型別系統那些事

參考 主要功能包括 typedef struct redisobject robj 記錄了物件所儲存的值的型別 redis string 0 字串 redis list 1 列表 redis set 2 集合 redis zset 3 有序集合 redis hash 4 雜湊表 記錄了物件所儲存的值...

c語言 陣列與指標的那些事

正文開始 由於是提高篇 所以不對簡單的指標和陣列解釋 includeint main 定義乙個一維陣列 int p a 定義乙個指向int的指標 指向陣列a的首位址 printf p p n a,a 1 printf p p n p,p 1 printf d d n p 0 a 0 return 0...