C++的資料與類型

來源:互聯網
上載者:User

一、前言

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

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

二、關於C++的學習

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

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

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

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

三、資料與類型

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

整型、字元型等內建類型

變數,用來為對象命名

運算式和語句,用於操縱上述資料類型的具體值

if或while等控制結構,這些結構允許我們有選擇地執行一些語句或者重複地執行一些語句

函數,用於定義可供隨時調用的計算單元

自訂資料類型:比如:類

標準庫

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

這本篇文章中,主要是關於前2點的內容:對象和對象的類型。

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

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

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

short 一般很少使用,容易產生越界。

char類型在一些實現中有時作為signed處理,而有時作為unsigned處理,所以只用char來表示字元是明智之舉。

在大多數的時候使用int就沒有問題,在很多機器上int用4個位元組儲存,足夠滿足大部分計算的要求。

浮點型的選擇就很簡單了,使用double類型基本不會有什麼錯誤,而且有可能會比float計算代價低。

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

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

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

3 {

4     std::cout << u << std::endl;

5 }

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

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

8,引用和指標都是C++定義的複合類型,引用與指標的定義是由一個基礎資料型別 (Elementary Data Type)和緊隨其後的一個聲明符列表組成。

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

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

更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/

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是一指向字元的指標

2 const pstring cstr=0; // cstr是一個指向字元的常量指標

3 const 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";  // 拷貝初始化

2 string s2("hiya"); // 直接初始化

3 string s3(10, 'c');   // 直接初始化

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

1 vector<vector<double>>::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<string> v1{"hi"};  //v1有一個元素

2 vector<string> v2("hi");  //error

3 vector<string> v3{10};  //v3本來想用10來初始化vector,但是發現10不是strring對象,所以把v3初始化為10個元素。

4 vector<string> v4{10,"hi"};  //v4本來想用10和“hi”初始化vector,但發現10不是string對象,所以就把v4定義為10個元素的vector

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

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

1 int ia[]={0,1,2,3,4,5,6,7,8,9};

2 int *beg = begin(ia);  // 指向ia首元素的指標

3 int *end = end(ia);  // 指向ia尾元素的下一位置的指標

作者:☆Ronny丶

出處:http://www.cnblogs.com/ronny/

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。