3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

《C++ Primer 5th》笔记(2 / 19):变量和基本类型

發(fā)布時(shí)間:2023/12/13 c/c++ 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《C++ Primer 5th》笔记(2 / 19):变量和基本类型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 基本內(nèi)置類型
      • 算術(shù)類型
        • 內(nèi)置類型的機(jī)器實(shí)現(xiàn)(類型在物理層面上的說明)
        • 建議:如何選擇類型
      • 類型轉(zhuǎn)換
        • 建議:避免無法預(yù)知和依賴于實(shí)現(xiàn)環(huán)境的行為
        • 算術(shù)表達(dá)式里使用布爾值
        • 含有無符號(hào)類型的表達(dá)式(帶符號(hào)數(shù)會(huì)自動(dòng)地轉(zhuǎn)換成無符號(hào)數(shù))
        • 提示:切勿混用帶符號(hào)類型和無符號(hào)類型
      • 字面值常量
        • 整型和浮點(diǎn)型字面值
        • 字符和字符串字面值
        • 轉(zhuǎn)義序列
        • 通過前后綴指定字面值的類型
        • 布爾字面值和指針字面值
    • 變量
      • 變量定義
        • 術(shù)語:何為對(duì)象?
        • 初始值
        • 列表初始化
        • 默認(rèn)初始化
        • 提示:未初始化變量引發(fā)運(yùn)行時(shí)故障
      • 變量聲明和定義的關(guān)系
        • 關(guān)鍵概念:靜態(tài)類型
      • 標(biāo)識(shí)符
      • 名字的作用域
        • 建議:當(dāng)你第一次使用變量時(shí)再定義它
        • 嵌套的作用域
    • 復(fù)合類型
      • 引用
        • 引用即別名
        • 引用的定義
      • 指針
        • 獲取對(duì)象的地址
        • 指針值
        • 利用指針訪問對(duì)象
        • 關(guān)鍵概念:一符多義(& 與 *)
        • 空指針
        • 建議:初始化所有指針
        • 賦值和指針
        • 其他指針操作
        • void* 指針
      • 理解復(fù)合類型的聲明
        • 定義多個(gè)變量
        • 指向指針的指針
        • 指向指針的引用(指針的別名)(從右向左閱讀理解)
    • const限定符
      • 概述
        • 初始化和const
        • 默認(rèn)狀態(tài)下,const對(duì)象僅在文件內(nèi)有效(const 常量在多文件中使用方法)
      • const的引用
        • 術(shù)語:常量引用是對(duì)const的引用
        • 初始化和對(duì)const的引用
        • 對(duì)const的引用可能引用一個(gè)并非const的對(duì)象
      • 指針和const
        • const指針
      • 頂層const
      • constexpr和常量表達(dá)式
        • constexpr變量
        • 字面值類型
        • 指針和constexpr
    • 處理類型
      • 類型別名
        • 指針、常量和類型別名
      • auto類型說明符
        • 復(fù)合類型、常量和 auto
      • decltype類型指示符
        • decltype和引用
    • 自定義數(shù)據(jù)結(jié)構(gòu)
      • 定義Sales_data類型
        • 類數(shù)據(jù)成員
      • 使用Sales_data類
        • Sales_data對(duì)象讀入數(shù)據(jù)
        • 輸出兩個(gè)Sales_data對(duì)象的和
      • 編寫自己的頭文件
        • 預(yù)處理器

數(shù)據(jù)類型決定了程序中數(shù)據(jù)操作的意義。如下所示的語句:

i = i + j;

其含義依賴于i和j的數(shù)據(jù)類型。如果i和j都是整型數(shù),那么這條語句執(zhí)行的就是最普通的加法運(yùn)算。然而,如果i和j是Sales_item類型(上一章內(nèi)容)的數(shù)據(jù)則上述語句把這兩個(gè)對(duì)象的成分相加。

基本內(nèi)置類型

C++定義基本數(shù)據(jù)類型:

  • 算術(shù)類型(arithmetic type)
    • 字符
    • 整型數(shù)
    • 布爾值
    • 浮點(diǎn)數(shù)
  • 空類型(void)
    • 空類型不對(duì)應(yīng)具體的值,僅用于一些特殊的場合,例如最常見的是,當(dāng)函數(shù)不返回任何值時(shí)使用空類型作為返回類型。

算術(shù)類型

算術(shù)類型分為:

  • 整型(integral type,包括字符和布爾類型在內(nèi))
  • 浮點(diǎn)型

算術(shù)類型的尺寸(也就是該類型數(shù)據(jù)所占的比特?cái)?shù))在不同機(jī)器上有所差別。

下表列出了C++標(biāo)準(zhǔn)規(guī)定的尺寸的最小值,同時(shí)允許編譯器賦予這些類型更大的尺寸。某一類型所占的比特?cái)?shù)不同,它所能表示的數(shù)據(jù)范圍也不一樣。

類型含義最小尺寸
bool布爾類型未定義
char字符8位
wchar_t寬字符16位
char16_tUnicode字符16位
char32_tUnicode字符32位
short短整型16位
int整型16位
long長整型32位
long long長整型64位
float單精度浮點(diǎn)數(shù)6位有效數(shù)字
double雙精度浮點(diǎn)數(shù)10位有效數(shù)字
long double擴(kuò)展精度浮點(diǎn)數(shù)10位有效數(shù)字

bool

布爾類型(bool)的取值是真(true)或者假(false)。

char

C++提供了幾種字符類型,其中多數(shù)支持國際化。基本的字符類型是char,一個(gè) char的空間應(yīng)確保可以存放機(jī)器基本字符集中任意字符對(duì)應(yīng)的數(shù)字值。也就是說,一個(gè)char的大小和一個(gè)機(jī)器字節(jié)一樣

其他字符類型用于擴(kuò)展字符集,如 wchar_t、char16_t、char32_t。wchar_t類型用于確保可以存放機(jī)器最大擴(kuò)展字符集中的任意一個(gè)字符,類型 charl6_t和char32_t則為Unicode字符集服務(wù)(Unicode是用于表示所有自然語言中字符的標(biāo)準(zhǔn))。

int

除字符和布爾類型之外,其他整型用于表示(可能)不同尺寸的整數(shù)。C++語言規(guī)定一個(gè)int至少和一個(gè)short一樣大,一個(gè)long至少和一個(gè)int一樣大,一個(gè)long long至少和一個(gè)long一樣大。其中,數(shù)據(jù)類型long long是在C++11中新定義的。

float

浮點(diǎn)型可表示單精度、雙精度和擴(kuò)展精度值。C++標(biāo)準(zhǔn)指定了一個(gè)浮點(diǎn)數(shù)有效位數(shù)的最小值,然而大多數(shù)編譯器都實(shí)現(xiàn)了更高的精度。通常,float 以1個(gè)字(32比特)來表示,double 以2個(gè)字(64比特)來表示,long double 以3或4個(gè)字(96或128比特)來表示。一般來說,類型float和 double分別有7和16個(gè)有效位;類型long double則常常被用于有特殊浮點(diǎn)需求的硬件,它的具體實(shí)現(xiàn)不同,精度也各不相同。


帶符號(hào)類型和無符號(hào)類型

除去布爾型和擴(kuò)展的字符型之外,其他整型可以劃分為:

  • 帶符號(hào)的(signed),可以表示正數(shù)、負(fù)數(shù)或0。
  • 無符號(hào)的(unsigned),僅能表示大于等于0的值。
  • 類型int、short、long和 long long 都是帶符號(hào)的,通過在這些類型名前添加unsigned就可以得到無符號(hào)類型,例如unsigned long。類型unsigned int可以縮寫為unsigned。

    與其他整型不同,字符型被分為了三種:char、signed char和unsigned char。

    特別需要注意的是:類型char和類型signed char并不一樣。盡管字符型有三種,但是字符的表現(xiàn)形式卻只有兩種:帶符號(hào)的和無符號(hào)的。類型char實(shí)際上會(huì)表現(xiàn)為上述兩種形式中的一種,具體是哪種由編譯器決定。

    無符號(hào)類型中所有比特都用來存儲(chǔ)值,例如,8比特的unsigned char可以表示0至255區(qū)間內(nèi)的值。

    C++標(biāo)準(zhǔn)并沒有規(guī)定帶符號(hào)類型應(yīng)如何表示,但是約定了在表示范圍內(nèi)正值和負(fù)值的量應(yīng)該平衡。因此,8比特的signed char理論上應(yīng)該可以表示-127至127區(qū)間內(nèi)的值,大多數(shù)現(xiàn)代計(jì)算機(jī)將實(shí)際的表示范圍定為-128至127。

    內(nèi)置類型的機(jī)器實(shí)現(xiàn)(類型在物理層面上的說明)

    計(jì)算機(jī)以比特序列存儲(chǔ)數(shù)據(jù),每個(gè)比特非0即1,例如:

    00011011011100010110010000111011…

    大多數(shù)計(jì)算機(jī)以2的整數(shù)次冪個(gè)比特作為塊來處理內(nèi)存,可尋址的最小內(nèi)存塊稱為“字節(jié)(byte)”,存儲(chǔ)的基本單元稱為“字(word)”,它通常由幾個(gè)字節(jié)組成。在C++語言中,一個(gè)字節(jié)要至少能容納機(jī)器基本字符集中的字符。

    大多數(shù)機(jī)器的字節(jié)由8比特(bit)構(gòu)成(1byte = 8bits),字則由32或64比特構(gòu)成,也就是4或8字節(jié)(1 word = 4 bytes or 8 bytes)。大多數(shù)計(jì)算機(jī)將內(nèi)存中的每個(gè)字節(jié)與一個(gè)數(shù)字(被稱為“地址(address)”)關(guān)聯(lián)起來

    一個(gè)字節(jié)為8比特、字為32比特的機(jī)器上,我們可能看到一個(gè)字的內(nèi)存區(qū)域如下所示:

    其中,左側(cè)是字節(jié)的地址右側(cè)是字節(jié)中8比特的具體內(nèi)容。

    我們能夠使用某個(gè)地址來表示從這個(gè)地址開始的大小不同的比特串,例如,我們可能會(huì)說地址736424的那個(gè)字或者地址736427的那個(gè)字節(jié)。

    為了賦予內(nèi)存中某個(gè)地址明確的含義必須首先知道存儲(chǔ)在該地址的數(shù)據(jù)的類型類型決定了數(shù)據(jù)所占的比特?cái)?shù)以及該如何解釋這些比特的內(nèi)容

    • 如果位置736424處的對(duì)象類型是float,并且該機(jī)器中float以32比特存儲(chǔ),那么我們就能知道這個(gè)對(duì)象的內(nèi)容占滿了整個(gè)字。這個(gè) float 數(shù)的實(shí)際值依賴于該機(jī)器是如何存儲(chǔ)浮點(diǎn)數(shù)的。
    • 如果位置736424處的對(duì)象類型是unsigned char,并且該機(jī)器使用ISO-Latin-1字符集,則該位置處的字節(jié)表示一個(gè)分號(hào)。

    Note:這里在物理層面說明一個(gè)變量的類型的作用。

    建議:如何選擇類型

    和C語言一樣,C的設(shè)計(jì)準(zhǔn)則之一也是盡可能地接近硬件。C++的算術(shù)類型必須滿足各種硬件特質(zhì),所以它們常常顯得繁雜而令人不知所措。事實(shí)上,大多數(shù)程序員能夠(也應(yīng)該)對(duì)數(shù)據(jù)類型的使用做出限定從而簡化選擇的過程。以下是選擇類型的一些經(jīng)驗(yàn)準(zhǔn)則:

    • 當(dāng)明確知曉數(shù)值不可能為負(fù)時(shí),選用無符號(hào)類型。(Note:無負(fù)無符,嗚呼嗚呼)

    • 使用int執(zhí)行整數(shù)運(yùn)算。在實(shí)際應(yīng)用中,short常常顯得太小而long一般和int有一樣的尺寸。如果你的數(shù)值超過了int 的表示范圍,選用long long。(Note:取中庸int,按需用short或long)

    • 在算術(shù)表達(dá)式中盡量不要使用 char或bool,而是只有在存放字符或布爾值時(shí)才使用它們。因?yàn)轭愋蚦har在一些機(jī)器上是有符號(hào)的,而在另一些機(jī)器上又是無符號(hào)的,所以如果使用char進(jìn)行運(yùn)算特別容易出問題。如果你需要使用一個(gè)不大的整數(shù),那么明確指定它的類型是signed char或者unsigned char(If you need a tiny integer, explicitly specify either signed char or unsigned char)。(Note:算數(shù)表達(dá)式盡量不用char或bool)

    • 執(zhí)行浮點(diǎn)數(shù)運(yùn)算選用 double,這是因?yàn)閒loat通常精度不夠而且雙精度浮點(diǎn)數(shù)和單精度浮點(diǎn)數(shù)的計(jì)算代價(jià)相差無幾。事實(shí)上,對(duì)于某些機(jī)器來說,雙精度運(yùn)算甚至比單精度還快。long double提供的精度在一般情況下是沒有必要的,況且它帶來的運(yùn)行時(shí)消耗也不容忽視。(Note:浮點(diǎn)數(shù)直接上double)

    類型轉(zhuǎn)換

    對(duì)象的類型定義了對(duì)象能包含的數(shù)據(jù)和能參與的運(yùn)算,其中一種運(yùn)算被大多數(shù)類型支持,就是將對(duì)象從一種給定的類型轉(zhuǎn)換(convert)為另一種相關(guān)類型。

    當(dāng)在程序的某處我們使用了一種類型而其實(shí)對(duì)象應(yīng)該取另一種類型時(shí),程序會(huì)自動(dòng)進(jìn)行類型轉(zhuǎn)換。

    將來第4章會(huì)有更詳細(xì)的介紹類型轉(zhuǎn)換:

    此處,有必要說明當(dāng)給某種類型的對(duì)象強(qiáng)行賦了另一種類型的值時(shí),到底會(huì)發(fā)生什么。

    bool b = 42; // b is true /* 當(dāng)我們把一個(gè)非布爾類型的算術(shù)值賦給布爾類型時(shí),初始值為О則結(jié)果為false,否則結(jié)果為true。 */int i = b; // i has value 1 /* 當(dāng)我們把一個(gè)布爾值賦給非布爾類型時(shí),初始值為false 則結(jié)果為0,初始值為true則結(jié)果為1。 */i = 3.14; // i has value 3 /* 當(dāng)我們把一個(gè)浮點(diǎn)數(shù)賦給整數(shù)類型時(shí),進(jìn)行了近似處理。結(jié)果值將僅保留浮點(diǎn)數(shù)中小數(shù)點(diǎn)之前的部分(截?cái)嗳≌麛?shù)部分)。 */double pi = i; // pi has value 3.0 /* 當(dāng)我們把一個(gè)整數(shù)值賦給浮點(diǎn)類型時(shí),小數(shù)部分記為0。如果該整數(shù)所占的空間超過了浮點(diǎn)類型的容量,精度可能有損失。 */unsigned char c = -1; // assuming 8-bit chars, c has value 255 /* 當(dāng)我們賦給無符號(hào)類型一個(gè)超出它表示范圍的值時(shí),結(jié)果是初始值對(duì)無符號(hào)類型表示數(shù)值總數(shù)取模后的余數(shù)。例如,8比特大小的unsigned char可以表示0至255區(qū)間內(nèi)的值,如果我們賦了一個(gè)區(qū)間以外的值,則實(shí)際的結(jié)果是該值對(duì)256取模后所得的余數(shù)。因此,把-1賦給8比特大小的unsigned char所得的結(jié)果是255。Note:x mod y = x - y * ?x / y? (from:https://blog.csdn.net/weixin_43435790/article/details/83181319)-1 mod 256 = -1 - 256 * ?-1 / 256? = -1 - 256 * (-1) = 255個(gè)人認(rèn)為以底層知識(shí)更容易理解這次轉(zhuǎn)換 計(jì)算機(jī)保存數(shù)值都以補(bǔ)碼的形式保存。-1的補(bǔ)碼是11111111,但char的類型是無符號(hào)整形數(shù),編譯器就把11111111當(dāng)作無符號(hào)整形來輸出。11111111當(dāng)作正數(shù)時(shí)值就是255。 */signed char c2 = 256; // assuming 8-bit chars, the value of c2 is undefined /* 當(dāng)我們賦給帶符號(hào)類型一個(gè)超出它表示范圍的值時(shí),結(jié)果是未定義的(undefined)。此時(shí),程序可能繼續(xù)工作、可能崩潰,也可能生成垃圾數(shù)據(jù)。 */

    類型所能表示的值的范圍決定了轉(zhuǎn)換的過程。

    建議:避免無法預(yù)知和依賴于實(shí)現(xiàn)環(huán)境的行為

    無法預(yù)知的行為源于編譯器無須(有時(shí)是不能)檢測的錯(cuò)誤。即使代碼編譯通過了,如果程序執(zhí)行了一條未定義的表達(dá)式,仍有可能產(chǎn)生錯(cuò)誤。

    不幸的是,在某些情況和/或某些編譯器下,含有無法預(yù)知行為的程序也能正確執(zhí)行。但是我們卻無法保證同樣一個(gè)程序在別的編譯器下能正常工作,甚至已經(jīng)編譯通過的代碼再次執(zhí)行也可能會(huì)出錯(cuò)。此外,也不能認(rèn)為這樣的程序?qū)σ唤M輸入有效,對(duì)另一組輸入就一定有效。

    程序也應(yīng)該盡量避免依賴于實(shí)現(xiàn)環(huán)境的行為。如果我們把 int的尺寸看成是一個(gè)確定不變的已知值,那么這樣的程序就稱作不可移植的(nonportable)。當(dāng)程序移植到別的機(jī)器上后,依賴于實(shí)現(xiàn)環(huán)境的程序就可能發(fā)生錯(cuò)誤。要從過去的代碼中定位這類錯(cuò)誤可不是一件輕松愉快的工作。

    算術(shù)表達(dá)式里使用布爾值

    當(dāng)在程序的某處使用了一種算術(shù)類型的值而其實(shí)所需的是另一種類型的值時(shí),編譯器同樣會(huì)執(zhí)行上述的類型轉(zhuǎn)換。

    例如,如果我們使用了一個(gè)非布爾值作為條件,那么它會(huì)被自動(dòng)地轉(zhuǎn)換成布爾值,這一做法和把非布爾值賦給布爾變量時(shí)的操作完全一樣:

    int i = 42; if (i) // if條件的值將為truei = 0;

    如果i的值為0,則條件的值為false;i的所有其他取值(非0)都將使條件為true。

    以此類推,如果我們把一個(gè)布爾值用在算術(shù)表達(dá)式里,則它的取值非0即1,所以一般不宜在算術(shù)表達(dá)式里使用布爾值

    含有無符號(hào)類型的表達(dá)式(帶符號(hào)數(shù)會(huì)自動(dòng)地轉(zhuǎn)換成無符號(hào)數(shù))

    記住:無符號(hào)類型與有符號(hào)類型混合表達(dá)式中,帶符號(hào)數(shù)會(huì)自動(dòng)地轉(zhuǎn)換成無符號(hào)數(shù)

    盡管我們不會(huì)故意給無符號(hào)對(duì)象賦一個(gè)負(fù)值,卻可能(特別容易)寫出這么做的代碼。

    例一:

    例如,當(dāng)一個(gè)算術(shù)表達(dá)式中既有無符號(hào)數(shù)又有int 值時(shí),那個(gè)int值就會(huì)轉(zhuǎn)換成無符號(hào)數(shù)。把int轉(zhuǎn)換成無符號(hào)數(shù)的過程和把int直接賦給無符號(hào)變量一樣:

    unsigned u = 10; int i = -42; std::cout << i + i << std::endl; // prints -84 std::cout << u + i << std::endl; // if 32-bit ints, prints 4294967264 std::cout << i + u << std::endl; // also prints 4294967264
  • 在第一個(gè)輸出表達(dá)式里,兩個(gè)(負(fù))整數(shù)相加并得到了期望的結(jié)果。
  • 在第二、三個(gè)輸出表達(dá)式里,相加前首先把i的-42轉(zhuǎn)換成無符號(hào)數(shù)。把負(fù)數(shù)轉(zhuǎn)換成無符號(hào)數(shù)類似于直接給無符號(hào)數(shù)賦一個(gè)負(fù)值,結(jié)果等于這個(gè)負(fù)數(shù)加上無符號(hào)數(shù)的模。(有符號(hào)數(shù)與無符號(hào)數(shù)相加,先將有符號(hào)轉(zhuǎn)換成無符號(hào))。
  • 例二:

    當(dāng)從無符號(hào)數(shù)中減去一個(gè)值時(shí),不管這個(gè)值是不是無符號(hào)數(shù),我們都必須確保結(jié)果不能是一個(gè)負(fù)值:

    unsigned u1 = 42, u2 = 10; std::cout << u1 - u2 << std::endl; // ok: result is 32 std::cout << u2 - u1 << std::endl; // ok: but the result will wrap around, 4294967264

    例三:

    無符號(hào)數(shù)不會(huì)小于0這一事實(shí)同樣關(guān)系到循環(huán)的寫法。例如,寫一個(gè)循環(huán),通過控制變量遞減的方式把從10到0的數(shù)字降序輸出。這個(gè)循環(huán)可能類似于下面的形式:

    for (int i = 10; i >= 0; --i)std::cout << i << std::endl;

    可能你會(huì)覺得反正也不打算輸出負(fù)數(shù),可以用無符號(hào)數(shù)來重寫這個(gè)循環(huán)。

    然而,這個(gè)不經(jīng)意的改變卻意味著死循環(huán)

    // WRONG: u can never be less than 0; the condition will always succeed for (unsigned u = 10; u >= 0; --u)std::cout << u << std::endl;

    來看看當(dāng)u等于0時(shí)發(fā)生了什么,這次迭代輸出0,然后繼續(xù)執(zhí)行for語句里的表達(dá)式。表達(dá)式–u從u當(dāng)中減去1,得到的結(jié)果-1并不滿足無符號(hào)數(shù)的要求,此時(shí)像所有表示范圍之外的其他數(shù)字一樣,-1被自動(dòng)地轉(zhuǎn)換成一個(gè)合法的無符號(hào)數(shù)。假設(shè) int類型占32位,則當(dāng)u等于0時(shí),–u的結(jié)果將會(huì)是4294967295。

    一種解決的辦法是(不如改回int ╮(╯▽╰)╭),用while語句來代替for語句,因?yàn)榍罢咦屛覀兡軌蛟谳敵鲎兞恐?#xff08;而非之后)先減去1:

    unsigned u = 11; // start the loop one past the first element we want to print while (u > 0) {--u; // decrement first, so that the last iteration will print 0std::cout << u << std::endl; }

    改寫后的循環(huán)先執(zhí)行對(duì)循環(huán)控制變量減1的操作,這樣最后一次迭代時(shí),進(jìn)入循環(huán)的u值為1。此時(shí)將其減1,則這次迭代輸出的數(shù)就是0:下一次再檢驗(yàn)循環(huán)條件時(shí),u的值等于0而無法再進(jìn)入循環(huán)。

    因?yàn)槲覀円茸鰷p1的操作,所以初始化u的值應(yīng)該比要輸出的最大值大1。這里,u初始化為11,輸出的最大數(shù)是10。(也就預(yù)大一位)。

    提示:切勿混用帶符號(hào)類型和無符號(hào)類型

    如果表達(dá)式里既有帶符號(hào)類型又有無符號(hào)類型,當(dāng)帶符號(hào)類型取值為負(fù)時(shí)會(huì)出現(xiàn)異常結(jié)果,這是因?yàn)?strong>帶符號(hào)數(shù)會(huì)自動(dòng)地轉(zhuǎn)換成無符號(hào)數(shù)。

    例如,在一個(gè)形如a * b的式子中,如果a=-1,b=1,而且a和b都是int,則表達(dá)式的值顯然為-1。

    然而,如果a是int,而b是unsigned,則結(jié)果須視在當(dāng)前機(jī)器上int所占位數(shù)而定。在我們的環(huán)境里,結(jié)果是4294967295。

    字面值常量

    一個(gè)形如42的值被稱作字面值常量(literal)。每個(gè)字面值常量都對(duì)應(yīng)一種數(shù)據(jù)類型,字面值常量的形式和值決定了它的數(shù)據(jù)類型。

    整型和浮點(diǎn)型字面值

    我們可以將整型字面值寫作十進(jìn)制數(shù)、八進(jìn)制數(shù)或十六進(jìn)制數(shù)的形式。

    以0開頭的整數(shù)代表八進(jìn)制數(shù),以0x或0x開頭的代表十六進(jìn)制數(shù)。

    例如,我們能用下面的任意一種形式來表示數(shù)值20:

    • 20 十進(jìn)制
    • 024 八進(jìn)制
    • 0x14 十六進(jìn)制

    整型字面值具體的數(shù)據(jù)類型由它的值和符號(hào)決定。默認(rèn)情況下,十進(jìn)制字面值是帶符號(hào)數(shù),八進(jìn)制和十六進(jìn)制字面值既可能是帶符號(hào)的也可能是無符號(hào)的。十進(jìn)制字面值的類型是int、long和 long long 中尺寸最小的那個(gè)(例如,三者當(dāng)中最小是int),當(dāng)然前提是這種類型要能容納下當(dāng)前的值。(帶負(fù)號(hào)的八進(jìn)制、十六進(jìn)數(shù)少見)。

    八進(jìn)制和十六進(jìn)制字面值的類型是能容納其數(shù)值的int、unsigned int、long、unsigned long、long long和 unsigned long long中的尺寸最小者。如果一個(gè)字面值連與之關(guān)聯(lián)的最大的數(shù)據(jù)類型都放不下,將產(chǎn)生錯(cuò)誤。類型short沒有對(duì)應(yīng)的字面值。

    以U、L等后綴可以代表相應(yīng)的字面值類型。

    盡管整型字面值可以存儲(chǔ)在帶符號(hào)數(shù)據(jù)類型中,但嚴(yán)格來說,十進(jìn)制字面值不會(huì)是負(fù)數(shù)。如果我們使用了一個(gè)形如-42的負(fù)十進(jìn)制字面值,那個(gè)負(fù)號(hào)并不在字面值之內(nèi),它的作用僅僅是對(duì)字面值取負(fù)值而已。


    浮點(diǎn)型字面值表現(xiàn)為一個(gè)小數(shù)或以科學(xué)計(jì)數(shù)法表示的指數(shù),其中指數(shù)部分用E或e標(biāo)識(shí):

    • 3.14159
    • 3.14159E0
    • 0.
    • 0e0
    • .001

    默認(rèn)的,浮點(diǎn)型字面值是一個(gè)double,我們可以用后綴F等來表示其他浮點(diǎn)型。

    字符和字符串字面值

    由單引號(hào)括起來的一個(gè)字符稱為char型字面值,雙引號(hào)括起來的零個(gè)或多個(gè)字符則構(gòu)成字符串型字面值

    • ‘a(chǎn)’:字符字面值
    • "Hello world! ":字符串字面值

    字符串字面值的類型實(shí)際上是由常量字符構(gòu)成的數(shù)組(array)。編譯器在每個(gè)字符串的結(jié)尾處添加一個(gè)空字符(’\0’),因此,字符串字面值的實(shí)際長度要比它的內(nèi)容多1。

    例如,

    • 字面值’A‘表示的就是單獨(dú)的字符A
    • 字符串"A"則代表了一個(gè)字符的數(shù)組,該數(shù)組包含兩個(gè)字符:一個(gè)是字母A、另一個(gè)是空字符(’\0’)。

    如果兩個(gè)字符串字面值位置緊鄰且僅由空格、縮進(jìn)和換行符分隔,則它們實(shí)際上是一個(gè)整體。

    當(dāng)書寫的字符串字面值比較長,寫在一行里不太合適時(shí),就可以采取分開書寫的方式:

    //分多行書寫的字符串字面值 std::cout<< "a really, really long string literal ""that spans two lines" << std::endl; //與Java相比,不用+號(hào)

    轉(zhuǎn)義序列

    有兩類字符程序員不能直接使用:

  • 不可打印(nonprintable)的字符,如退格或其他控制字符,因?yàn)樗鼈儧]有可視的圖符;
  • 在C++語言中有特殊含義的字符(單引號(hào)、雙引號(hào)、問號(hào)、反斜線)。
  • 對(duì)于特殊含義的字符需要用到轉(zhuǎn)義序列(escape sequence),轉(zhuǎn)義序列均以反斜線作為開始,C++語言規(guī)定的轉(zhuǎn)義序列包括:

    • 換行符 \n

    • 縱向制表符 \v

    • 反斜線 \ \

    • 回車符 \r

    • 橫向制表符 \t

    • 退格符 \b

    • 問號(hào) ?

    • 進(jìn)紙符 \f

    • 報(bào)警(響鈴)符 \a

    • 雙引號(hào) \ "

    • 單引號(hào) \ ’

    在程序中,上述轉(zhuǎn)義序列被當(dāng)作一個(gè)字符使用:

    std::cout << '\n'; // prints a newline std::cout << "\tHi!\n"; // prints a tab followd by "Hi!" and a newline

    偏僻語法,不能一見知意,少用)我們也可以使用泛化的轉(zhuǎn)義序列,其形式是\x后緊跟1個(gè)或多個(gè)十六進(jìn)制數(shù)字,或者\(yùn)后緊跟1個(gè)、2個(gè)或3個(gè)八進(jìn)制數(shù)字,其中數(shù)字部分表示的是字符對(duì)應(yīng)的數(shù)值。假設(shè)使用的是Latin-1字符集,以下是一些示例:

    • \7 (bell)
    • \12 (newline)
    • \40 (blank)
    • \0 (null)
    • \115 (‘M’)
    • \x4d (‘M’)

    我們可以像使用普通字符那樣使用C++語言定義的轉(zhuǎn)義序列:

    std::cout << "Hi \x4dO\115!\n"; // prints Hi MOM! followed by a newline std::cout << '\115' << '\n'; // prints M followed by a newline

    注意,如果反斜線\后面跟著的八進(jìn)制數(shù)字超過3個(gè),只有前3個(gè)數(shù)字與\構(gòu)成轉(zhuǎn)義序列。

    例如,"\1234"表示2個(gè)字符,即八進(jìn)制數(shù)123對(duì)應(yīng)的字符以及字符4。

    相反,\x要用到后面跟著的所有數(shù)字,例如,"\x1234"表示一個(gè)16位的字符,該字符由這4個(gè)十六進(jìn)制數(shù)所對(duì)應(yīng)的比特唯一確定。

    因?yàn)榇蠖鄶?shù)機(jī)器的char型數(shù)據(jù)占8位,所以上面這個(gè)例子可能會(huì)報(bào)錯(cuò)。一般來說,超過8位的十六進(jìn)制字符都是與U等前綴作為開頭的擴(kuò)展字符集一起使用的。

    通過前后綴指定字面值的類型

    通過添加前綴和后綴,可以改變整型、浮點(diǎn)型和字符型字面值的默認(rèn)類型。

    L'a' // wide character literal, type is wchar_t u8"hi!" // utf-8 string literal (utf-8 encodes a Unicode character in 8 bits) 42ULL // unsigned integer literal, type is unsigned long long 1E-3F // single-precision floating-point literal, type is float 3.14159L // extended-precision floating-point literal, type is long double

    (不要用字母l作后綴)當(dāng)使用一個(gè)長整型字面值時(shí),請(qǐng)使用大寫字母L來標(biāo)記,因?yàn)樾懽帜竘和數(shù)字1太容易混淆了。

    通過添加前綴或后綴指定字面值的類型

    字符和字符串字面值

    前綴含義類型
    uUnicode 16字符char16_t
    UUnicode 32字符char32_t
    L寬字符wchar_t
    u8UTF8(僅用于字符串字面常量)char

    整型字面值

    后綴最小匹配類型
    u or Uunsigned
    l or Llong
    ll or LLlong long

    浮點(diǎn)數(shù)字面值

    后綴類型
    f or Ffloat
    l or Llong double

    對(duì)于一個(gè)整型字面值來說,我們能分別指定它是否帶符號(hào)以及占用多少空間。如果后綴中有u,則該字面值屬于無符號(hào)類型,也就是說,以u(píng)為后綴的十進(jìn)制數(shù)、八進(jìn)制數(shù)或十六進(jìn)制數(shù)都將從unsigned int、unsigned long和 unsigned long long中選擇能匹配的空間最小的一個(gè)作為其數(shù)據(jù)類型。

    如果后綴中有L,則字面值的類型至少是long; 如果后綴中有LL,則字面值的類型將是long long和unsigned long long 中的一種。顯然我們可以將u與工或LL合在一起使用。例如,以UL為后綴的字面值的數(shù)據(jù)類型將根據(jù)具體數(shù)值情況或者取unsigned long,或者取unsigned long long。

    布爾字面值和指針字面值

    true和false是布爾類型的字面值:

    bool test = false;

    nullptr是指針字面值。

    變量

    變量提供一個(gè)具名的、可供程序操作的存儲(chǔ)空間。

    C++中的每個(gè)變量都有其數(shù)據(jù)類型,數(shù)據(jù)類型決定著變量:

    • 所占內(nèi)存空間的大小和布局方式、(內(nèi)存大小)
    • 該空間能存儲(chǔ)的值的范圍,(范圍)
    • 以及變量能參與的運(yùn)算。(運(yùn)算)

    對(duì)C++程序員來說,“變量(variable)”和“對(duì)象(object)”一般可以互換使用。

    變量定義

    變量定義的基本形式是:首先是類型說明符(type specifier),隨后緊跟由一個(gè)或多個(gè)變量名組成的列表,其中變量名以逗號(hào)分隔,最后以分號(hào)結(jié)束。

    列表中每個(gè)變量名的類型都由類型說明符指定,定義時(shí)還可以為一個(gè)或多個(gè)變量賦初值:

    int sum = 0, value, // sum, value, and units_sold have type intunits_sold = 0; // sum and units_sold have initial value 0Sales_item item; // item has type Sales_item// string is a library type, representing a variable-length sequence of characters std::string book("0-201-78345-X"); // book initialized from string literal

    book的定義用到了庫類型std: :string,像iostream一樣,string 也是在命名空間std中定義的,我們將在第3章中對(duì)string類型做更詳細(xì)的介紹。眼下,只需了解string是一種表示可變長字符序列的數(shù)據(jù)類型即可。

    C++庫提供了幾種初始化string對(duì)象的方法,其中一種是把字面值拷貝給string對(duì)象,因此在上例中,book被初始化為0-201-78345-X。

    術(shù)語:何為對(duì)象?

    C++程序員們?cè)诤芏鄨龊隙紩?huì)使用對(duì)象(object)這個(gè)名詞。通常情況下,對(duì)象是指一塊能存儲(chǔ)數(shù)據(jù)并具有某種類型的內(nèi)存空間

    • 一些人僅在與有關(guān)的場景下才使用“對(duì)象”這個(gè)詞。
    • 另一些人則把已命名的對(duì)象和未命名的對(duì)象區(qū)分開來,他們把命名了的對(duì)象叫做變量。
    • 還有一些人把對(duì)象和值區(qū)分開來,其中對(duì)象指能被程序修改的數(shù)據(jù),而(value)指只讀的數(shù)據(jù)。

    本書遵循大多數(shù)人的習(xí)慣用法,即認(rèn)為對(duì)象是具有某種數(shù)據(jù)類型的內(nèi)存空間。我們?cè)谑褂脤?duì)象這個(gè)詞時(shí),并不嚴(yán)格區(qū)分是類還是內(nèi)置類型,也不區(qū)分是否命名或是否只讀。

    (記住:對(duì)象是具有某種數(shù)據(jù)類型的內(nèi)存空間

    初始值

    當(dāng)對(duì)象在創(chuàng)建時(shí)獲得了一個(gè)特定的值,我們說這個(gè)對(duì)象被初始化(initialized)了。

    用于初始化變量的值可以是任意復(fù)雜的表達(dá)式。

    當(dāng)一次定義了兩個(gè)或多個(gè)變量時(shí),對(duì)象的名字隨著定義也就馬上可以使用了。

    因此在同一條定義語句中,可以用先定義的變量值去初始化后定義的其他變量。

    // ok: price is defined and initialized before it is used to initialize discount double price = 109.99, discount = price * 0.16; // ok: call applyDiscount and use the return value to initialize salePrice double salePrice = applyDiscount(price, discount);

    在C++語言中,初始化是一個(gè)異常復(fù)雜的問題,我們也將反復(fù)討論這個(gè)問題。

    很多程序員對(duì)于用等號(hào)=來初始化變量的方式倍感困惑,這種方式容易讓人認(rèn)為初始化是賦值的一種。事實(shí)上在C++語言中,初始化和賦值是兩個(gè)完全不同的操作。然而在很多編程語言中二者的區(qū)別幾乎可以忽略不計(jì),即使在C++語言中有時(shí)這種區(qū)別也無關(guān)緊要,所以人們特別容易把二者混為一談。

    需要強(qiáng)調(diào)的是,這個(gè)概念至關(guān)重要,我們也將在后面不止一次提及這一點(diǎn)。

    初始化不是賦值,初始化的含義是創(chuàng)建變量時(shí)賦予其一個(gè)初始值,而賦值的含義是把對(duì)象的當(dāng)前值擦除,而以一個(gè)新值來替代。

    (Note: 初始化和賦值是兩碼事,即使它們很相似。當(dāng)某一變量首次用=號(hào)的就是初始化,其他地方用=號(hào)的就是賦值

    列表初始化

    C++語言定義了初始化的好幾種不同形式,這也是初始化問題復(fù)雜性的一個(gè)體現(xiàn)。例如,要想定義一個(gè)名為units_sold的int變量并初始化為0,以下的4條語句都可以做到這一點(diǎn):

    int units_sold = 0; int units_sold = {0}; int units_sold{0}; int units_sold(0);

    作為C++11新標(biāo)準(zhǔn)的一部分,用花括號(hào)來初始化變量得到了全面應(yīng)用,而在此之前,這種初始化的形式僅在某些受限的場合下才能使用。出于3.3.1節(jié)將要介紹的原因,這種初始化的形式被稱為列表初始化(list initialization)。現(xiàn)在,無論是初始化對(duì)象還是某些時(shí)候?yàn)閷?duì)象賦新值,都可以使用這樣一組由花括號(hào)括起來的初始值了。

    當(dāng)用于內(nèi)置類型的變量時(shí),這種初始化形式有一個(gè)重要特點(diǎn):如果我們使用列表初始化且初始值存在丟失信息的風(fēng)險(xiǎn),則編譯器將報(bào)錯(cuò)

    long double ld = 3.1415926536; int a{ld}, b = {ld}; // error: narrowing conversion required int c(ld), d = ld; // ok: but value will be truncated

    使用long double的值初始化int變量時(shí)可能丟失數(shù)據(jù),所以編譯器拒絕了a和b的初始化請(qǐng)求。

    其中,至少ld的小數(shù)部分會(huì)丟失掉,而且int也可能存不下ld的整數(shù)部分。

    (Note: 列表初始化變量轉(zhuǎn)型有數(shù)據(jù)丟失報(bào)錯(cuò)功能???)

    默認(rèn)初始化

    如果定義變量時(shí)沒有指定初值,則變量被默認(rèn)初始化(default initialized),此時(shí)變量被賦予了“默認(rèn)值”。默認(rèn)值到底是什么由變量類型決定,同時(shí)定義變量的位置也會(huì)對(duì)此有影響。

    如果是內(nèi)置類型的變量未被顯式初始化,它的值由定義的位置決定。定義于任何函數(shù)體之外的變量被初始化為0。

    • 一種例外情況是,定義在函數(shù)體內(nèi)部的內(nèi)置類型變量將不被初始化(uninitialized)。

    • 一個(gè)未被初始化的內(nèi)置類型變量的值是未定義的,如果試圖拷貝或以其他形式訪問此類值將引發(fā)錯(cuò)誤。

    每個(gè)類各自決定其初始化對(duì)象的方式。而且,是否允許不經(jīng)初始化就定義對(duì)象也由類自己決定。如果類允許這種行為,它將決定對(duì)象的初始值到底是什么。

    絕大多數(shù)類都支持無須顯式初始化而定義對(duì)象,這樣的類提供了一個(gè)合適的默認(rèn)值。例如,String類規(guī)定如果沒有指定初值則生成一個(gè)空串:

    std::string empty;//empty非顯式地初始化為一個(gè)空串 Sales_item item;//被默認(rèn)初始化的sales_item對(duì)象

    一些類要求每個(gè)對(duì)象都顯式初始化,此時(shí)如果創(chuàng)建了一個(gè)該類的對(duì)象而未對(duì)其做明確的初始化操作,將引發(fā)錯(cuò)誤。

    定義于函數(shù)體內(nèi)的內(nèi)置類型的對(duì)象如果沒有初始化,則其值未定義。類的對(duì)象如果沒有顯式地初始化,則其值由類確定。

    提示:未初始化變量引發(fā)運(yùn)行時(shí)故障

    未初始化的變量含有一個(gè)不確定的值,使用未初始化變量的值是一種錯(cuò)誤的編程行為并且很難調(diào)試。盡管大多數(shù)編譯器都能對(duì)一部分使用未初始化變量的行為提出警告,但嚴(yán)格來說,編譯器并未被要求檢查此類錯(cuò)誤。

    使用未初始化的變量將帶來無法預(yù)計(jì)的后果。有時(shí)我們足夠幸運(yùn),一訪問此類對(duì)象程序就崩潰并報(bào)錯(cuò),此時(shí)只要找到崩潰的位置就很容易發(fā)現(xiàn)變量沒被初始化的問題。另外一些時(shí)候,程序會(huì)一直執(zhí)行完并產(chǎn)生錯(cuò)誤的結(jié)果。更糟糕的情況是,程序結(jié)果時(shí)對(duì)時(shí)錯(cuò)、無法把握。而且,往無關(guān)的位置添加代碼還會(huì)導(dǎo)致我們誤以為程序?qū)α?#xff0c;其實(shí)結(jié)果仍舊有錯(cuò)。

    建議初始化每一個(gè)內(nèi)置類型的變量。雖然并非必須這么做,但如果我們不能確保初始化后程序安全,那么這么做不失為一種簡單可靠的方法。

    (Note: 創(chuàng)建一個(gè)變量都初始化吧。保安全)

    變量聲明和定義的關(guān)系

    為了允許把程序拆分成多個(gè)邏輯部分來編寫,C++語言支持分離式編譯(separate compilation)機(jī)制,該機(jī)制允許將程序分割為若干個(gè)文件,每個(gè)文件可被獨(dú)立編譯。

    如果將程序分為多個(gè)文件,則需要有在文件間共享代碼的方法。例如,一個(gè)文件的代碼可能需要使用另一個(gè)文件中定義的變量。一個(gè)實(shí)際的例子是std: :cout和std::cin,它們定義于標(biāo)準(zhǔn)庫,卻能被我們寫的程序使用。

    為了支持分離式編譯,C++語言將聲明和定義區(qū)分開來

    • 聲明(declaration)使得名字為程序所知,一個(gè)文件如果想使用別處定義的名字則必須包含對(duì)那個(gè)名字的聲明。
    • 定義(definition)負(fù)責(zé)創(chuàng)建與名字關(guān)聯(lián)的實(shí)體。

    變量聲明規(guī)定了變量的類型和名字,在這一點(diǎn)上定義與之相同。但是除此之外,定義還申請(qǐng)存儲(chǔ)空間,也可能會(huì)為變量賦一個(gè)初始值。

    如果想聲明一個(gè)變量而非定義它,就在變量名前添加關(guān)鍵字extern,而且不要顯式地初始化變量:

    extern int i; // declares but does not define i int j; // declares and defines j

    任何包含了顯式初始化的聲明即成為定義。我們能給由extern關(guān)鍵字標(biāo)記的變量賦一個(gè)初始值,但是這么做也就抵消了extern的作用。extern語句如果包含初始值就不再是聲明,而變成定義了

    extern double pi = 3.1416; //定義

    在函數(shù)體內(nèi)部,如果試圖初始化一個(gè)由extern關(guān)鍵字標(biāo)記的變量,將引發(fā)錯(cuò)誤。

    聲明和定義的區(qū)別看起來也許微不足道,但實(shí)際上卻非常重要。(重中之重)如果要在多個(gè)文件中使用同一個(gè)變量,就必須將聲明和定義分離。此時(shí),變量的定義必須出現(xiàn)在且只能出現(xiàn)在一個(gè)文件中,而其他用到該變量的文件必須對(duì)其進(jìn)行聲明,卻絕對(duì)不能重復(fù)定義。

    (Note: 變量能且只能被定義一次,但是可以被多次聲明(只為使用它)。)

    關(guān)于C++語言對(duì)分離式編譯的支持在將來做更詳細(xì)介紹。

    關(guān)鍵概念:靜態(tài)類型

    C++是一種靜態(tài)類型(statically typed)語言,其含義是在編譯階段檢查類型。其中,檢查類型的過程稱為類型檢查(type checking)。

    對(duì)象的類型決定了對(duì)象所能參與的運(yùn)算。在C++語言中,編譯器負(fù)責(zé)檢查數(shù)據(jù)類型是否支持要執(zhí)行的運(yùn)算,如果試圖執(zhí)行類型不支持的運(yùn)算,編譯器將報(bào)錯(cuò)并且不會(huì)生成可執(zhí)行文件。

    程序越復(fù)雜,靜態(tài)類型檢查越有助于發(fā)現(xiàn)問題。然而,前提是編譯器必須知道每一個(gè)實(shí)體對(duì)象的類型,這就要求我們?cè)谑褂媚硞€(gè)變量之前必須聲明其類型。

    標(biāo)識(shí)符

    C++的標(biāo)識(shí)符(identifier)由字母、數(shù)字和下畫線組成,其中必須以字母或下畫線開頭。標(biāo)識(shí)符的長度沒有限制,但是對(duì)大小寫字母敏感:

    // defines four different int variables int somename, someName, SomeName, SOMENAME;

    下面兩表所示,C++語言保留了一些名字供語言本身使用,這些名字不能被用作標(biāo)識(shí)符。

    同時(shí),C++也為標(biāo)準(zhǔn)庫保留了一些名字。用戶自定義的標(biāo)識(shí)符中不能連續(xù)出現(xiàn)兩個(gè)下畫線,也不能以下畫線緊連大寫字母開頭。此外,定義在函數(shù)體外的標(biāo)識(shí)符不能以下畫線開頭。

    C++關(guān)鍵字

    -----
    alignascontinuefriendregistertrue
    alignofdecltypegotoreinterpret_casttry
    asmdefaultifreturntypedef
    autodeleteinlineshorttypeid
    booldointsignedtypename
    breakdoublelongsizeofunion
    casedynamic_castmutablestaticunsigned
    catchelsenamespacestatic_assertusing
    charenumnewstatic_castvirtual
    char16_texplicitnoexceptstructvoid
    char32_texportnullptrswitchvolatile
    classexternoperatortemplatewchar_t
    constfalseprivatethiswhile
    constexprfloatprotectedthread_local
    const_castforpublicthrow

    C++操作符替代名

    ---
    andcomplor_eq
    and_eqnotxor
    bitandnot_eqxor_eq
    bitoror

    變量命名規(guī)范

    變量命名有許多約定俗成的規(guī)范,下面的這些規(guī)范能有效提高程序的可讀性:

    • 標(biāo)識(shí)符要能體現(xiàn)實(shí)際含義。
    • 變量名一般用小寫字母,如 index,不要使用Index或INDEX。
    • 用戶自定義的類名一般以大寫字母開頭,如 Sales_item。
    • 如果標(biāo)識(shí)符由多個(gè)單詞組成,則單詞間應(yīng)有明顯區(qū)分,如 student_loan或studentLoan,不要使用studentloan。

    對(duì)于命名規(guī)范來說,若能堅(jiān)持,必將有效

    (Note:使用Java駝峰命名法吧)

    名字的作用域

    不論是在程序的什么位置,使用到的每個(gè)名字都會(huì)指向一個(gè)特定的實(shí)體:變量、函數(shù)、類型等。然而,同一個(gè)名字如果出現(xiàn)在程序的不同位置,也可能指向的是不同實(shí)體。

    作用域(scope)是程序的一部分,在其中名字有其特定的含義。C++語言中大多數(shù)作用域都以花括號(hào)分隔。

    同一個(gè)名字在不同的作用域中可能指向不同的實(shí)體。名字的有效區(qū)域始于名字的聲明語句,以聲明語句所在的作用域末端為結(jié)束。

    #include <iostream> int main() {int sum = 0;// sum values from 1 through 10 inclusivefor (int val = 1; val <= 10; ++val)sum += val;// equivalent to sum = sum + valstd::cout << "Sum of 1 to 10 inclusive is "<< sum << std::endl;return 0; }

    這段程序定義了3個(gè)名字: main、sum和val,同時(shí)使用了命名空間名字std,該空間提供了2個(gè)名字cout和 cin供程序使用。

    名字main定義于所有花括號(hào)之外,它和其他大多數(shù)定義在函數(shù)體之外的名字一樣擁有全局作用域(global scope)。一旦聲明之后,全局作用域內(nèi)的名字在整個(gè)程序的范圍內(nèi)都可使用。

    名字sum定義于main函數(shù)所限定的作用域之內(nèi),從聲明sum開始直到main函數(shù)結(jié)束為止都可以訪問它,但是出了main函數(shù)所在的塊就無法訪問了,因此說變量sum擁有塊作用域(block scope)。名字val定義于 for語句內(nèi),在for語句之內(nèi)可以訪問val,但是在main函數(shù)的其他部分就不能訪問它了。

    建議:當(dāng)你第一次使用變量時(shí)再定義它

    一般來說,在對(duì)象第一次被使用的地方附近定義它是一種好的選擇,因?yàn)檫@樣做有助于更容易地找到變量的定義。更重要的是,當(dāng)變量的定義與它第一次被使用的地方很近時(shí),我們也會(huì)賦給它一個(gè)比較合理的初始值。

    嵌套的作用域

    作用域能彼此包含,被包含(或者說被嵌套)的作用域稱為內(nèi)層作用域(inner scope),包含著別的作用域的作用域稱為外層作用域(outer scope)。

    作用域中一旦聲明了某個(gè)名字,它所嵌套著的所有作用域中都能訪問該名字。同時(shí),允許在內(nèi)層作用域中重新定義外層作用域已有的名字:

    #include <iostream> // Program for illustration purposes only: It is bad style for a function // to use a global variable and also define a local variable with the same name int reused = 42; // reused has global scope int main() {int unique = 0; // unique has block scope// output #1: uses global reused; prints 42 0std::cout << reused << " " << unique << std::endl;int reused = 0;// new, local object named reused hides global reused// output #2: uses local reused; prints 0 0std::cout << reused << " " << unique << std::endl;// output #3: explicitly requests the global reused; prints 42 0std::cout << ::reused << " " << unique << std::endl;return 0; }
    • 輸出#1出現(xiàn)在局部變量 reused定義之前,因此這條語句使用全局作用域中定義的名字reused,輸出42 0。

    • 輸出#2發(fā)生在局部變量reused定義之后,此時(shí)局部變量reused正在作用域內(nèi)(in scope),因此第二條輸出語句使用的是局部變量reused而非全局變量,輸出0 0。

    • 輸出#3使用作用域操作符來覆蓋默認(rèn)的作用域規(guī)則,因?yàn)槿肿饔糜虮旧聿]有名字,所以當(dāng)作用域操作符的左側(cè)為空時(shí),向全局作用域發(fā)出請(qǐng)求獲取作用域操作符右側(cè)名字對(duì)應(yīng)的變量。結(jié)果是,第三條輸出語句使用全局變量reused,輸出42 0。

    如果函數(shù)有可能用到某全局變量,則不宜再定義一個(gè)同名的局部變量。(各個(gè)變量盡量在可控范圍有獨(dú)一名字)

    復(fù)合類型

    復(fù)合類型( compound type)是指基于其他類型定義的類型。C++語言有幾種復(fù)合類型,本章將介紹其中的兩種:引用和指針。

    與我們已經(jīng)掌握的變量聲明相比,定義復(fù)合類型的變量要復(fù)雜很多。

    上一節(jié)提到,一條簡單的聲明語句由一個(gè)數(shù)據(jù)類型和緊隨其后的一個(gè)變量名列表組成。

    其實(shí)更通用的描述是,一條聲明語句由一個(gè)基本數(shù)據(jù)類型(base type)和緊隨其后的一個(gè)聲明符(declarator)列表組成。每個(gè)聲明符命名了一個(gè)變量并指定該變量為與基本數(shù)據(jù)類型有關(guān)的某種類型。

    (Note: ,1條聲明語句=1個(gè)基本數(shù)據(jù)類型+1個(gè)聲明符)

    目前為止,我們所接觸的聲明語句中,聲明符其實(shí)就是變量名,此時(shí)變量的類型也就是聲明的基本數(shù)據(jù)類型。其實(shí)還可能有更復(fù)雜的聲明符,它基于基本數(shù)據(jù)類型得到更復(fù)雜的類型,并把它指定給變量。

    (系好安全帶吧,少年!)

    引用

    C++11中新增了一種引用:所謂的“右值引用(rvalue reference)”,之后會(huì)做更詳細(xì)的介紹。這種引用主要用于內(nèi)置類。

    嚴(yán)格來說,當(dāng)我們使用術(shù)語“引用(reference)”時(shí),指的其實(shí)是“左值引用(Ivalue reference)”。


    引用(reference)為對(duì)象起了另外一個(gè)名字,引用類型引用(refers to)另外一種類型

    通過將聲明符寫成&d的形式來定義引用類型,其中d是聲明的變量名:

    int ival = 1024; int &refVal = ival; // refVal refers to (is another name for) ival int &refVal2; // error: a reference must be initialized

    一般在初始化變量時(shí),初始值會(huì)被拷貝到新建的對(duì)象中。然而定義引用時(shí),程序把引用和它的初始值綁定(bind)在一起,而不是將初始值拷貝給引用。一旦初始化完成,引用將和它的初始值對(duì)象一直綁定在一起。因?yàn)闊o法令引用重新綁定到另外一個(gè)對(duì)象,因此引用必須初始化。(引用一次性的)

    引用即別名

    引用并非對(duì)象,相反的,它只是為一個(gè)已經(jīng)存在的對(duì)象所起的另外一個(gè)名字。

    對(duì)象是具有某種數(shù)據(jù)類型的內(nèi)存空間)(引用只是對(duì)象的別名)

    定義了一個(gè)引用之后,對(duì)其進(jìn)行的所有操作都是在與之綁定的對(duì)象上進(jìn)行的:

    refVal = 2; // assigns 2 to the object to which refVal refers, i.e., to ival int ii = refVal; // same as ii = ival

    為引用賦值,實(shí)際上是把值賦給了與引用綁定的對(duì)象。獲取引用的值,實(shí)際上是獲取了與引用綁定的對(duì)象的值。同理,以引用作為初始值,實(shí)際上是以與引用綁定的對(duì)象作為初始值:

    // ok: refVal3 is bound to the object to which refVal is bound, i.e., to ival int &refVal3 = refVal; // initializes i from the value in the object to which refVal is bound int i = refVal; // ok: initializes i to the same value as ival

    因?yàn)橐帽旧聿皇且粋€(gè)對(duì)象,所以不能定義引用的引用。

    引用的定義

    允許在一條語句中定義多個(gè)引用,其中每個(gè)引用標(biāo)識(shí)符都必須以符號(hào)&開頭:

    int i = 1024, i2 = 2048; // i and i2 are both ints int &r = i, r2 = i2; // r is a reference bound to i; r2 is an int int i3 = 1024, &ri = i3; // i3 is an int; ri is a reference bound to i3 int &r3 = i3, &r4 = i2; // both r3 and r4 are references

    所有引用的類型都要和與之綁定的對(duì)象嚴(yán)格匹配。而且,引用只能綁定在對(duì)象上,而不能與字面值或某個(gè)表達(dá)式的計(jì)算結(jié)果綁定在一起:

    int &refVal4 = 10; // error: initializer must be an object double dval = 3.14; int &refVal5 = dval; // error: initializer must be an int object

    (Note: 引用(reference)為對(duì)象起了另外一個(gè)名字(起別名),引用類型引用(refers to)另外一種類型。

    指針

    指針(pointer)是“指向(point to)”另外一種類型的復(fù)合類型。與引用類似,指針也實(shí)現(xiàn)了對(duì)其他對(duì)象的間接訪問。

    然而指針與引用相比又有很多不同點(diǎn)

  • 指針本身就是一個(gè)對(duì)象,允許對(duì)指針賦值和拷貝,而且在指針的生命周期內(nèi)它可以先后指向幾個(gè)不同的對(duì)象。(不像引用那樣一次性)
  • 指針無須在定義時(shí)賦初值。和其他內(nèi)置類型一樣,在塊作用域內(nèi)定義的指針如果沒有被初始化,也將擁有一個(gè)不確定的值。
  • 指針通常難以理解,即使是有經(jīng)驗(yàn)的程序員也常常因?yàn)檎{(diào)試指針引發(fā)的錯(cuò)誤而被備受折磨。

    定義指針類型的方法將聲明符寫成*d的形式,其中d是變量名。如果在一條語句中定義了幾個(gè)指針變量,每個(gè)變量前面都必須有符號(hào)*:

    int *ip1, *ip2; // both ip1 and ip2 are pointers to int double dp, *dp2; // dp2 is a pointer to double; dp is a double

    獲取對(duì)象的地址

    指針存放某個(gè)對(duì)象的地址,要想獲取該地址,需要使用取地址符 address-of operator(操作符&):

    int ival = 42; int *p = &ival; // p holds the address of ival; p is a pointer to ival

    第二條語句把p定義為一個(gè)指向 int 的指針,隨后初始化p令其指向名為 ival的int對(duì)象。

    因?yàn)橐貌皇菍?duì)象,沒有實(shí)際地址,所以不能定義指向引用的指針。

    (Note: &取地址符 跟 引用&號(hào)是兩碼事,注意區(qū)分)

    其他所有指針的類型都要和它所指向的對(duì)象嚴(yán)格匹配:(有兩種例外情況,日后再介紹)

    對(duì)象是具有某種數(shù)據(jù)類型的內(nèi)存空間

    double dval; double *pd = &dval; // ok: initializer is the address of a double double *pd2 = pd; // ok: initializer is a pointer to double//類型不同,不能亂指 int *pi = pd; // error: types of pi and pd differ pi = &dval; // error: assigning the address of a double to a pointer to int

    因?yàn)樵诼暶髡Z句中指針的類型實(shí)際上被用于指定它所指向?qū)ο蟮念愋?#xff0c;所以二者必須匹配。如果指針指向了一個(gè)其他類型的對(duì)象,對(duì)該對(duì)象的操作將發(fā)生錯(cuò)誤。

    指針值

    指針的值(即地址)應(yīng)屬下列4種狀態(tài)之一:

  • 指向一個(gè)對(duì)象。
  • 指向緊鄰對(duì)象所占空間的下一個(gè)位置。(用在數(shù)組)
  • 空指針,意味著指針沒有指向任何對(duì)象。
  • 無效指針,也就是上述情況之外的其他值。
  • 試圖拷貝或以其他方式訪問無效指針的值都將引發(fā)錯(cuò)誤。編譯器并不負(fù)責(zé)檢查此類錯(cuò)誤,這一點(diǎn)和試圖使用未經(jīng)初始化的變量是一樣的。訪問無效指針的后果無法預(yù)計(jì),因此程序員必須清楚任意給定的指針是否有效。

    盡管第2種和第3種形式的指針是有效的,但其使用同樣受到限制。顯然這些指針沒有指向任何具體對(duì)象,所以試圖訪問此類指針(假定的)對(duì)象的行為不被允許。如果這樣做了,后果也無法預(yù)計(jì)。

    利用指針訪問對(duì)象

    如果指針指向了一個(gè)對(duì)象,則允許使用解引用符 dereference operator(操作符*)來訪問該對(duì)象:

    int ival = 42; int *p = &ival; // p holds the address of ival; p is a pointer to ival cout << *p; // * yields the object to which p points; prints 42

    (Note: * & 位置不同傻傻分不清楚。)

    一條聲明語句由一個(gè)基本數(shù)據(jù)類型(base type)和緊隨其后的一個(gè)聲明符(declarator)列表組成

    int a = 1; int &aa = a;//這里&為引用聲明符(這名我自起的)int ival = 42;jie int *p = &ival;//這里*為指針聲明符(這名我自起的),&為取地址符 cout << *p;//這里*為解引用符

    對(duì)指針解引用會(huì)得出所指的對(duì)象,因此如果給解引用的結(jié)果賦值,實(shí)際上也就是給指針?biāo)傅膶?duì)象賦值:

    *p = 0; // * yields the object; we assign a new value to ival through p,這里*是解引用符 cout << *p; // prints 0

    如上述程序所示,為*p賦值實(shí)際上是為p所指的對(duì)象賦值。

    解引用操作僅適用于那些確實(shí)指向了某個(gè)對(duì)象的有效指針。

    關(guān)鍵概念:一符多義(& 與 *)

    像&和*這樣的符號(hào),既能用作表達(dá)式里的運(yùn)算符(&按位與符取址符乘法符或解引用符*),也能作為聲明的一部分出現(xiàn)(&引用聲明符,*指針聲明符),符號(hào)的上下文決定了符號(hào)的意義:

    int i = 42; int &r = i; //這里&為引用聲明符, & follows a type and is part of a declaration; r is a reference int *p; //這里*為指針聲明符, * follows a type and is part of a declaration; p is a pointer p = &i; // 這里&為取值符, & is used in an expression as the address-of operator *p = i; // 這里*為解引用符 * is used in an expression as the dereference operator int &r2 = *p; // & is part of the declaration; * is the dereference operator
    • 在聲明語句中,&和*用于組成復(fù)合類型(我個(gè)人將它們分別稱為引用聲明符指針聲明符)。

    • 在表達(dá)式中,&和*又轉(zhuǎn)變成運(yùn)算符(操作數(shù)為1個(gè)時(shí),分別稱為取值符解引用符。操作數(shù)為2個(gè)時(shí),分別稱為按位與符乘法符)。

    在不同場景下出現(xiàn)的雖然是同一個(gè)符號(hào),但是由于含義截然不同,所以我們完全可以把它當(dāng)作不同的符號(hào)來看待。

    空指針

    空指針(null pointer)不指向任何對(duì)象,在試圖使用一個(gè)指針之前代碼可以首先檢查它是否為空。以下列出幾個(gè)生成空指針的方法:

    int *p1 = nullptr; // equivalent to int *p1 = 0; int *p2 = 0; // directly initializes p2 from the literal constant 0 // must #include cstdlib int *p3 = NULL; // equivalent to int *p3 = 0;

    得到空指針最直接的辦法就是用字面值nullptr來初始化指針,這也是C++11新標(biāo)準(zhǔn)剛剛引入的一種方法。nullptr是一種特殊類型的字面值,它可以被轉(zhuǎn)換成任意其他的指針類型。另一種辦法就如對(duì)p2的定義一樣,也可以通過將指針初始化為字面值0來生成空指針。

    過去的程序還會(huì)用到一個(gè)名為NULL的預(yù)處理變量(preprocessor variable)來給指針賦值,這個(gè)變量在頭文件cstdlib中定義,它的值就是0。

    稍微介紹一點(diǎn)關(guān)于預(yù)處理器的知識(shí),現(xiàn)在只要知道預(yù)處理器是運(yùn)行于編譯過程之前的一段程序就可以了。預(yù)處理變量不屬于命名空間std,它由預(yù)處理器負(fù)責(zé)管理,因此我們可以直接使用預(yù)處理變量而無須在前面加上std: :。

    當(dāng)用到一個(gè)預(yù)處理變量時(shí),預(yù)處理器會(huì)自動(dòng)地將它替換為實(shí)際值,因此用NULL初始化指針和用0初始化指針是一樣的。在新標(biāo)準(zhǔn)下,現(xiàn)在的C++程序最好使用nullptr,同時(shí)盡量避免使用NULL

    把int變量直接賦給指針是錯(cuò)誤的操作,即使int變量的值恰好等于0也不行。

    int zero = 0; pi = zero; // error: cannot assign an int to a pointer

    建議:初始化所有指針

    使用未經(jīng)初始化的指針是引發(fā)運(yùn)行時(shí)錯(cuò)誤的一大原因。(像Java的NullPointerException)

    和其他變量一樣,訪問未經(jīng)初始化的指針?biāo)l(fā)的后果也是無法預(yù)計(jì)的。通常這一行為將造成程序崩潰,而且一旦崩潰,要想定位到出錯(cuò)位置將是特別棘手的問題。

    在大多數(shù)編譯器環(huán)境下,如果使用了未經(jīng)初始化的指針,則該指針?biāo)純?nèi)存空間的當(dāng)前內(nèi)容將被看作一個(gè)地址值。訪問該指針,相當(dāng)于去訪問一個(gè)本不存在的位置上的本不存在的對(duì)象。糟糕的是,如果指針?biāo)純?nèi)存空間中恰好有內(nèi)容,而這些內(nèi)容又被當(dāng)作了某個(gè)地址,我們就很難分清它到底是合法的還是非法的了。(指針未初始化會(huì)出現(xiàn)的糟糕狀況)

    因此建議初始化所有的指針,并且在可能的情況下,盡量等定義了對(duì)象之后再定義指向它的指針。如果實(shí)在不清楚指針應(yīng)該指向何處,就把它初始化為nullptr或者0,這樣程序就能檢測并知道它沒有指向任何具體的對(duì)象了。

    賦值和指針

    指針和引用都能提供對(duì)其他對(duì)象的間接訪問,然而在具體實(shí)現(xiàn)細(xì)節(jié)上二者有很大不同:

  • 其中最重要的一點(diǎn)就是引用本身并非一個(gè)對(duì)象。一旦定義了引用,就無法令其再綁定到另外的對(duì)象,之后每次使用這個(gè)引用都是訪問它最初綁定的那個(gè)對(duì)象。
  • 指針和它存放的地址之間就沒有這種限制了。和其他任何變量(只要不是引用)一樣,給指針賦值就是令它存放一個(gè)新的地址,從而指向一個(gè)新的對(duì)象:
  • int i = 42; int *pi = 0; // pi is initialized but addresses no object int *pi2 = &i; // pi2 initialized to hold the address of i int *pi3; // if pi3 is defined inside a block, pi3 is uninitialized pi3 = pi2; // pi3 and pi2 address the same object, e.g., i pi2 = 0; // pi2 now addresses no object

    有時(shí)候要想搞清楚一條賦值語句到底是改變了指針的值還是改變了指針?biāo)笇?duì)象的值不太容易,最好的辦法就是記住賦值永遠(yuǎn)改變的是等號(hào)左側(cè)的對(duì)象。當(dāng)寫出如下語句時(shí),

    pi = &ival; // value in pi is changed; pi now points to ival

    意思是為 pi賦一個(gè)新的值,也就是改變了那個(gè)存放在pi內(nèi)的地址值。相反的,如果寫出如下語句,

    *pi = 0; // value in ival is changed; pi is unchanged

    則*pi(也就是指針pi指向的那個(gè)對(duì)象)發(fā)生改變。

    其他指針操作

    只要指針擁有一個(gè)合法值,就能將它用在條件表達(dá)式中。和采用算術(shù)值作為條件遵循的規(guī)則類似,如果指針的值是0,條件取false:

    int ival = 1024; int *pi = 0; // pi is a valid, null pointer int *pi2 = &ival; // pi2 is a valid pointer that holds the address of ival if (pi) // pi has value 0, so condition evaluates as false// ... if (pi2) // pi2 points to ival, so it is not 0; the condition evaluates as true// ...

    任何非0指針對(duì)應(yīng)的條件值都是true。

    對(duì)于兩個(gè)類型相同的合法指針,可以用相等操作符(=)或不相等操作符(!=)來比較它們,比較的結(jié)果是布爾類型。如果兩個(gè)指針存放的地址值相同,則它們相等;反之它們不相等。

    這里兩個(gè)指針存放的地址值相同(兩個(gè)指針相等)有三種可能:

  • 它們都為空、
  • 它們都指向同一個(gè)對(duì)象,
  • 它們都指向了同一個(gè)對(duì)象的下一地址(???這情況不太懂)
  • 需要注意的是,一個(gè)指針指向某對(duì)象,同時(shí)另一個(gè)指針指向另外對(duì)象的下一地址,此時(shí)也有可能出現(xiàn)這兩個(gè)指針值相同的情況,即指針相等。

    因?yàn)樯鲜霾僮饕玫街羔樀闹?#xff0c;所以不論是作為條件出現(xiàn)還是參與比較運(yùn)算(再數(shù)組中用),都必須使用合法指針,使用非法指針作為條件或進(jìn)行比較都會(huì)引發(fā)不可預(yù)計(jì)的后果。

    void* 指針

    void*是一種特殊的指針類型,可用于存放任意對(duì)象的地址。一個(gè)void*指針存放著一個(gè)地址,這一點(diǎn)和其他指針類似。

    不同的是,我們對(duì)該地址中到底是個(gè)什么類型的對(duì)象并不了解:

    double obj = 3.14, *pd = &obj; // ok: void* can hold the address value of any data pointer type void *pv = &obj; // obj can be an object of any type pv = pd; // pv can hold a pointer to any type

    利用void*指針能做的事兒比較有限:

    • 拿它和別的指針比較、
    • 作為函數(shù)的輸入或輸出,
    • 賦給另外一個(gè)void*指針。

    不能直接操作void*指針?biāo)傅膶?duì)象,因?yàn)槲覀儾⒉恢肋@個(gè)對(duì)象到底是什么類型,也就無法確定能在這個(gè)對(duì)象上做哪些操作。

    概括說來,以void*的視角來看內(nèi)存空間也就僅僅是內(nèi)存空間,沒辦法訪問內(nèi)存空間中所存的對(duì)象,不過,是有獲取void*指針?biāo)娴刂返姆椒?#xff0c;日后介紹。

    理解復(fù)合類型的聲明

    如前所述,變量的定義包括一個(gè)基本數(shù)據(jù)類型(base type)和一組聲明符。在同一條定義語句中,雖然基本數(shù)據(jù)類型只有一個(gè),但是聲明符的形式卻可以不同。也就是說,一條定義語句可能定義出不同類型的變量:

    // i is an int; p is a pointer to int; r is a reference to int int i = 1024, *p = &i, &r = i;

    很多程序員容易迷惑于基本數(shù)據(jù)類型和類型修飾符的關(guān)系,其實(shí)后者不過是聲明符的一部分罷了。

    定義多個(gè)變量

    經(jīng)常有一種觀點(diǎn)會(huì)誤以為,在定義語句中,類型修飾符(*或s)作用于本次定義的全部變量。造成這種錯(cuò)誤看法的原因有很多,其中之一是我們可以把空格寫在類型修飾符和變量名中間:

    int* p; // legal but might be misleading

    我們說這種寫法可能產(chǎn)生誤導(dǎo)是因?yàn)閕nt*放在一起好像是這條語句中所有變量共同的類型一樣。其實(shí)恰恰相反,基本數(shù)據(jù)類型是int而非int*。*僅僅是修飾了p而已,對(duì)該聲明語句中的其他變量,它并不產(chǎn)生任何作用:

    int* p1, p2;// p1 is a pointer to int; p2 is an int

    涉及指針或引用的聲明,一般有兩種寫法

    第一種把修飾符和變量標(biāo)識(shí)符寫在一起:(推薦)

    int *p1, *p2; // both p1 and p2 are pointers to int

    這種形式著重強(qiáng)調(diào)變量具有的復(fù)合類型

    第二種把修飾符和類型名寫在一起,并且每條語句只定義一個(gè)變量:

    int* p1; // p1 is a pointer to int int* p2; // p2 is a pointer to int

    這種形式著重強(qiáng)調(diào)本次聲明定義了一種復(fù)合類型

    上述兩種定義指針或引用的不同方法沒有孰對(duì)孰錯(cuò)之分,關(guān)鍵是選擇并堅(jiān)持其中的一種寫法,不要總是變來變?nèi)ァ?/strong>

    我們接下都采用第一種寫法,將*(或是&)與變量名連在一起。(聲明符與變量)

    指向指針的指針

    一般來說,聲明符中修飾符的個(gè)數(shù)并沒有限制。當(dāng)有多個(gè)修飾符連寫在一起時(shí),按照其邏輯關(guān)系詳加解釋即可。以指針為例,指針是內(nèi)存中的對(duì)象,像其他對(duì)象一樣也有自己的地址,因此允許把指針的地址再存放到另一個(gè)指針當(dāng)中。

    通過*的個(gè)數(shù)可以區(qū)分指針的級(jí)別。也就是說,**表示指向指針的指針,***表示指向指針的指針的指針,以此類推:

    int ival = 1024; int *pi = &ival; // pi points to an int int **ppi = &pi; // ppi points to a pointer to an int

    此處pi是指向int型數(shù)的指針,而ppi是指向int型指針的指針,下圖描述了它們之間的關(guān)系。

    解引用int型指針會(huì)得到一個(gè)int型的數(shù),同樣,解引用指向指針的指針會(huì)得到一個(gè)指針。此時(shí)為了訪問最原始的那個(gè)對(duì)象,需要對(duì)指針的指針做兩次解引用:

    cout << "The value of ival\n"<< "direct value: " << ival << "\n"li<< "indirect value: " << *pi << "\n"<< "doubly indirect value: " << **ppi//兩次解引用<< endl;

    該程序使用三種不同的方式輸出了變量ival的值:

  • 第一種直接輸出;

  • 第二種通過int型指針pi輸出;

  • 第三種兩次解引用ppi,取得ival的值。

  • 指向指針的引用(指針的別名)(從右向左閱讀理解)

    引用本身不是一個(gè)對(duì)象,因此不能定義指向引用的指針。但指針是對(duì)象,所以存在對(duì)指針的引用:(指針不能指向引用)

    int i = 42; int *p; // p is a pointer to int int *&r = p; // r is a reference to the pointer p //對(duì)指針的引用//int &r = *p;//可以有這種寫法,有點(diǎn)懵,日后注意r = &i; // r refers to a pointer; assigning &i to r makes p point to i *r = 0; // dereferencing r yields i, the object to which p points; changes i to 0

    要理解r的類型到底是什么,最簡單的辦法是從右向左閱讀r的定義。

    離變量名最近的符號(hào)(此例中是&r的符號(hào)&)對(duì)變量的類型有最直接的影響,因此r是一個(gè)引用。聲明符的其余部分用以確定r引用的類型是什么,此例中的符號(hào)*說明r引用的是一個(gè)指針。最后,聲明的基本數(shù)據(jù)類型部分指出r引用的是一個(gè)int指針。

    面對(duì)一條比較復(fù)雜的指針或引用的聲明語句時(shí),從右向左閱讀有助于弄清楚它的真實(shí)含義。


    我寫的小程序來解惑:

    #include <iostream> #include "Sales_item.h" int main() {int i = 1;int *p = &i;int &r = *p;int *&r2 = p;//對(duì)指針的引用//int &r1 = 1; //errorint *p2 = &r;//int *p2 = r; //errorstd::cout<<r<<std::endl;std::cout<<*p2<<std::endl;std::cout<<*r2<<std::endl;std::cout<<p<<std::endl;std::cout<<&r<<std::endl;std::cout<<r2<<std::endl;std::cout<<p2<<std::endl;return 0; }

    輸出結(jié)果:

    1 1 1 0x61fe34 0x61fe34 0x61fe34 0x61fe34Process returned 0 (0x0) execution time : 0.048 s Press any key to continue.

    (Note:)

    (引用與指針一起來聲明,有點(diǎn)懵,記住:引用本身不是一個(gè)對(duì)象,因此不能定義指向引用的指針。但指針是對(duì)象,所以存在對(duì)指針的引用

    (引用->指針 OK,指針->引用 NO)

    int i = 1; int *p = &i;int &r = *p; //int *p2 = r; //指針->引用 NO int *p2 = &r; //這個(gè)r還是可以取址的,這是懵點(diǎn),

    (引用只是對(duì)象的別名)

    const限定符

    概述

    有時(shí)我們希望定義這樣一種變量,它的值不能被改變。(Note: 只讀變量

    例如,用一個(gè)變量來表示緩沖區(qū)的大小。使用變量的好處是當(dāng)我們覺得緩沖區(qū)大小不再合適時(shí),很容易對(duì)其進(jìn)行調(diào)整。另一方面,也應(yīng)隨時(shí)警惕防止程序一不小心改變了這個(gè)值。為了滿足這一要求,可以用關(guān)鍵字const對(duì)變量的類型加以限定:

    const int bufSize = 512; //輸入緩沖區(qū)大小

    這樣就把bufSize定義成了一個(gè)常量。任何試圖為bufSize賦值的行為都將引發(fā)錯(cuò)誤:

    bufSize = 1024; //錯(cuò)誤:試圖向const對(duì)象寫值

    因?yàn)閏onst對(duì)象一旦創(chuàng)建后其值就不能再改變,所以const對(duì)象必須初始化。一如既往,初始值可以是任意復(fù)雜的表達(dá)式:

    const int i = get_size(); // ok: initialized at run time const int j = 42; // ok: initialized at compile time const int k; // error: k is uninitialized const

    初始化和const

    正如之前反復(fù)提到的,對(duì)象的類型決定了其上的操作。與非 const類型所能參與的操作相比,const類型的對(duì)象能完成其中大部分,但也不是所有的操作都適合。主要的限制就是只能在const類型的對(duì)象上執(zhí)行不改變其內(nèi)容的操作。

    例如,const int和普通的int一樣都能參與算術(shù)運(yùn)算,也都能轉(zhuǎn)換成一個(gè)布爾值,等等。

    在不改變 const對(duì)象的操作中還有一種是初始化,如果利用一個(gè)對(duì)象去初始化另外一個(gè)對(duì)象,則它們是不是const都無關(guān)緊要:

    int i = 42; const int ci = i; // ok: the value in i is copied into ci int j = ci; // ok: the value in ci is copied into j

    盡管ci是整型常量,但無論如何ci中的值還是一個(gè)整型數(shù)。ci的常量特征僅僅在執(zhí)行改變ci的操作時(shí)才會(huì)發(fā)揮作用。當(dāng)用ci去初始化j時(shí),根本無須在意ci是不是一個(gè)常量。拷貝一個(gè)對(duì)象的值并不會(huì)改變它,一旦拷貝完成,新的對(duì)象就和原來的對(duì)象沒什么關(guān)系了。

    默認(rèn)狀態(tài)下,const對(duì)象僅在文件內(nèi)有效(const 常量在多文件中使用方法)

    當(dāng)以編譯時(shí)初始化的方式定義一個(gè)const對(duì)象時(shí),就如對(duì)bufsize的定義一樣:

    const int bufSize = 512;//輸入緩沖區(qū)大小

    編譯器將在編譯過程中把用到該變量的地方都替換成對(duì)應(yīng)的值。也就是說,編譯器會(huì)找到代碼中所有用到bufSize的地方,然后用512替換。

    為了執(zhí)行上述替換,編譯器必須知道變量的初始值。如果程序包含多個(gè)文件,則每個(gè)用了const對(duì)象的文件都必須得能訪問到它的初始值才行。要做到這一點(diǎn),就必須在每一個(gè)用到變量的文件中都有對(duì)它的定義。為了支持這一用法,同時(shí)避免對(duì)同一變量的重復(fù)定義,默認(rèn)情況下,const對(duì)象被設(shè)定為僅在文件內(nèi)有效。當(dāng)多個(gè)文件中出現(xiàn)了同名的const變量時(shí),其實(shí)等同于在不同文件中分別定義了獨(dú)立的變量。

    某些時(shí)候有這樣一種 const變量,它的初始值不是一個(gè)常量表達(dá)式,但又確實(shí)有必要在文件間共享。這種情況下,我們不希望編譯器為每個(gè)文件分別生成獨(dú)立的變量。相反,我們想讓這類const對(duì)象像其他(非常量)對(duì)象一樣工作,也就是說,只在一個(gè)文件中定義const,而在其他多個(gè)文件中聲明并使用它。

    解決的辦法是,對(duì)于const變量不管是聲明還是定義都添加extern關(guān)鍵字,這樣只需定義一次就可以了:

    //file_1.cc定義并初始化了一個(gè)常量,該常量能被其他文件訪問 extern const int bufSize = fcn();//file_l.h頭文件 extern const int bufSize; //與file_1.cc中定義的bufSize是同一個(gè)

    如上述程序所示,file_1.cc定義并初始化了bufsize。因?yàn)檫@條語句包含了初始值,所以它(顯然〉是一次定義。然而,因?yàn)閎ufsize是一個(gè)常量,必須用extern加以限定使其被其他文件使用。

    file_1.h頭文件中的聲明也由extern做了限定,其作用是指明bufsize并非本文件所獨(dú)有,它的定義將在別處出現(xiàn)。

    如果想在多個(gè)文件之間共享const對(duì)象,必須在變量的定義之前添加extern關(guān)鍵字。

    const的引用

    可以把引用綁定到const對(duì)象上,就像綁定到其他對(duì)象上一樣,我們稱之為對(duì)常量的引用(reference to const)。與普通引用不同的是,對(duì)常量的引用不能被用作修改它所綁定的對(duì)象:

    const int ci = 1024; const int &r1 = ci; // ok: both reference and underlying object are const r1 = 42; // error: r1 is a reference to const int &r2 = ci; // error: non const reference to a const object

    因?yàn)椴辉试S直接為ci賦值,當(dāng)然也就不能通過引用去改變ci。因此,對(duì)r2的初始化是錯(cuò)誤的。假設(shè)該初始化合法,則可以通過r2來改變它引用對(duì)象的值,這顯然是不正確的。

    術(shù)語:常量引用是對(duì)const的引用

    C++程序員們經(jīng)常把詞組“對(duì)const的引用”簡稱為“常量引用”,這一簡稱還是挺靠譜的,不過前提是你得時(shí)刻記得這就是個(gè)簡稱而已。

    嚴(yán)格來說,并不存在常量引用。因?yàn)橐貌皇且粋€(gè)對(duì)象,所以我們沒法讓引用本身恒定不變。事實(shí)上,由于C+語言并不允許隨意改變引用所綁定的對(duì)象,所以從這層意義上理解所有的引用又都算是常量。引用的對(duì)象是常量還是非常量可以決定其所能參與的操作,卻無論如何都不會(huì)影響到引用和對(duì)象的綁定關(guān)系本身。

    初始化和對(duì)const的引用

    前文提到,引用的類型必須與其所引用對(duì)象的類型一致,但是有兩個(gè)例外。

    第一種例外情況就是在初始化常量引用時(shí)允許用任意表達(dá)式作為初始值,只要該表達(dá)式的結(jié)果能轉(zhuǎn)換成引用的類型即可。尤其,允許為一個(gè)常量引用綁定非常量的對(duì)象、字面值,甚至是個(gè)一般表達(dá)式:

    int i = 42; const int &r1 = i; // we can bind a const int& to a plain int object const int &r2 = 42; // ok: r1 is a reference to const const int &r3 = r1 * 2; // ok: r3 is a reference to const int &r4 = r * 2; // error: r4 is a plain, non const reference

    要想理解這種例外情況的原因,最簡單的辦法是弄清楚當(dāng)一個(gè)常量引用被綁定到另外一種類型上時(shí)到底發(fā)生了什么:

    double dval = 3.14; const int &ri = dval;

    此處ri引用了一個(gè)int型的數(shù)。對(duì)ri的操作應(yīng)該是整數(shù)運(yùn)算,但dval卻是一個(gè)雙精度浮點(diǎn)數(shù)而非整數(shù)。因此為了確保讓ri綁定一個(gè)整數(shù),編譯器把上述代碼變成了如下形式:

    const int temp = dval;//由雙精度浮點(diǎn)數(shù)生成一個(gè)臨時(shí)的整型常量 const int &ri = temp;//讓ri綁定這個(gè)臨時(shí)量

    在這種情況下,ri綁定了一個(gè)臨時(shí)量(temporary)對(duì)象。所謂臨時(shí)量對(duì)象就是當(dāng)編譯器需要一個(gè)空間來暫存表達(dá)式的求值結(jié)果時(shí)臨時(shí)創(chuàng)建的一個(gè)未命名的對(duì)象。C++程序員們常常把臨時(shí)量對(duì)象簡稱為臨時(shí)量。

    接下來探討當(dāng)ri不是常量時(shí),如果執(zhí)行了類似于上面的初始化過程將帶來什么樣的后果。

    如果ri不是常量,就允許對(duì)ri賦值,這樣就會(huì)改變r(jià)i所引用對(duì)象的值。注意,此時(shí)綁定的對(duì)象是一個(gè)臨時(shí)量而非dval。程序員既然讓 ri引用dval,就肯定想通過ri改變dval的值,否則干什么要給ri賦值呢?如此看來,既然大家基本上不會(huì)想著把引用綁定到臨時(shí)量上,C++語言也就把這種行為歸為非法。

    (Note: 第二種例外情況在哪???)

    對(duì)const的引用可能引用一個(gè)并非const的對(duì)象

    必須認(rèn)識(shí)到,常量引用僅對(duì)引用可參與的操作做出了限定,對(duì)于引用的對(duì)象本身是不是一個(gè)常量未作限定。因?yàn)閷?duì)象也可能是個(gè)非常量,所以允許通過其他途徑改變它的值:

    int i = 42; int &r1 = i; // r1 bound to i const int &r2 = i; // r2 also bound to i; but cannot be used to change i r1 = 0; // r1 is not const; i is now 0 r2 = 0; // error: r2 is a reference to const

    r2綁定(非常量)整數(shù)i是合法的行為。然而,不允許通過r2修改i的值。盡管如此,i的值仍然允許通過其他途徑修改,既可以直接給i賦值,也可以通過像r1一樣綁定到i的其他引用來修改。(防不勝防)(Note: 真麻煩)

    指針和const

    與引用一樣,也可以令指針指向常量或非常量。類似于常量引用,指向常量的指針(pointer to const)不能用于改變其所指對(duì)象的值。要想存放常量對(duì)象的地址,只能使用指向常量的指針:

    const double pi = 3.14; // pi is const; its value may not be changed double *ptr = &pi; // error: ptr is a plain pointer const double *cptr = &pi; // ok: cptr may point to a double that is const *cptr = 42; // error: cannot assign to *cptr

    前文提到,指針的類型必須與其所指對(duì)象的類型一致,但是有兩個(gè)例外第一種例外情況是允許令一個(gè)指向常量的指針指向一個(gè)非常量對(duì)象:

    double dval = 3.14; // dval is a double; its value can be changed cptr = &dval; // ok: but can't change dval through cptr

    和常量引用一樣,指向常量的指針也沒有規(guī)定其所指的對(duì)象必須是一個(gè)常量。所謂指向常量的指針僅僅要求不能通過該指針改變對(duì)象的值,而沒有規(guī)定那個(gè)對(duì)象的值不能通過其他途徑改變。(也就是說還有其他路子改變對(duì)象的值,可查看第一節(jié))。

    試試這樣想吧:所謂指向常量的指針或引用,不過是指針或引用“自以為是”罷了,它們覺得自己指向了常量,所以自覺地不去改變所指對(duì)象的值。It may be helpful to think of pointers and references to const as pointers or references “that think they point or refer to const.

    (第二中例外沒寫)

    const指針

    (上一節(jié)講的是指向常量的指針,這節(jié)將常量指針)

    指針是對(duì)象而引用不是,因此就像其他對(duì)象類型一樣,允許把指針本身定為常量。常量指針(const pointer)必須初始化,而且一旦初始化完成,則它的值(也就是存放在指針中的那個(gè)地址)就不能再改變了。把*放在const關(guān)鍵字之前用以說明指針是一個(gè)常量,這樣的書寫形式隱含著一層意味,即不變的是指針本身的值而非指向的那個(gè)值:

    int errNumb = 0; int *const curErr = &errNumb; // curErr will always point to errNumb const double pi = 3.14159; const double *const pip = &pi; // pip is a const pointer to a const object

    前文提到,要想弄清楚這些聲明的含義最行之有效的辦法是從右向左閱讀。(Note:這是理解這些復(fù)雜申明語句的關(guān)鍵

    此例中,

  • 離curErr最近的符號(hào)是const,意味著curErr本身是一個(gè)常量對(duì)象,對(duì)象的類型由聲明符的其余部分確定。
  • 聲明符中的下一個(gè)符號(hào)是*,意思是curErr是一個(gè)常量指針
  • 最后,該聲明語句的基本數(shù)據(jù)類型部分確定了常量指針指向的是一個(gè)int對(duì)象
  • 對(duì)象是指一塊能存儲(chǔ)數(shù)據(jù)并具有某種類型的內(nèi)存空間

    與之相似,我們也能推斷出,pip是一個(gè)常量指針,它指向的對(duì)象是一個(gè)雙精度浮點(diǎn)型常量。

    指針本身是一個(gè)常量并不意味著不能通過指針修改其所指對(duì)象的值,能否這樣做完全依賴于所指對(duì)象的類型。例如,pip是一個(gè)指向常量的常量指針,則不論是 pip 所指的對(duì)象值還是pip自己存儲(chǔ)的那個(gè)地址都不能改變。

    相反的,curErr指向的是一個(gè)一般的非常量整數(shù),那么就完全可以用curErr去修改errNumb 的值:

    *pip = 2.72; // error: pip is a pointer to const//指向 // if the object to which curErr points (i.e., errNumb) is nonzero if (*curErr) {errorHandler();*curErr = 0; // ok: reset the value of the object to which curErr is bound curr常量指針指向的是一個(gè)int對(duì)象,這對(duì)象可以改變 }

    頂層const

    如前所述,指針本身是一個(gè)對(duì)象,它又可以指向另外一個(gè)對(duì)象。因此,指針本身是不是常量以及指針?biāo)傅氖遣皇且粋€(gè)常量就是兩個(gè)相互獨(dú)立的問題。

    用名詞頂層const(top-level const)表示指針本身是個(gè)常量,而用名詞底層const (low-level const)表示指針?biāo)傅膶?duì)象是一個(gè)常量

    更一般的:

    頂層const可以表示任意的對(duì)象是常量,這一點(diǎn)對(duì)任何數(shù)據(jù)類型都適用,如算術(shù)類型、類、指針等。

    底層const則與指針和引用等復(fù)合類型的基本類型部分有關(guān)。比較特殊的是,指針類型既可以是頂層const也可以是底層const,這一點(diǎn)和其他類型相比區(qū)別明顯:

    (助記:頂常底復(fù))

    int i = 0; //頂層const:表示任意的對(duì)象是常量 int *const p1 = &i; // we can't change the value of p1; const is top-level const int ci = 42; // we cannot change ci; const is top-level//底層const:與指針和引用等復(fù)合類型的基本類型部分有關(guān) const int *p2 = &ci; // we can change p2; const is low-level const int &r = ci; // const in reference types is always low-level//頂層const又是底層const const int *const p3 = p2; // right-most const is top-level, left-most is not

    (Note:根據(jù)const所在位置來判斷頂層const或底層const不管用)

    當(dāng)執(zhí)行對(duì)象的拷貝操作時(shí),常量是頂層const還是底層const區(qū)別明顯。

    其中,頂層const不受什么影響:

    i = ci; // ok: copying the value of ci; top-level const in ci is ignored p2 = p3; // ok: pointed-to type matches; top-level const in p3 is ignored

    執(zhí)行拷貝操作并不會(huì)改變被拷貝對(duì)象的值,因此,拷入和拷出的對(duì)象是否是常量都沒什么影響。

    另一方面,底層 const 的限制卻不能忽視。當(dāng)執(zhí)行對(duì)象的拷貝操作時(shí),拷入和拷出的對(duì)象必須具有相同的底層 const 資格,或者兩個(gè)對(duì)象的數(shù)據(jù)類型必須能夠轉(zhuǎn)換。一般來說,非常量可以轉(zhuǎn)換成常量,反之則不行:

    int *p = p3; // error: p3 has a low-level const but p doesn't p2 = p3; // ok: p2 has the same low-level const qualification as p3 p2 = &i; // ok: we can convert int* to const int* int &r = ci; // error: can't bind an ordinary int& to a const int object const int &r2 = i; // ok: can bind const int& to plain int

    p3既是頂層const也是底層const,拷貝p3時(shí)可以不在乎它是一個(gè)頂層const,但是必須清楚它指向的對(duì)象得是一個(gè)常量。因此,不能用p3去初始化p,因?yàn)閜指向的是一個(gè)普通的(非常量)整數(shù)。另一方面,p3的值可以賦給p2,是因?yàn)檫@兩個(gè)指針都是底層const,盡管p3同時(shí)也是一個(gè)常量指針(頂層const),僅就這次賦值而言不會(huì)有什么影響。

    (Note:這節(jié)不好懂)

    constexpr和常量表達(dá)式

    常量表達(dá)式(const expression)是指值不會(huì)改變并且在編譯過程就能得到計(jì)算結(jié)果的表達(dá)式。顯然,字面值屬于常量表達(dá)式,用常量表達(dá)式初始化的const對(duì)象也是常量表達(dá)式。后面將會(huì)提到,C++語言中有幾種情況下是要用到常量表達(dá)式的。

    一個(gè)對(duì)象(或表達(dá)式)是不是常量表達(dá)式由它的數(shù)據(jù)類型和初始值共同決定,例如:

    const int max_files = 20; // max_files is a constant expression const int limit = max_files + 1; // limit is a constant expression int staff_size = 27; // staff_size is not a constant expression const int sz = get_size(); // sz is not a constant expression

    盡管staff_size的初始值是個(gè)字面值常量,但由于它的數(shù)據(jù)類型只是一個(gè)普通int而非const int,所以它不屬于常量表達(dá)式。另一方面,盡管 sz本身是一個(gè)常量,但它的具體值直到運(yùn)行時(shí)才能獲取到,所以也不是常量表達(dá)式。

    constexpr變量

    在一個(gè)復(fù)雜系統(tǒng)中,很難(幾乎肯定不能)分辨一個(gè)初始值到底是不是常量表達(dá)式。當(dāng)然可以定義一個(gè) const變量并把它的初始值設(shè)為我們認(rèn)為的某個(gè)常量表達(dá)式,但在實(shí)際使用時(shí),盡管要求如此卻常常發(fā)現(xiàn)初始值并非常量表達(dá)式的情況。可以這么說,在此種情況下,對(duì)象的定義和使用根本就是兩回事兒。

    C++11新標(biāo)準(zhǔn)規(guī)定,允許將變量聲明為constexpr類型以便由編譯器來驗(yàn)證變量的值是否是一個(gè)常量表達(dá)式。聲明為constexpr的變量一定是一個(gè)常量,而且必須用常量表達(dá)式初始化:

    constexpr int mf = 20; // 20 is a constant expression constexpr int limit = mf + 1; // mf + 1 is a constant expression constexpr int sz = size(); // ok only if size is a constexpr function

    盡管不能使用普通函數(shù)作為constexpr變量的初始值,但是,將要介紹的,新標(biāo)準(zhǔn)允許定義一種特殊的constexpr函數(shù)。這種函數(shù)應(yīng)該足夠簡單以使得編譯時(shí)就可以計(jì)算其結(jié)果,這樣就能用constexpr函數(shù)去初始化 constexpr變量了。

    一般來說,如果你認(rèn)定變量是一個(gè)常量表達(dá)式,那就把它聲明成 constexpr類型。

    字面值類型

    常量表達(dá)式的值需要在編譯時(shí)就得到計(jì)算,因此對(duì)聲明constexpr時(shí)用到的類型必須有所限制。因?yàn)檫@些類型一般比較簡單,值也顯而易見、容易得到,就把它們稱為“字面值類型”( literal type)。

    到目前為止接觸過的數(shù)據(jù)類型中,算術(shù)類型、引用和指針都屬于字面值類型。

    自定義類sales_item、IO 庫、string 類型則不屬于字面值類型,也就不能被定義成constexpr。

    盡管指針和引用都能定義成constexpr,但它們的初始值卻受到嚴(yán)格限制。一個(gè)constexpr指針的初始值必須是nullptr或者0,或者是存儲(chǔ)于某個(gè)固定地址中的對(duì)象。

    將要提到,函數(shù)體內(nèi)定義的變量一般來說并非存放在固定地址中,因此constexpr指針不能指向這樣的變量。相反的,定義于所有函數(shù)體之外的對(duì)象其地址固定不變,能用來初始化constexpr指針。

    將提到,允許函數(shù)定義一類有效范圍超出函數(shù)本身的變量,這類變量和定義在函數(shù)體之外的變量一樣也有固定地址。因此,constexpr引用能綁定到這樣的變量上,constexpr 指針也能指向這樣的變量。

    (Note:哪些定義constexpr,哪些不能定義constexpr)

    指針和constexpr

    必須明確一點(diǎn),在constexpr聲明中如果定義了一個(gè)指針,限定符constexpr僅對(duì)指針有效,與指針?biāo)傅膶?duì)象無關(guān):

    const int *p = nullptr; // p is a pointer to a const int constexpr int *q = nullptr; // q is a const pointer to int

    p和q的類型相差甚遠(yuǎn),p是一個(gè)指向常量的指針,而q是一個(gè)常量指針,其中的關(guān)鍵在于constexpr把它所定義的對(duì)象置為了頂層const。

    與其他常量指針類似,constexpr指針既可以指向常量也可以指向一個(gè)非常量:

    constexpr int *np = nullptr; // np is a constant pointer to int that is null int j = 0; constexpr int i = 42; // type of i is const int// i and j must be defined outside any function constexpr const int *p = &i; // p is a constant pointer to the const int i constexpr int *p1 = &j; // p1 is a constant pointer to the int j

    處理類型

    隨著程序越來越復(fù)雜,程序中用到的類型也越來越復(fù)雜,這種復(fù)雜性體現(xiàn)在兩個(gè)方面。

  • 一些類型難于“拼寫”,它們的名字既難記又容易寫錯(cuò),還無法明確體現(xiàn)其真實(shí)目的和含義。
  • 有時(shí)候根本搞不清到底需要的類型是什么,程序員不得不回過頭去從程序的上下文中尋求幫助。
  • 類型別名

    類型別名(type alias)是一個(gè)名字,它是某種類型的同義詞。使用類型別名有很多好處,它讓復(fù)雜的類型名字變得簡單明了、易于理解和使用,還有助于程序員清楚地知道使用該類型的真實(shí)目的。

    有兩種方法可用于定義類型別名。傳統(tǒng)的方法是使用關(guān)鍵字typedef

    typedef double wages; // wages is a synonym for double typedef wages base, *p; // base is a synonym for double, p for double*

    其中,關(guān)鍵字typedef作為聲明語句中的基本數(shù)據(jù)類型的一部分出現(xiàn)。含有 typedef 的聲明語句定義的不再是變量而是類型別名。和以前的聲明語句一樣,這里的聲明符也可以包含類型修飾,從而也能由基本數(shù)據(jù)類型構(gòu)造出復(fù)合類型來。

    C++11新標(biāo)準(zhǔn)規(guī)定了一種新的方法,使用別名聲明(alias declaration)來定義類型的別名:

    using SI = Sales_item; // SI is a synonym for Sales_item

    這種方法用關(guān)鍵字using 作為別名聲明的開始,其后緊跟別名和等號(hào),其作用是把等號(hào)左側(cè)的名字規(guī)定成等號(hào)右側(cè)類型的別名。

    類型別名和類型的名字等價(jià),只要是類型的名字能出現(xiàn)的地方,就能使用類型別名:

    wages hourly, weekly; // same as double hourly, weekly; SI item; // same as Sales_item item

    指針、常量和類型別名

    如果某個(gè)類型別名指代的是復(fù)合類型或常量,那么把它用到聲明語句里就會(huì)產(chǎn)生意想不到的后果。例如下面的聲明語句用到了類型pstring,它實(shí)際上是類型char*的別名:

    typedef char *pstring; const pstring cstr = 0; // cstr is a constant pointer to char const pstring *ps; // ps is a pointer to a constant pointer to char//從指向指針的指針

    上述兩條聲明語句的基本數(shù)據(jù)類型都是const pstring,和過去一樣,const是對(duì)給定類型的修飾。pstring 實(shí)際上是指向char 的指針,因此,const pstring 就是指向char的常量指針,而非指向常量字符的指針。

    遇到一條使用了類型別名的聲明語句時(shí),人們往往會(huì)錯(cuò)誤地嘗試把類型別名替換成它本來的樣子,以理解該語句的含義:(Note:不能像代數(shù)那樣代入

    const char *cstr = 0; // wrong interpretation of const pstring cstr

    再強(qiáng)調(diào)一遍:這種理解是錯(cuò)誤的。

    聲明語句中用到pstring 時(shí),其基本數(shù)據(jù)類型是指針。可是用char*重寫了聲明語句后,數(shù)據(jù)類型就變成了char,*成為了聲明符的一部分。However, this interpretation is wrong. When we use pstring in a declaration, the base type of the declaration is a pointer type. When we rewrite the declaration using char*, the base type is char and the * is part of the declarator.

    這樣改寫的結(jié)果是,const char成了基本數(shù)據(jù)類型。前后兩種聲明含義截然不同,前者聲明了一個(gè)指向char的常量指針,改寫后的形式則聲明了一個(gè)指向const char的指針。 In this case, const char is the base type. This rewrite declares cstr as a pointer to const char rather than as a const pointer to char.

    (Note:)

    const (char *)cstr = 0;//我是這樣理解的,一個(gè)指向char的常量指針

    auto類型說明符

    C++11新特性

    編程時(shí)常常需要把表達(dá)式的值賦給變量,這就要求在聲明變量的時(shí)候清楚地知道表達(dá)式的類型。然而要做到這一點(diǎn)并非那么容易,有時(shí)甚至根本做不到。為了解決這個(gè)問題,C++11新標(biāo)準(zhǔn)引入了auto類型說明符,用它就能讓編譯器替我們?nèi)シ治霰磉_(dá)式所屬的類型。和原來那些只對(duì)應(yīng)一種特定類型的說明符(比如 double)不同,auto 讓編譯器通過初始值來推算變量的類型。顯然,auto定義的變量必須有初始值:

    // the type of item is deduced from the type of the result of adding val1 and val2 auto item = val1 + val2; // item initialized to the result of val1 + val2

    此處編譯器將根據(jù)val1和val2相加的結(jié)果來推斷item的類型。如果val1和val2是類Sales _item(具體查看上一章)的對(duì)象,則item的類型就是Sales_item;如果這兩個(gè)變量的類型是double,則item的類型就是double,以此類推。

    使用auto也能在一條語句中聲明多個(gè)變量。因?yàn)橐粭l聲明語句只能有一個(gè)基本數(shù)據(jù)類型,所以該語句中所有變量的初始基本數(shù)據(jù)類型都必須一樣:

    auto i = 0, *p = &i; // ok: i is int and p is a pointer to int auto sz = 0, pi = 3.14; // error: inconsistent types for sz and pi

    復(fù)合類型、常量和 auto

    編譯器推斷出來的auto類型有時(shí)候和初始值的類型并不完全一樣,編譯器會(huì)適當(dāng)?shù)馗淖兘Y(jié)果類型使其更符合初始化規(guī)則

    首先,正如我們所熟知的,使用引用其實(shí)是使用引用的對(duì)象,特別是當(dāng)引用被用作初始值時(shí),真正參與初始化的其實(shí)是引用對(duì)象的值。此時(shí)編譯器以引用對(duì)象的類型作為auto的類型:

    int i = 0, &r = i; auto a = r; // a is an int (r is an alias for i, which has type int)

    其次,auto一般會(huì)忽略掉頂層const,同時(shí)底層const則會(huì)保留下來,比如當(dāng)初始值是一個(gè)指向常量的指針時(shí):

    const int ci = i, &cr = ci; auto b = ci; // b is an int (top-level const in ci is dropped) auto c = cr; // c is an int (cr is an alias for ci whose const is top-level) auto d = &i; // d is an int*(& of an int object is int*) auto e = &ci; // e is const int*(& of a const object is low-level const)

    如果希望推斷出的auto類型是一個(gè)頂層const,需要明確指出:

    const auto f = ci; // deduced type of ci is int; f has type const int

    還可以將引用的類型設(shè)為auto,此時(shí)原來的初始化規(guī)則仍然適用:

    auto &g = ci; // g is a const int& that is bound to ci auto &h = 42; // error: we can't bind a plain reference to a literal const auto &j = 42; // ok: we can bind a const reference to a literal

    設(shè)置一個(gè)類型為auto的引用時(shí),初始值中的頂層常量屬性仍然保留。和往常一樣,如果我們給初始值綁定一個(gè)引用,則此時(shí)的常量就不是頂層常量了。

    要在一條語句中定義多個(gè)變量,切記,符號(hào)&和*只從屬于某個(gè)聲明符,而非基本數(shù)據(jù)類型的一部分,因此初始值必須是同一種類型:

    auto k = ci, &l = i; // k is int; l is int& auto &m = ci, *p = &ci; // m is a const int&;p is a pointer to const int // error: type deduced from i is int; type deduced from &ci is const int auto &n = i, *p2 = &ci;

    (Note:符號(hào)&和*只從屬于某個(gè)聲明符,而非基本數(shù)據(jù)類型的一部分,這一句很重要)。

    decltype類型指示符

    C++11新標(biāo)準(zhǔn)

    有時(shí)會(huì)遇到這種情況:希望從表達(dá)式的類型推斷出要定義的變量的類型,但是不想用該表達(dá)式的值初始化變量。為了滿足這一要求,C++11新標(biāo)準(zhǔn)引入了第二種類型說明符decltype,它的作用是選擇并返回操作數(shù)的數(shù)據(jù)類型。在此過程中,編譯器分析表達(dá)式并得到它的類型,卻不實(shí)際計(jì)算表達(dá)式的值:

    decltype(f()) sum = x; // sum has whatever type f returns

    編譯器并不實(shí)際調(diào)用函數(shù)f,而是使用當(dāng)調(diào)用發(fā)生時(shí)f的返回值類型作為sum的類型。換句話說,編譯器為sum 指定的類型是什么呢?就是假如f被調(diào)用的話將會(huì)返回的那個(gè)類型。

    decltype處理頂層const和引用的方式與auto有些許不同。如果decltype使用的表達(dá)式是一個(gè)變量,則 decltype返回該變量的類型(包括頂層const和引用在內(nèi)):

    const int ci = 0, &cj = ci; decltype(ci) x = 0; // x has type const int decltype(cj) y = x; // y has type const int& and is bound to x decltype(cj) z; // error: z is a reference and must be initialized

    因?yàn)閏j是一個(gè)引用,decltype(cj)的結(jié)果就是引用類型,因此作為引用的z必須被初始化。

    需要指出的是,引用從來都作為其所指對(duì)象的同義詞出現(xiàn),只有用在 decltype 處是一個(gè)例外。

    decltype和引用

    如果decltype使用的表達(dá)式不是一個(gè)變量,則decltype返回表達(dá)式結(jié)果對(duì)應(yīng)的類型。有些表達(dá)式將向decltype返回一個(gè)引用類型。一般來說當(dāng)這種情況發(fā)生時(shí),意味著該表達(dá)式的結(jié)果對(duì)象能作為一條賦值語句的左值:

    // decltype of an expression can be a reference type int i = 42, *p = &i, &r = i; decltype(r + 0) b; // ok: addition yields an int; b is an (uninitialized) int decltype(*p) c; // error: c is int& and must be initialized

    因?yàn)閞是一個(gè)引用,因此 decltype?的結(jié)果是引用類型。如果想讓結(jié)果類型是r所指的類型,可以把r作為表達(dá)式的一部分,如r+0,顯然這個(gè)表達(dá)式的結(jié)果將是一個(gè)具體值而非一個(gè)引用。

    另一方面,如果表達(dá)式的內(nèi)容是解引用操作,則decltype 將得到引用類型。正如我們所熟悉的那樣,解引用指針可以得到指針?biāo)傅膶?duì)象,而且還能給這個(gè)對(duì)象賦值。因此,decltype (*p)的結(jié)果類型就是int&,而非int。

    decltype和 auto的另一處重要區(qū)別是,decltype的結(jié)果類型與表達(dá)式形式密切相關(guān)。有一種情況需要特別注意:對(duì)于 decltype所用的表達(dá)式來說,如果變量名加上了一對(duì)括號(hào),則得到的類型與不加括號(hào)時(shí)會(huì)有不同。

    • 如果 decltype使用的是一個(gè)不加括號(hào)的變量,則得到的結(jié)果就是該變量的類型;
    • 如果給變量加上了一層或多層括號(hào),編譯器就會(huì)把它當(dāng)成是一個(gè)表達(dá)式。

    變量是一種可以作為賦值語句左值的特殊表達(dá)式,所以這樣的decltype就會(huì)得到引用類型:

    // decltype of a parenthesized variable is always a reference decltype((i)) d; // error: d is int& and must be initialized decltype(i) e; // ok: e is an (uninitialized) int

    切記:decltype ((variable))(注意是雙層括號(hào))的結(jié)果永遠(yuǎn)是引用,而decltype(variable)結(jié)果只有當(dāng) variable本身就是一個(gè)引用時(shí)才是引用。

    自定義數(shù)據(jù)結(jié)構(gòu)

    從最基本的層面理解,數(shù)據(jù)結(jié)構(gòu)是把一組相關(guān)的數(shù)據(jù)元素組織起來然后使用它們的策略和方法。

    舉一個(gè)例子,我們的Sales_item類把書本的ISBN編號(hào)、售出量及銷售收入等數(shù)據(jù)組織在了一起,并且提供諸如isbn函數(shù)、>>、<<、+、+=等運(yùn)算在內(nèi)的一系列操作,sales_item類就是一個(gè)數(shù)據(jù)結(jié)構(gòu)。

    C++語言允許用戶以類的形式自定義數(shù)據(jù)類型,而庫類型string、 istream、ostream等也都是以類的形式定義的,就像上一章Sales_item類型一樣。

    定義Sales_data類型

    盡管我們還寫不出完整的Sales_item類,但是可以嘗試著把那些數(shù)據(jù)元素組織到一起形成一個(gè)簡單點(diǎn)兒的類。初步的想法是用戶能直接訪問其中的數(shù)據(jù)元素,也能實(shí)現(xiàn)一些基本的操作。

    既然我們籌劃的這個(gè)數(shù)據(jù)結(jié)構(gòu)不帶有任何運(yùn)算功能,不妨把它命名為 Sales_data以示與Sales_item的區(qū)別。Sales_data初步定義如下:

    struct Sales_data {std::string bookNo;unsigned units_sold = 0;double revenue = 0.0; };

    我們的類以關(guān)鍵字struct開始,緊跟著類名和類體(其中類體部分可以為空)。類體由花括號(hào)包圍形成了一個(gè)新的作用域。類內(nèi)部定義的名字必須唯一,但是可以與類外部定義的名字重復(fù)。

    類體右側(cè)的表示結(jié)束的花括號(hào)后必須寫一個(gè)分號(hào),這是因?yàn)轭愺w后面可以緊跟變量名以示對(duì)該類型對(duì)象的定義,所以分號(hào)必不可少:

    struct Sales_data { /* ... */ } accum, trans, *salesptr; // equivalent, but better way to define these objects struct Sales_data { /* ... */ }; Sales_data accum, trans, *salesptr;

    分號(hào)表示聲明符(通常為空)的結(jié)束。一般來說,最好不要把對(duì)象的定義和類的定義放在一起。這么做無異于把兩種不同實(shí)體的定義混在了一條語句里,一會(huì)兒定義類,一會(huì)兒又定義變量,顯然這是一種不被建議的行為。

    很多新手程序員經(jīng)常忘了在類定義的最后加上分號(hào)。

    類數(shù)據(jù)成員

    類體定義類的成員,我們的類只有數(shù)據(jù)成員(data member)。類的數(shù)據(jù)成員定義了類的對(duì)象的具體內(nèi)容,每個(gè)對(duì)象有自己的一份數(shù)據(jù)成員拷貝。修改一個(gè)對(duì)象的數(shù)據(jù)成員,不會(huì)影響其他Sales_data的對(duì)象。

    定義數(shù)據(jù)成員的方法和定義普通變量一樣:首先說明一個(gè)基本類型,隨后緊跟一個(gè)或多個(gè)聲明符。我們的類有3個(gè)數(shù)據(jù)成員:

  • 一個(gè)名為bookNo的string 成員、
  • 一個(gè)名為units_sold的unsigned 成員
  • 一個(gè)名為revenue的 double 成員。
  • 每個(gè)Sales_data的對(duì)象都將包括這3個(gè)數(shù)據(jù)成員。

    C++11新標(biāo)準(zhǔn)規(guī)定,可以為數(shù)據(jù)成員提供一個(gè)類內(nèi)初始值(in-class initializer)。創(chuàng)建對(duì)象時(shí),類內(nèi)初始值將用于初始化數(shù)據(jù)成員。沒有初始值的成員將被默認(rèn)初始化(函數(shù)體內(nèi)的默認(rèn)不初始化,函數(shù)體外的都默認(rèn)初始化)。因此當(dāng)定義Sales_data的對(duì)象時(shí),units_sold和revenue都將初始化為0,bookNo將初始化為空字符串。

    用戶可以使用C++語言提供的另外一個(gè)關(guān)鍵字class來定義自己的數(shù)據(jù)結(jié)構(gòu),到時(shí)也將說明現(xiàn)在我們使用struct 的原因。現(xiàn)在使用struct定義自己的數(shù)據(jù)類型。

    和Sales_item類不同的是,我們自定義的sales_data類沒有提供任何操作,sales_data類的使用者如果想執(zhí)行什么操作就必須自己動(dòng)手實(shí)現(xiàn)。例如,寫一段程序?qū)崿F(xiàn)求兩次交易相加結(jié)果的功能。程序的輸入是下面這兩條交易記錄:

    0-201-78345-x 3 20.00 0-201-78345-x 2 25.00

    每筆交易記錄著圖書的ISBN編號(hào)、售出數(shù)量和售出單價(jià)。

    使用Sales_data類

    因?yàn)閟ales_data類沒有提供任何操作,所以我們必須自己編碼實(shí)現(xiàn)輸入、輸出和相加的功能。假設(shè)已知Sales_data類定義于Sales_data.h文件內(nèi)。

    #include <iostream> #include <string> #include "Sales_data.h" int main() {Sales_data data1, data2;// code to read into data1 and data2// code to check whether data1 and data2 have the same ISBN// and if so print the sum of data1 and data2 }

    Sales_data對(duì)象讀入數(shù)據(jù)

    在此之前,我們先了解一點(diǎn)兒關(guān)于string 的知識(shí)以便定義和使用我們的ISBN成員。string類型其實(shí)就是字符的序列,它的操作有>>、<<和==等,功能分別是讀入字符串、寫出字符串和比較字符串。這樣我們就能書寫代碼讀入兩筆交易了:

    double price = 0; // price per book, used to calculate total revenue // read the first transactions: ISBN, number of books sold, price per book std::cin >> data1.bookNo >> data1.units_sold >> price; // calculate total revenue from price and units_sold data1.revenue = data1.units_sold * price;// read the second transaction std::cin >> data2.bookNo >> data2.units_sold >> price; data2.revenue = data2.units_sold * price;

    輸出兩個(gè)Sales_data對(duì)象的和

    剩下的工作就是檢查兩筆交易涉及的工SBN編號(hào)是否相同了。如果相同輸出它們的和,否則輸出一條報(bào)錯(cuò)信息:

    if (data1.bookNo == data2.bookNo) {unsigned totalCnt = data1.units_sold + data2.units_sold;double totalRevenue = data1.revenue + data2.revenue;// print: ISBN, total sold, total revenue, average price per bookstd::cout << data1.bookNo << " " << totalCnt<< " " << totalRevenue << " ";if (totalCnt != 0)std::cout << totalRevenue/totalCnt << std::endl;elsestd::cout << "(no sales)" << std::endl;return 0; // indicate success } else { // transactions weren't for the same ISBNstd::cerr << "Data must refer to the same ISBN" << std::endl;return -1; // indicate failure }

    編寫自己的頭文件

    函數(shù)體內(nèi)定義類(先了解一下),但是這樣的類畢競受到了一些限制。所以,類一般都不定義在函數(shù)體內(nèi)。當(dāng)在函數(shù)體外部定義類時(shí),在各個(gè)指定的源文件中可能只有一處該類的定義。而且,如果要在不同文件中使用同一個(gè)類,類的定義就必須保持一致。

    為了確保各個(gè)文件中類的定義一致,類通常被定義在頭文件中,而且類所在頭文件的名字應(yīng)與類的名字一樣。例如,庫類型string在名為string 的頭文件中定義。又如,我們應(yīng)該把Sales_data類定義在名為sales_data.h 的頭文件中。

    頭文件通常包含那些只能被定義一次的實(shí)體,如類、const和 constexpr變量等。

    頭文件也經(jīng)常用到其他頭文件的功能。

    例如,我們的Sales_data類包含有一個(gè)string 成員,所以Sales_data.h必須包含string.h頭文件。同時(shí),使用sales_data類的程序?yàn)榱四懿僮鱞ookNo成員需要再一次包含string.h頭文件。

    這樣,事實(shí)上使用sales_data類的程序就先后兩次包含了string.h頭文件:一次是直接包含的,另有一次是隨著包含sales_data.h 被隱式地包含進(jìn)來的。有必要在書寫頭文件時(shí)做適當(dāng)處理,使其遇到多次包含的情況也能安全和正常地工作。

    頭文件一旦改變,相關(guān)的源文件必須重新編譯以獲取更新過的聲明。

    預(yù)處理器

    確保頭文件多次包含仍能安全工作的常用技術(shù)是預(yù)處理器(preprocessor),它由C++語言從C語言繼承而來。預(yù)處理器是在編譯之前執(zhí)行的一段程序,可以部分地改變我們所寫的程序。之前已經(jīng)用到了一項(xiàng)預(yù)處理功能#include,當(dāng)預(yù)處理器看到#include標(biāo)記時(shí)就會(huì)用指定的頭文件的內(nèi)容代替#include。

    C++程序還會(huì)用到的一項(xiàng)預(yù)處理功能是頭文件保護(hù)符(header guard),頭文件保護(hù)符依賴于預(yù)處理變量。預(yù)處理變量有兩種狀態(tài):已定義和未定義。

    • #define指令把一個(gè)名字設(shè)定為預(yù)處理變量,

    另外兩個(gè)指令則分別檢查某個(gè)指定的預(yù)處理變量是否已經(jīng)定義:

    • #ifdef當(dāng)且僅當(dāng)變量已定義時(shí)為真,
    • #ifndef當(dāng)且僅當(dāng)變量未定義時(shí)為真。

    一旦檢查結(jié)果為真,則執(zhí)行后續(xù)操作直至遇到 #endif 指令為止。

    使用這些功能就能有效地防止重復(fù)包含的發(fā)生

    #ifndef SALES_DATA_H #define SALES_DATA_H #include <string> struct Sales_data {std::string bookNo;unsigned units_sold = 0;double revenue = 0.0; }; #endif

    第一次包含sales_data.h時(shí),#ifndef的檢查結(jié)果為真,預(yù)處理器將順序執(zhí)行后面的操作直至遇到#endif 為止。此時(shí),預(yù)處理變量SALES_DATA_H的值將變?yōu)橐讯x,而且sales_data. h也會(huì)被拷貝到我們的程序中來。

    后面如果再一次包含sales_data.h,則#ifndef 的檢查結(jié)果將為假,編譯器將忽略#ifndef到#endif之間的部分。

    預(yù)處理變量無視C++語言中關(guān)于作用域的規(guī)則。

    整個(gè)程序中的預(yù)處理變量包括頭文件保護(hù)符必須唯一,通常的做法是基于頭文件中類的名字來構(gòu)建保護(hù)符的名字,以確保其唯一性。為了避免與程序中的其他實(shí)體發(fā)生名字沖突,一般把預(yù)處理變量的名字全部大寫。

    頭文件即使(目前還)沒有被包含在任何其他頭文件中,也應(yīng)該設(shè)置保護(hù)符。頭文件保護(hù)符很簡單,程序員只要習(xí)慣性地加上就可以了,沒必要太在乎你的程序到底需不需要。

    (Note:日后寫頭文件都要設(shè)置保護(hù)符

    總結(jié)

    以上是生活随笔為你收集整理的《C++ Primer 5th》笔记(2 / 19):变量和基本类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    天天拍夜夜添久久精品大 | 中文精品无码中文字幕无码专区 | 国产免费久久精品国产传媒 | 日日干夜夜干 | 无码国内精品人妻少妇 | 国产农村乱对白刺激视频 | 国产精品久久福利网站 | 国产精品人人妻人人爽 | 无码人妻av免费一区二区三区 | а√资源新版在线天堂 | 日本丰满熟妇videos | 澳门永久av免费网站 | 最近中文2019字幕第二页 | 无码人妻出轨黑人中文字幕 | 亚洲国产成人a精品不卡在线 | 人妻少妇精品无码专区二区 | 曰本女人与公拘交酡免费视频 | 欧美熟妇另类久久久久久多毛 | 无码人妻久久一区二区三区不卡 | 国产亚洲精品久久久久久国模美 | 精品国产一区av天美传媒 | av无码电影一区二区三区 | 国产精品国产自线拍免费软件 | 国产免费久久久久久无码 | 激情人妻另类人妻伦 | 红桃av一区二区三区在线无码av | 亚洲精品鲁一鲁一区二区三区 | 国产美女极度色诱视频www | 久久久久亚洲精品中文字幕 | 娇妻被黑人粗大高潮白浆 | 亚洲综合另类小说色区 | 色欲av亚洲一区无码少妇 | 牲交欧美兽交欧美 | 亚洲日韩av片在线观看 | 免费无码午夜福利片69 | 99riav国产精品视频 | 特黄特色大片免费播放器图片 | 国产人成高清在线视频99最全资源 | 久久精品一区二区三区四区 | 暴力强奷在线播放无码 | 欧美freesex黑人又粗又大 | 国产亚洲日韩欧美另类第八页 | 精品国精品国产自在久国产87 | 欧美阿v高清资源不卡在线播放 | 色综合视频一区二区三区 | 亚洲小说春色综合另类 | 久久精品国产一区二区三区 | 国产精品无码成人午夜电影 | 久久国产精品二国产精品 | 欧美日韩在线亚洲综合国产人 | 少妇无套内谢久久久久 | 国产精品-区区久久久狼 | 男女爱爱好爽视频免费看 | 亚洲国产精品久久人人爱 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产熟妇另类久久久久 | 国产手机在线αⅴ片无码观看 | 免费看少妇作爱视频 | 国产成人亚洲综合无码 | 国产午夜精品一区二区三区嫩草 | 扒开双腿吃奶呻吟做受视频 | 久久午夜无码鲁丝片秋霞 | 人妻aⅴ无码一区二区三区 | 麻豆蜜桃av蜜臀av色欲av | 国产亚洲精品久久久ai换 | 国产九九九九九九九a片 | 亚洲精品无码国产 | 中文字幕无码av波多野吉衣 | 国产一区二区三区精品视频 | 国产精品va在线观看无码 | 夜夜躁日日躁狠狠久久av | 亚洲色欲色欲天天天www | 97夜夜澡人人双人人人喊 | 午夜精品久久久久久久久 | www成人国产高清内射 | 国产成人无码av在线影院 | 国产精品99久久精品爆乳 | 国产亚洲日韩欧美另类第八页 | 国产极品视觉盛宴 | 成人精品天堂一区二区三区 | 久久精品视频在线看15 | 午夜福利不卡在线视频 | 国产精品久久精品三级 | 日本熟妇人妻xxxxx人hd | 国产精品人人妻人人爽 | 国产人妻大战黑人第1集 | 国产av久久久久精东av | 国产精品爱久久久久久久 | 国产免费观看黄av片 | 九九综合va免费看 | 亚洲色大成网站www国产 | 国产无遮挡又黄又爽又色 | 亚洲精品鲁一鲁一区二区三区 | 天堂а√在线地址中文在线 | 老熟妇乱子伦牲交视频 | 中文无码伦av中文字幕 | 久久99久久99精品中文字幕 | 中文字幕乱码亚洲无线三区 | 国产精品久久久久久亚洲毛片 | 伊在人天堂亚洲香蕉精品区 | 捆绑白丝粉色jk震动捧喷白浆 | 最新国产麻豆aⅴ精品无码 | 日韩精品无码一本二本三本色 | 影音先锋中文字幕无码 | 性欧美疯狂xxxxbbbb | 亚洲 a v无 码免 费 成 人 a v | 99在线 | 亚洲 | 精品乱码久久久久久久 | 日本饥渴人妻欲求不满 | 欧美高清在线精品一区 | 国产成人精品一区二区在线小狼 | 男人的天堂av网站 | 国产内射爽爽大片视频社区在线 | 亚洲自偷自偷在线制服 | 精品乱子伦一区二区三区 | 狠狠噜狠狠狠狠丁香五月 | 国产精品亚洲专区无码不卡 | а√资源新版在线天堂 | 久久99精品久久久久久动态图 | 亚洲综合无码一区二区三区 | 国产午夜精品一区二区三区嫩草 | 99久久久无码国产aaa精品 | 2019午夜福利不卡片在线 | 午夜性刺激在线视频免费 | 日本欧美一区二区三区乱码 | 日日噜噜噜噜夜夜爽亚洲精品 | 国产亚洲精品久久久久久国模美 | 久久成人a毛片免费观看网站 | 又大又硬又黄的免费视频 | 丰满人妻被黑人猛烈进入 | 亚洲熟妇色xxxxx亚洲 | 亚洲欧洲日本综合aⅴ在线 | 亚洲乱码国产乱码精品精 | 毛片内射-百度 | 国产在线aaa片一区二区99 | 欧美性色19p | 在线 国产 欧美 亚洲 天堂 | 日本成熟视频免费视频 | 麻豆蜜桃av蜜臀av色欲av | 女高中生第一次破苞av | 色婷婷综合中文久久一本 | 免费男性肉肉影院 | 国产色xx群视频射精 | 亚洲日韩精品欧美一区二区 | 正在播放老肥熟妇露脸 | 欧美真人作爱免费视频 | 99精品视频在线观看免费 | 久久国产自偷自偷免费一区调 | 国产两女互慰高潮视频在线观看 | 人妻少妇被猛烈进入中文字幕 | 亚洲中文字幕在线观看 | 国产精品美女久久久 | 久久午夜无码鲁丝片秋霞 | 妺妺窝人体色www在线小说 | a片免费视频在线观看 | 精品亚洲成av人在线观看 | 美女毛片一区二区三区四区 | 在线观看免费人成视频 | 狠狠亚洲超碰狼人久久 | 国产高清不卡无码视频 | 亚洲区小说区激情区图片区 | 国产成人无码区免费内射一片色欲 | 四虎影视成人永久免费观看视频 | 久9re热视频这里只有精品 | 男女爱爱好爽视频免费看 | 精品国精品国产自在久国产87 | 老子影院午夜精品无码 | 国产精品亚洲一区二区三区喷水 | 美女张开腿让人桶 | 99久久精品无码一区二区毛片 | 少女韩国电视剧在线观看完整 | 亚洲成a人片在线观看无码 | 性生交大片免费看l | 国产精品99爱免费视频 | 国产免费久久久久久无码 | 欧美成人午夜精品久久久 | 久激情内射婷内射蜜桃人妖 | 国产真实伦对白全集 | 扒开双腿吃奶呻吟做受视频 | 中文字幕无码av激情不卡 | 免费男性肉肉影院 | av无码不卡在线观看免费 | 国产人妻精品一区二区三区不卡 | 免费观看黄网站 | 亚洲日韩中文字幕在线播放 | 久久精品国产一区二区三区肥胖 | 中文字幕无线码免费人妻 | 俺去俺来也在线www色官网 | 久久国产精品萌白酱免费 | 一本久道久久综合婷婷五月 | 在线播放亚洲第一字幕 | 爆乳一区二区三区无码 | 国产午夜福利100集发布 | 国产一区二区不卡老阿姨 | 国产无遮挡吃胸膜奶免费看 | 玩弄中年熟妇正在播放 | 性啪啪chinese东北女人 | 377p欧洲日本亚洲大胆 | 国产成人无码一二三区视频 | 最近中文2019字幕第二页 | 国产精品福利视频导航 | 男女下面进入的视频免费午夜 | a在线观看免费网站大全 | 国产无套内射久久久国产 | 在教室伦流澡到高潮hnp视频 | 天堂在线观看www | 精品久久8x国产免费观看 | 久久精品视频在线看15 | 一个人看的www免费视频在线观看 | 帮老师解开蕾丝奶罩吸乳网站 | 在线成人www免费观看视频 | 久精品国产欧美亚洲色aⅴ大片 | 午夜免费福利小电影 | 玩弄少妇高潮ⅹxxxyw | 18禁黄网站男男禁片免费观看 | 欧美一区二区三区视频在线观看 | 四虎4hu永久免费 | 377p欧洲日本亚洲大胆 | 蜜桃视频插满18在线观看 | 亚洲精品美女久久久久久久 | 中文字幕av无码一区二区三区电影 | 中文字幕日产无线码一区 | av人摸人人人澡人人超碰下载 | 女人被男人爽到呻吟的视频 | 377p欧洲日本亚洲大胆 | 亚洲区欧美区综合区自拍区 | 无码精品国产va在线观看dvd | 国产成人无码区免费内射一片色欲 | 狠狠躁日日躁夜夜躁2020 | 精品无码成人片一区二区98 | 久久精品国产一区二区三区肥胖 | 97精品人妻一区二区三区香蕉 | 久久综合色之久久综合 | 国产艳妇av在线观看果冻传媒 | 丰满护士巨好爽好大乳 | 天堂а√在线地址中文在线 | 免费中文字幕日韩欧美 | 成人三级无码视频在线观看 | 在线天堂新版最新版在线8 | 久久综合网欧美色妞网 | 精品无码国产一区二区三区av | 久久久久久久女国产乱让韩 | 99精品国产综合久久久久五月天 | 久久亚洲日韩精品一区二区三区 | 欧美日韩综合一区二区三区 | 好屌草这里只有精品 | 高清国产亚洲精品自在久久 | 久久无码专区国产精品s | 4hu四虎永久在线观看 | 欧洲欧美人成视频在线 | 熟女体下毛毛黑森林 | 曰本女人与公拘交酡免费视频 | 欧洲精品码一区二区三区免费看 | 国产成人无码午夜视频在线观看 | 久久久久免费精品国产 | 伊人色综合久久天天小片 | 久久伊人色av天堂九九小黄鸭 | 无人区乱码一区二区三区 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 国产真实伦对白全集 | 亚洲一区二区观看播放 | 中文字幕无码av激情不卡 | 少妇邻居内射在线 | 欧美黑人巨大xxxxx | 野外少妇愉情中文字幕 | 正在播放老肥熟妇露脸 | 无码国内精品人妻少妇 | 无码av免费一区二区三区试看 | 国产精品无码一区二区三区不卡 | 成人一区二区免费视频 | 亚洲国产精品一区二区第一页 | 国产激情无码一区二区app | 少妇被粗大的猛进出69影院 | 欧美日韩人成综合在线播放 | 欧美精品国产综合久久 | 内射后入在线观看一区 | 亚洲日韩中文字幕在线播放 | 中文字幕乱码人妻无码久久 | 丝袜美腿亚洲一区二区 | 日韩 欧美 动漫 国产 制服 | 少妇被粗大的猛进出69影院 | 国产亚洲美女精品久久久2020 | 国产av一区二区三区最新精品 | 成人欧美一区二区三区 | 无码中文字幕色专区 | 精品人妻av区 | 亚洲高清偷拍一区二区三区 | 图片小说视频一区二区 | 六十路熟妇乱子伦 | 国产精品内射视频免费 | 国产超碰人人爽人人做人人添 | 青青草原综合久久大伊人精品 | 久久亚洲国产成人精品性色 | 一本色道久久综合狠狠躁 | 久久综合久久自在自线精品自 | 亚洲色欲色欲天天天www | 久久综合色之久久综合 | 乱人伦中文视频在线观看 | 国产区女主播在线观看 | √天堂中文官网8在线 | 精品国精品国产自在久国产87 | 97精品人妻一区二区三区香蕉 | 欧美 日韩 亚洲 在线 | 国产精品va在线播放 | 欧美人与物videos另类 | 内射老妇bbwx0c0ck | 亚洲熟女一区二区三区 | 亚洲色在线无码国产精品不卡 | 97久久精品无码一区二区 | 日产国产精品亚洲系列 | 四虎国产精品一区二区 | 国产成人无码av片在线观看不卡 | 亚洲区欧美区综合区自拍区 | 国产人妻精品一区二区三区 | 俄罗斯老熟妇色xxxx | 亚洲精品午夜国产va久久成人 | 丰满人妻一区二区三区免费视频 | 成人免费视频视频在线观看 免费 | 免费播放一区二区三区 | 久久婷婷五月综合色国产香蕉 | 丁香花在线影院观看在线播放 | 无遮挡国产高潮视频免费观看 | 久久久久久九九精品久 | 日韩少妇白浆无码系列 | 国产口爆吞精在线视频 | 久久精品无码一区二区三区 | 国产成人无码av一区二区 | 又大又黄又粗又爽的免费视频 | 欧美丰满熟妇xxxx | 欧美野外疯狂做受xxxx高潮 | 国产精品igao视频网 | 国产亚洲精品久久久久久国模美 | 久久国产劲爆∧v内射 | 中文字幕无码av波多野吉衣 | 久久国产精品偷任你爽任你 | 男女超爽视频免费播放 | 午夜福利电影 | 亚洲无人区一区二区三区 | 日本高清一区免费中文视频 | 99视频精品全部免费免费观看 | 久久综合九色综合97网 | 精品无码一区二区三区爱欲 | 久久亚洲日韩精品一区二区三区 | 欧美丰满老熟妇xxxxx性 | 亚洲男人av天堂午夜在 | 无码av免费一区二区三区试看 | 荫蒂添的好舒服视频囗交 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 中文字幕乱码人妻二区三区 | 久久久久av无码免费网 | 欧美午夜特黄aaaaaa片 | 偷窥日本少妇撒尿chinese | 欧美日韩一区二区免费视频 | 欧美老熟妇乱xxxxx | 乱人伦人妻中文字幕无码 | 午夜精品久久久久久久久 | 人妻少妇精品无码专区动漫 | 亚洲爆乳无码专区 | 九九在线中文字幕无码 | 最近的中文字幕在线看视频 | 国产片av国语在线观看 | 青青草原综合久久大伊人精品 | 国产办公室秘书无码精品99 | 老司机亚洲精品影院无码 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 久久久久se色偷偷亚洲精品av | 99久久久无码国产精品免费 | 国产精品高潮呻吟av久久 | 欧美性猛交xxxx富婆 | 欧美日韩一区二区三区自拍 | 午夜丰满少妇性开放视频 | 国产精华av午夜在线观看 | 爱做久久久久久 | 成人毛片一区二区 | 青春草在线视频免费观看 | 精品一区二区三区无码免费视频 | 狂野欧美激情性xxxx | 午夜福利电影 | 欧美人与禽zoz0性伦交 | 久久www免费人成人片 | 欧美变态另类xxxx | 人妻少妇精品无码专区二区 | 性色av无码免费一区二区三区 | 色妞www精品免费视频 | 精品乱码久久久久久久 | 精品国精品国产自在久国产87 | 激情综合激情五月俺也去 | 国产又爽又黄又刺激的视频 | 亚洲国产精品无码久久久久高潮 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲乱码国产乱码精品精 | 亚洲精品国偷拍自产在线观看蜜桃 | 日韩精品a片一区二区三区妖精 | 成人无码视频免费播放 | 日韩人妻系列无码专区 | 亚洲精品成a人在线观看 | 熟妇人妻无码xxx视频 | 欧美日韩精品 | 欧美日韩精品 | 2019午夜福利不卡片在线 | 最新国产麻豆aⅴ精品无码 | 天天做天天爱天天爽综合网 | 色综合久久久无码网中文 | 无码一区二区三区在线 | 狠狠色噜噜狠狠狠狠7777米奇 | 成在人线av无码免观看麻豆 | 亚洲精品久久久久久久久久久 | 亚洲日本va午夜在线电影 | 久久久久亚洲精品中文字幕 | 少妇人妻偷人精品无码视频 | 性开放的女人aaa片 | 久久精品女人天堂av免费观看 | 扒开双腿疯狂进出爽爽爽视频 | 久久精品女人的天堂av | 国产精品第一区揄拍无码 | 亚洲中文字幕成人无码 | av无码电影一区二区三区 | 国产精品亚洲专区无码不卡 | 国产黑色丝袜在线播放 | 又粗又大又硬毛片免费看 | 在线亚洲高清揄拍自拍一品区 | 亚洲综合久久一区二区 | 久久精品国产一区二区三区 | 丰满少妇高潮惨叫视频 | 精品少妇爆乳无码av无码专区 | 成熟人妻av无码专区 | 麻豆人妻少妇精品无码专区 | 国产成人精品一区二区在线小狼 | 又湿又紧又大又爽a视频国产 | 亚洲色欲久久久综合网东京热 | 色老头在线一区二区三区 | 丰满岳乱妇在线观看中字无码 | 久久久久亚洲精品男人的天堂 | 欧洲vodafone精品性 | 无码纯肉视频在线观看 | 美女黄网站人色视频免费国产 | 丁香啪啪综合成人亚洲 | 欧美人与禽猛交狂配 | 国产精品资源一区二区 | 中国女人内谢69xxxxxa片 | 欧美喷潮久久久xxxxx | 无码国内精品人妻少妇 | 岛国片人妻三上悠亚 | 亚洲色在线无码国产精品不卡 | 国产午夜无码精品免费看 | 欧美精品免费观看二区 | 亚洲の无码国产の无码影院 | 国产亚洲精品久久久闺蜜 | 夜夜躁日日躁狠狠久久av | 黑人粗大猛烈进出高潮视频 | 欧美日韩一区二区三区自拍 | 亚洲欧美日韩国产精品一区二区 | 亚洲va欧美va天堂v国产综合 | 久久精品国产99精品亚洲 | 丰满妇女强制高潮18xxxx | 欧美野外疯狂做受xxxx高潮 | 成人欧美一区二区三区黑人 | 欧美人与禽猛交狂配 | 日本乱偷人妻中文字幕 | 中文字幕久久久久人妻 | 精品人人妻人人澡人人爽人人 | 精品一区二区三区波多野结衣 | 国产精品手机免费 | 两性色午夜视频免费播放 | 久久久久久久人妻无码中文字幕爆 | 国产成人久久精品流白浆 | 亚洲自偷精品视频自拍 | 久久精品国产99精品亚洲 | 亚洲国产精品久久久天堂 | 亚洲中文无码av永久不收费 | 欧美日韩精品 | 丰满少妇熟乱xxxxx视频 | 强辱丰满人妻hd中文字幕 | 精品国偷自产在线视频 | 水蜜桃av无码 | 欧美成人家庭影院 | 亚洲欧美综合区丁香五月小说 | 黄网在线观看免费网站 | 99久久婷婷国产综合精品青草免费 | 国产免费久久精品国产传媒 | 亚洲国产一区二区三区在线观看 | 又大又硬又爽免费视频 | 久久国产36精品色熟妇 | 欧美一区二区三区 | 任你躁国产自任一区二区三区 | 中文字幕 亚洲精品 第1页 | 色综合久久88色综合天天 | 久久99精品久久久久婷婷 | 全黄性性激高免费视频 | 国产网红无码精品视频 | 中文字幕无码av激情不卡 | 国产成人无码午夜视频在线观看 | 成人精品视频一区二区 | 少妇高潮一区二区三区99 | 成人一在线视频日韩国产 | 国产真实乱对白精彩久久 | 精品夜夜澡人妻无码av蜜桃 | 国产亚洲精品久久久ai换 | 国产后入清纯学生妹 | 丰满肥臀大屁股熟妇激情视频 | 激情国产av做激情国产爱 | 亚洲一区二区三区四区 | 国产av一区二区精品久久凹凸 | 亚洲精品一区国产 | 亚洲日韩av一区二区三区中文 | 欧美丰满少妇xxxx性 | 老头边吃奶边弄进去呻吟 | 在线播放亚洲第一字幕 | 在线亚洲高清揄拍自拍一品区 | 国产乱人无码伦av在线a | 亚洲成av人片天堂网无码】 | 帮老师解开蕾丝奶罩吸乳网站 | 性色欲情网站iwww九文堂 | 久久久无码中文字幕久... | 女人和拘做爰正片视频 | 亚洲人成人无码网www国产 | 高清国产亚洲精品自在久久 | 免费无码一区二区三区蜜桃大 | 色综合视频一区二区三区 | 亚洲a无码综合a国产av中文 | 女高中生第一次破苞av | 国产内射爽爽大片视频社区在线 | 亚洲成a人片在线观看无码3d | 日本熟妇浓毛 | 无码吃奶揉捏奶头高潮视频 | 一本大道久久东京热无码av | 欧美人与善在线com | 性欧美牲交xxxxx视频 | 国产成人人人97超碰超爽8 | 亚洲色成人中文字幕网站 | 最近的中文字幕在线看视频 | 嫩b人妻精品一区二区三区 | 欧美乱妇无乱码大黄a片 | 亚洲精品一区二区三区在线观看 | 性史性农村dvd毛片 | 三级4级全黄60分钟 | 99re在线播放 | 国产av无码专区亚洲a∨毛片 | 亚洲色大成网站www | 麻花豆传媒剧国产免费mv在线 | 亚洲精品久久久久久久久久久 | 久久精品无码一区二区三区 | 久久久久久九九精品久 | 秋霞特色aa大片 | 水蜜桃亚洲一二三四在线 | 天下第一社区视频www日本 | 国产三级精品三级男人的天堂 | 国产熟妇高潮叫床视频播放 | 亚洲一区av无码专区在线观看 | 国产免费久久久久久无码 | 少妇厨房愉情理9仑片视频 | 欧美老妇与禽交 | 国产精品无码一区二区桃花视频 | 玩弄中年熟妇正在播放 | 亚洲国产综合无码一区 | 成人免费视频视频在线观看 免费 | 欧美丰满老熟妇xxxxx性 | 久久午夜无码鲁丝片午夜精品 | 一二三四在线观看免费视频 | 国产成人无码av在线影院 | 无码纯肉视频在线观看 | 丰满肥臀大屁股熟妇激情视频 | 亚洲春色在线视频 | 亚洲一区二区三区四区 | 熟妇人妻激情偷爽文 | 97久久国产亚洲精品超碰热 | 荡女精品导航 | 色爱情人网站 | 18禁止看的免费污网站 | 亚洲人成网站免费播放 | 久久精品中文字幕一区 | 国内综合精品午夜久久资源 | 日日摸日日碰夜夜爽av | 粉嫩少妇内射浓精videos | 丰腴饱满的极品熟妇 | 98国产精品综合一区二区三区 | 少妇人妻大乳在线视频 | 国产成人人人97超碰超爽8 | 成人一在线视频日韩国产 | 国内综合精品午夜久久资源 | 国产人妻精品一区二区三区不卡 | 高清国产亚洲精品自在久久 | 中文字幕无码日韩欧毛 | 免费看男女做好爽好硬视频 | 国产人妻精品一区二区三区不卡 | 国产精品久久久午夜夜伦鲁鲁 | 午夜无码人妻av大片色欲 | 国产色精品久久人妻 | 大胆欧美熟妇xx | 国产一区二区不卡老阿姨 | 欧美人与牲动交xxxx | 玩弄少妇高潮ⅹxxxyw | 亚洲色偷偷男人的天堂 | 国产黄在线观看免费观看不卡 | 久久人人爽人人爽人人片ⅴ | 国产偷抇久久精品a片69 | 久久精品丝袜高跟鞋 | 久久久久成人片免费观看蜜芽 | 98国产精品综合一区二区三区 | 国产精品人妻一区二区三区四 | 国产精品久久久久久亚洲毛片 | 荫蒂被男人添的好舒服爽免费视频 | 久久国内精品自在自线 | 国内老熟妇对白xxxxhd | 99久久人妻精品免费一区 | 麻豆果冻传媒2021精品传媒一区下载 | 中文字幕乱码人妻无码久久 | 久久国产劲爆∧v内射 | 131美女爱做视频 | 青草青草久热国产精品 | 少妇久久久久久人妻无码 | 久久久无码中文字幕久... | 国产电影无码午夜在线播放 | 丰满肥臀大屁股熟妇激情视频 | 免费播放一区二区三区 | 51国偷自产一区二区三区 | 国产凸凹视频一区二区 | 人妻中文无码久热丝袜 | 久久久久se色偷偷亚洲精品av | 伊人久久大香线蕉亚洲 | 久久伊人色av天堂九九小黄鸭 | 久久综合给久久狠狠97色 | 久久99精品久久久久久 | 成人欧美一区二区三区黑人 | 男女超爽视频免费播放 | 好爽又高潮了毛片免费下载 | 天天躁日日躁狠狠躁免费麻豆 | 美女黄网站人色视频免费国产 | 亚欧洲精品在线视频免费观看 | 欧洲精品码一区二区三区免费看 | 午夜无码人妻av大片色欲 | 精品无人国产偷自产在线 | 免费人成网站视频在线观看 | 香蕉久久久久久av成人 | 亚洲成a人一区二区三区 | 又大又紧又粉嫩18p少妇 | 成在人线av无码免费 | 中文字幕乱码人妻无码久久 | 国产精品久久福利网站 | 亚洲日韩av一区二区三区四区 | 黑人粗大猛烈进出高潮视频 | 亚洲呦女专区 | 夜夜影院未满十八勿进 | 国内精品九九久久久精品 | 国产农村乱对白刺激视频 | 一本大道伊人av久久综合 | 成人动漫在线观看 | 日韩av无码一区二区三区 | 人妻体内射精一区二区三四 | 亚洲欧美中文字幕5发布 | 18无码粉嫩小泬无套在线观看 | 亚洲伊人久久精品影院 | 国産精品久久久久久久 | 午夜免费福利小电影 | 国产激情无码一区二区 | 日韩精品久久久肉伦网站 | 欧美肥老太牲交大战 | 日韩精品a片一区二区三区妖精 | 粗大的内捧猛烈进出视频 | 麻豆国产丝袜白领秘书在线观看 | 成人aaa片一区国产精品 | 亚洲成熟女人毛毛耸耸多 | 在教室伦流澡到高潮hnp视频 | 亚洲午夜福利在线观看 | 亚洲自偷精品视频自拍 | 国色天香社区在线视频 | 激情国产av做激情国产爱 | 亚洲男女内射在线播放 | 亚洲精品中文字幕 | 欧美国产日产一区二区 | 久久国产精品萌白酱免费 | aⅴ在线视频男人的天堂 | 在线观看免费人成视频 | 亚洲 另类 在线 欧美 制服 | 亚洲乱码中文字幕在线 | 爆乳一区二区三区无码 | 亚洲中文字幕在线观看 | 精品国产一区av天美传媒 | 99久久精品国产一区二区蜜芽 | 中文字幕无码免费久久99 | 水蜜桃色314在线观看 | aa片在线观看视频在线播放 | 色五月丁香五月综合五月 | 人妻aⅴ无码一区二区三区 | 99视频精品全部免费免费观看 | 亚洲a无码综合a国产av中文 | 亚洲人成网站色7799 | 乱码午夜-极国产极内射 | 欧美日韩一区二区三区自拍 | 四虎影视成人永久免费观看视频 | 国产精品久久久午夜夜伦鲁鲁 | 99精品视频在线观看免费 | 婷婷综合久久中文字幕蜜桃三电影 | 亚洲精品国产第一综合99久久 | 东京热一精品无码av | 精品久久久无码中文字幕 | 国产成人人人97超碰超爽8 | 亚洲精品中文字幕 | 对白脏话肉麻粗话av | 色 综合 欧美 亚洲 国产 | 中文字幕 人妻熟女 | 成人三级无码视频在线观看 | 日本又色又爽又黄的a片18禁 | 在线а√天堂中文官网 | 亚无码乱人伦一区二区 | 国产人成高清在线视频99最全资源 | 精品乱子伦一区二区三区 | 中文字幕av无码一区二区三区电影 | 国产成人无码午夜视频在线观看 | 国产av人人夜夜澡人人爽麻豆 | 婷婷五月综合缴情在线视频 | 色一情一乱一伦一区二区三欧美 | 清纯唯美经典一区二区 | 国产情侣作爱视频免费观看 | 国产精品亚洲五月天高清 | 特级做a爰片毛片免费69 | 7777奇米四色成人眼影 | 久精品国产欧美亚洲色aⅴ大片 | 国产精品igao视频网 | 亚洲综合久久一区二区 | 无码av最新清无码专区吞精 | 久久天天躁夜夜躁狠狠 | 国产一区二区不卡老阿姨 | 亚洲最大成人网站 | 天堂久久天堂av色综合 | 乱码午夜-极国产极内射 | 日韩精品无码免费一区二区三区 | 色欲久久久天天天综合网精品 | 精品国产乱码久久久久乱码 | 国产精品多人p群无码 | 1000部啪啪未满十八勿入下载 | 亚洲欧美色中文字幕在线 | 精品成在人线av无码免费看 | 奇米影视7777久久精品人人爽 | 狠狠色丁香久久婷婷综合五月 | 国内丰满熟女出轨videos | 丝袜人妻一区二区三区 | 精品日本一区二区三区在线观看 | 国产精品a成v人在线播放 | 夜夜高潮次次欢爽av女 | 丰满少妇弄高潮了www | 人人爽人人澡人人人妻 | 国产精品国产三级国产专播 | 无码人妻av免费一区二区三区 | 熟妇人妻激情偷爽文 | 在线 国产 欧美 亚洲 天堂 | 国产黑色丝袜在线播放 | 中文亚洲成a人片在线观看 | 在线观看欧美一区二区三区 | 中国女人内谢69xxxx | 好爽又高潮了毛片免费下载 | 亚洲阿v天堂在线 | 性色欲情网站iwww九文堂 | 国语自产偷拍精品视频偷 | 99久久亚洲精品无码毛片 | а√天堂www在线天堂小说 | 强辱丰满人妻hd中文字幕 | 久久久久国色av免费观看性色 | 女人被男人爽到呻吟的视频 | 久久99国产综合精品 | 久久综合给久久狠狠97色 | 强开小婷嫩苞又嫩又紧视频 | 熟女少妇人妻中文字幕 | 九月婷婷人人澡人人添人人爽 | 亚洲中文字幕无码一久久区 | 亚洲中文字幕乱码av波多ji | 国产艳妇av在线观看果冻传媒 | 亚洲国产精品毛片av不卡在线 | 婷婷丁香六月激情综合啪 | 日日噜噜噜噜夜夜爽亚洲精品 | 亚洲 另类 在线 欧美 制服 | 国产精品嫩草久久久久 | 免费无码av一区二区 | 欧美激情综合亚洲一二区 | 亚洲啪av永久无码精品放毛片 | 强伦人妻一区二区三区视频18 | 国产成人综合在线女婷五月99播放 | 国产午夜精品一区二区三区嫩草 | 中文字幕无码日韩欧毛 | 国内老熟妇对白xxxxhd | 熟女少妇人妻中文字幕 | 宝宝好涨水快流出来免费视频 | 人妻无码αv中文字幕久久琪琪布 | 久久久久久国产精品无码下载 | 午夜男女很黄的视频 | 亚洲中文无码av永久不收费 | 露脸叫床粗话东北少妇 | 亚洲日韩一区二区三区 | 97久久精品无码一区二区 | 桃花色综合影院 | 国产无遮挡吃胸膜奶免费看 | 午夜精品一区二区三区在线观看 | 最新国产麻豆aⅴ精品无码 | 国产又爽又猛又粗的视频a片 | 久久精品国产亚洲精品 | 99视频精品全部免费免费观看 | 日本肉体xxxx裸交 | 国产精品久久久久久久影院 | 丰满妇女强制高潮18xxxx | 无码人妻丰满熟妇区五十路百度 | 国产精品亚洲一区二区三区喷水 | 日本乱人伦片中文三区 | 正在播放老肥熟妇露脸 | 爆乳一区二区三区无码 | 精品成人av一区二区三区 | 国产亚洲精品精品国产亚洲综合 | 国产欧美熟妇另类久久久 | 狠狠躁日日躁夜夜躁2020 | 久青草影院在线观看国产 | 久久久中文久久久无码 | 成人免费无码大片a毛片 | 亚洲日韩一区二区三区 | 亚洲中文无码av永久不收费 | 亚洲精品无码人妻无码 | 2020最新国产自产精品 | 国产美女精品一区二区三区 | 久久久精品成人免费观看 | 98国产精品综合一区二区三区 | 欧美日韩一区二区免费视频 | 又粗又大又硬毛片免费看 | 免费视频欧美无人区码 | 久久久精品456亚洲影院 | 麻豆国产人妻欲求不满谁演的 | 日日干夜夜干 | 日本丰满熟妇videos | 少妇厨房愉情理9仑片视频 | 乱人伦人妻中文字幕无码 | 亚洲成色www久久网站 | 高清不卡一区二区三区 | 亚洲国产精品无码一区二区三区 | 内射白嫩少妇超碰 | 亚洲狠狠婷婷综合久久 | 亚洲成av人综合在线观看 | 欧美人与动性行为视频 | 国产精品永久免费视频 | 久久国产自偷自偷免费一区调 | 男人的天堂av网站 | 无人区乱码一区二区三区 | 红桃av一区二区三区在线无码av | 日韩精品一区二区av在线 | 久久精品无码一区二区三区 | 无码任你躁久久久久久久 | 国产两女互慰高潮视频在线观看 | 女人被男人躁得好爽免费视频 | 曰韩少妇内射免费播放 | 蜜臀aⅴ国产精品久久久国产老师 | v一区无码内射国产 | 欧美老熟妇乱xxxxx | 亚洲国产午夜精品理论片 | 久久人人爽人人爽人人片av高清 | 好爽又高潮了毛片免费下载 | 色噜噜亚洲男人的天堂 | 青青草原综合久久大伊人精品 | 麻豆人妻少妇精品无码专区 | 丰满岳乱妇在线观看中字无码 | 国产色xx群视频射精 | 999久久久国产精品消防器材 | 无码人妻丰满熟妇区毛片18 | 亚洲成色在线综合网站 | 午夜嘿嘿嘿影院 | 无码精品国产va在线观看dvd | 精品国产av色一区二区深夜久久 | 中文无码成人免费视频在线观看 | 久久久久久亚洲精品a片成人 | 欧美黑人性暴力猛交喷水 | 中文亚洲成a人片在线观看 | 狂野欧美性猛xxxx乱大交 | 日韩精品a片一区二区三区妖精 | 精品夜夜澡人妻无码av蜜桃 | 国内精品人妻无码久久久影院 | 久久 国产 尿 小便 嘘嘘 | 欧美zoozzooz性欧美 | 99久久人妻精品免费一区 | 狠狠色欧美亚洲狠狠色www | ass日本丰满熟妇pics | 精品无码国产自产拍在线观看蜜 | 中文字幕乱妇无码av在线 | 成人欧美一区二区三区黑人免费 | 内射后入在线观看一区 | а√资源新版在线天堂 | 亚洲中文字幕成人无码 | 亚洲综合在线一区二区三区 | 久久国内精品自在自线 | 亚洲中文字幕在线无码一区二区 | 免费视频欧美无人区码 | 久久午夜无码鲁丝片午夜精品 | 国产va免费精品观看 | www国产亚洲精品久久网站 | 色婷婷久久一区二区三区麻豆 | a片在线免费观看 | 久久成人a毛片免费观看网站 | 东京一本一道一二三区 | 51国偷自产一区二区三区 | 国产欧美精品一区二区三区 | 久久久久99精品成人片 | 国产性生大片免费观看性 | 99精品视频在线观看免费 | 午夜无码区在线观看 | 国产精品视频免费播放 | 天干天干啦夜天干天2017 | 麻豆国产人妻欲求不满 | 亚洲乱码中文字幕在线 | 欧洲精品码一区二区三区免费看 | 动漫av网站免费观看 | 狠狠综合久久久久综合网 | 一本色道婷婷久久欧美 | 亚洲人成影院在线无码按摩店 | 男人扒开女人内裤强吻桶进去 | 日本爽爽爽爽爽爽在线观看免 | 无码人妻丰满熟妇区毛片18 | 性欧美疯狂xxxxbbbb | 乱码av麻豆丝袜熟女系列 | 在线播放免费人成毛片乱码 | 久久精品无码一区二区三区 | 欧美日本日韩 | 午夜福利电影 | 国产人妖乱国产精品人妖 | 日产精品99久久久久久 | 国产成人无码av片在线观看不卡 | 日韩av无码中文无码电影 | 亚洲伊人久久精品影院 | 东京无码熟妇人妻av在线网址 | 国产精品欧美成人 | 亚洲 欧美 激情 小说 另类 | 久久久久久久久蜜桃 | 性做久久久久久久久 | 国产精品美女久久久 | 高清不卡一区二区三区 | 一个人免费观看的www视频 | 国产乱人无码伦av在线a | 国产在线精品一区二区三区直播 | 丰满人妻精品国产99aⅴ | 亚洲欧美日韩国产精品一区二区 | 免费国产成人高清在线观看网站 | 丝袜 中出 制服 人妻 美腿 | 中文字幕av无码一区二区三区电影 | 精品国产青草久久久久福利 | 欧美丰满熟妇xxxx | www一区二区www免费 | 国产偷国产偷精品高清尤物 | 精品偷自拍另类在线观看 | 国产一区二区不卡老阿姨 | 日韩av无码一区二区三区不卡 | 青青草原综合久久大伊人精品 | 免费国产黄网站在线观看 | 亚洲七七久久桃花影院 | 牲欲强的熟妇农村老妇女视频 | 狂野欧美性猛xxxx乱大交 | 中文字幕精品av一区二区五区 | 欧洲vodafone精品性 | 国产精品毛片一区二区 | 人人爽人人爽人人片av亚洲 | 真人与拘做受免费视频 | 久久亚洲国产成人精品性色 | 中文字幕无码人妻少妇免费 | 日本xxxx色视频在线观看免费 | 天天躁日日躁狠狠躁免费麻豆 | 亚洲经典千人经典日产 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 色妞www精品免费视频 | 99久久精品午夜一区二区 | 黑人玩弄人妻中文在线 | 亚洲春色在线视频 | 自拍偷自拍亚洲精品10p | 日产国产精品亚洲系列 | 欧美国产日韩亚洲中文 | 永久免费观看国产裸体美女 | 亚洲国产精品毛片av不卡在线 | 国产精品人人妻人人爽 | 人妻中文无码久热丝袜 | 国产区女主播在线观看 | 日本丰满熟妇videos | 亚洲熟女一区二区三区 | 国产香蕉尹人综合在线观看 | 亚洲a无码综合a国产av中文 | 波多野结衣av在线观看 | 精品国产av色一区二区深夜久久 | 成人动漫在线观看 | 久久综合网欧美色妞网 | 麻豆果冻传媒2021精品传媒一区下载 | 久久99国产综合精品 | 亚洲色成人中文字幕网站 | 日韩亚洲欧美精品综合 | 99久久精品午夜一区二区 | 成人精品视频一区二区三区尤物 | 大地资源网第二页免费观看 | 国产人妻人伦精品1国产丝袜 | 欧美日本免费一区二区三区 | 波多野结衣av在线观看 | 亚洲一区二区三区在线观看网站 | 免费无码午夜福利片69 | 欧美三级a做爰在线观看 | 亚洲熟妇色xxxxx亚洲 | 色欲综合久久中文字幕网 | 亚洲七七久久桃花影院 | 亚洲精品无码国产 | 午夜福利电影 | 免费乱码人妻系列无码专区 | 四虎永久在线精品免费网址 | 少妇无码av无码专区在线观看 | 国产xxx69麻豆国语对白 | 国产va免费精品观看 | 波多野结衣av一区二区全免费观看 | 欧美阿v高清资源不卡在线播放 | 亚洲精品国产精品乱码不卡 | 国产精品va在线观看无码 | 伊人久久大香线蕉亚洲 | 国产精品99久久精品爆乳 | 国产成人综合色在线观看网站 | 一个人看的www免费视频在线观看 | 人妻夜夜爽天天爽三区 | 久久久无码中文字幕久... | 狠狠色丁香久久婷婷综合五月 | 国产一区二区三区日韩精品 | 国产精品理论片在线观看 | 女人被男人躁得好爽免费视频 | 熟妇人妻激情偷爽文 | 奇米影视888欧美在线观看 | 给我免费的视频在线观看 | 久久人妻内射无码一区三区 | 亚洲国产精品无码一区二区三区 | 中文无码成人免费视频在线观看 | 风流少妇按摩来高潮 | 狠狠色丁香久久婷婷综合五月 | 一本久久a久久精品vr综合 | 国产片av国语在线观看 | 欧美freesex黑人又粗又大 | 少妇无码一区二区二三区 | 永久免费观看国产裸体美女 | 久久99精品国产麻豆 | 亚洲自偷自偷在线制服 | 国产精品久久久久影院嫩草 | 日日碰狠狠丁香久燥 | 婷婷丁香六月激情综合啪 | 免费中文字幕日韩欧美 | 最近的中文字幕在线看视频 | 水蜜桃色314在线观看 | 西西人体www44rt大胆高清 | 一本久久a久久精品vr综合 | 国产在线无码精品电影网 | 熟女俱乐部五十路六十路av | 亚洲国产欧美国产综合一区 | 欧美大屁股xxxxhd黑色 | 99久久精品日本一区二区免费 | 亚洲国产成人a精品不卡在线 | 日本欧美一区二区三区乱码 | 久久久久成人片免费观看蜜芽 | 黑人巨大精品欧美黑寡妇 | 久久国产劲爆∧v内射 | 无码国内精品人妻少妇 | 亚洲a无码综合a国产av中文 | 国产av剧情md精品麻豆 | 人妻少妇精品无码专区动漫 | 一本久久a久久精品亚洲 | 内射白嫩少妇超碰 | 国产在线一区二区三区四区五区 | 国产无套粉嫩白浆在线 | 性生交大片免费看l | 一二三四社区在线中文视频 | 国产亚洲精品久久久久久久久动漫 | 色 综合 欧美 亚洲 国产 | 国产农村乱对白刺激视频 | 999久久久国产精品消防器材 | 性欧美牲交xxxxx视频 | 久久久久免费精品国产 | 大色综合色综合网站 | 人人爽人人澡人人高潮 | 欧美日韩在线亚洲综合国产人 | 中文字幕无码av波多野吉衣 | 欧美国产亚洲日韩在线二区 | 色五月五月丁香亚洲综合网 | 国产熟妇高潮叫床视频播放 | 波多野结衣高清一区二区三区 | 成人aaa片一区国产精品 | 久久视频在线观看精品 | а√天堂www在线天堂小说 | 欧美freesex黑人又粗又大 | 欧美人与善在线com | 国产极品视觉盛宴 | 免费男性肉肉影院 | 奇米影视7777久久精品 | 国产精品毛片一区二区 | 国产97在线 | 亚洲 | 水蜜桃av无码 | 娇妻被黑人粗大高潮白浆 | 在线播放无码字幕亚洲 | 中文字幕无码av波多野吉衣 | 亚洲中文字幕无码一久久区 | 久在线观看福利视频 | www成人国产高清内射 | 亚洲欧美日韩成人高清在线一区 | 香蕉久久久久久av成人 | 人妻人人添人妻人人爱 | 久激情内射婷内射蜜桃人妖 | 亚洲自偷精品视频自拍 | 天堂亚洲2017在线观看 | 亚洲天堂2017无码中文 | 亚洲色www成人永久网址 | 国产无套内射久久久国产 | 国产精品丝袜黑色高跟鞋 | 国产又爽又黄又刺激的视频 | 熟妇人妻中文av无码 | 又色又爽又黄的美女裸体网站 | 国产精品国产三级国产专播 | av无码电影一区二区三区 | 国产一区二区三区影院 | 久久久久99精品成人片 | 国产卡一卡二卡三 | 国产色精品久久人妻 | 中文字幕亚洲情99在线 | 国产人妻精品一区二区三区不卡 | 亚洲人成网站色7799 | 中文字幕无码热在线视频 | 任你躁在线精品免费 | 国产午夜福利亚洲第一 | 欧美亚洲国产一区二区三区 | 亚洲成av人综合在线观看 | 中文字幕乱码人妻二区三区 | 亚洲人成网站免费播放 | 国产成人人人97超碰超爽8 | 中文字幕无码免费久久99 | 亚洲欧美日韩国产精品一区二区 | 美女极度色诱视频国产 | 国产农村妇女高潮大叫 | 在线播放免费人成毛片乱码 | 俄罗斯老熟妇色xxxx | 清纯唯美经典一区二区 | 精品无码国产自产拍在线观看蜜 | 国产精品无码mv在线观看 | 国产真人无遮挡作爱免费视频 | 中文字幕色婷婷在线视频 | 免费观看激色视频网站 | 亚洲精品成人福利网站 | 成年美女黄网站色大免费全看 | 精品少妇爆乳无码av无码专区 | 天天燥日日燥 | 日韩成人一区二区三区在线观看 | 97精品国产97久久久久久免费 | 亚洲精品一区二区三区在线观看 | 18禁止看的免费污网站 | 特级做a爰片毛片免费69 | 国产精品无码一区二区桃花视频 | 麻花豆传媒剧国产免费mv在线 | 成人无码精品1区2区3区免费看 | 国模大胆一区二区三区 | 黑人巨大精品欧美黑寡妇 | 伊人久久婷婷五月综合97色 | 亚洲欧美日韩成人高清在线一区 | 国产精品毛多多水多 | 成人免费视频在线观看 | 亚洲一区二区观看播放 | 国产精品无套呻吟在线 | 日韩人妻少妇一区二区三区 | 久久人人爽人人人人片 | 精品人妻人人做人人爽 | 国产黑色丝袜在线播放 | 欧美精品免费观看二区 | 中文无码成人免费视频在线观看 | 人人爽人人爽人人片av亚洲 | 日日摸天天摸爽爽狠狠97 | 无码人妻精品一区二区三区不卡 | 精品国产成人一区二区三区 | 国产无av码在线观看 | 欧美黑人巨大xxxxx | 四虎国产精品免费久久 | 在线观看免费人成视频 | 国产精品丝袜黑色高跟鞋 | 国产精品99爱免费视频 | 婷婷色婷婷开心五月四房播播 | 最新国产乱人伦偷精品免费网站 | 久热国产vs视频在线观看 | 98国产精品综合一区二区三区 | 欧美亚洲日韩国产人成在线播放 | 日本欧美一区二区三区乱码 | 国产激情艳情在线看视频 | 国产性生大片免费观看性 | 国产精品资源一区二区 | 亚洲综合伊人久久大杳蕉 | 性色av无码免费一区二区三区 | 人人妻人人澡人人爽欧美一区 | 夜夜影院未满十八勿进 | 久久久久免费精品国产 | 成人综合网亚洲伊人 | 免费中文字幕日韩欧美 | 麻豆av传媒蜜桃天美传媒 | √天堂资源地址中文在线 | 国产超碰人人爽人人做人人添 | 无码人妻精品一区二区三区下载 | 亚洲精品国产品国语在线观看 | 内射巨臀欧美在线视频 | 欧洲美熟女乱又伦 | 欧美成人午夜精品久久久 | 国产电影无码午夜在线播放 | 成人综合网亚洲伊人 | 六月丁香婷婷色狠狠久久 | 噜噜噜亚洲色成人网站 | av无码久久久久不卡免费网站 | 欧美丰满熟妇xxxx | 在线成人www免费观看视频 | 亚洲色欲色欲天天天www | 中文字幕无码视频专区 | 久久久久国色av免费观看性色 | 国产亚洲精品精品国产亚洲综合 | 亚洲天堂2017无码 | 人人爽人人澡人人高潮 | 久激情内射婷内射蜜桃人妖 | 欧美日本精品一区二区三区 | 领导边摸边吃奶边做爽在线观看 | а√天堂www在线天堂小说 | 丰满少妇弄高潮了www | 成人片黄网站色大片免费观看 | 熟妇人妻激情偷爽文 | 日韩精品乱码av一区二区 | 欧美野外疯狂做受xxxx高潮 | 亚洲日韩av片在线观看 | 一区二区三区高清视频一 | 亚洲大尺度无码无码专区 | 亚洲色大成网站www | 国产无套粉嫩白浆在线 | 亚洲の无码国产の无码影院 | 国产无套粉嫩白浆在线 | 乱人伦人妻中文字幕无码 | 国产偷抇久久精品a片69 | 成人无码视频免费播放 | 亚洲精品无码国产 | 亚洲伊人久久精品影院 | 图片区 小说区 区 亚洲五月 | 亚洲精品成a人在线观看 | 久久久久久国产精品无码下载 | 亚洲中文字幕在线观看 | 中文字幕色婷婷在线视频 | 亚洲成a人一区二区三区 | 青草视频在线播放 | 亚洲成a人片在线观看日本 | 成年女人永久免费看片 | 欧美日韩视频无码一区二区三 | 国产肉丝袜在线观看 | 久久久久久国产精品无码下载 | 日本熟妇人妻xxxxx人hd | 国产av一区二区精品久久凹凸 | 欧美丰满少妇xxxx性 | 久久久精品成人免费观看 | 天天拍夜夜添久久精品大 | 日韩精品a片一区二区三区妖精 | 熟女少妇人妻中文字幕 | 国产精品无码成人午夜电影 | 无码精品国产va在线观看dvd | 日本熟妇大屁股人妻 | 日本熟妇乱子伦xxxx | 国产成人无码av在线影院 | 天堂久久天堂av色综合 | 一区二区三区高清视频一 | 大色综合色综合网站 | 国产无遮挡又黄又爽免费视频 | 性色av无码免费一区二区三区 | 国产精品久久福利网站 | 国产精品手机免费 | 国产麻豆精品一区二区三区v视界 | 九九在线中文字幕无码 | 亚洲中文字幕乱码av波多ji | 成人影院yy111111在线观看 | 2020最新国产自产精品 | 亚洲欧洲日本无在线码 | 99久久无码一区人妻 | 激情五月综合色婷婷一区二区 | 国产精品成人av在线观看 | 99国产精品白浆在线观看免费 | 久久久国产精品无码免费专区 | 中文字幕无码乱人伦 | 思思久久99热只有频精品66 | 日韩精品一区二区av在线 | 久久久久久久女国产乱让韩 | 无码人妻少妇伦在线电影 | 成 人 免费观看网站 | 亚洲欧美综合区丁香五月小说 | 国产精品美女久久久 | 夜夜躁日日躁狠狠久久av | 日日噜噜噜噜夜夜爽亚洲精品 | 久久精品99久久香蕉国产色戒 | 东京热无码av男人的天堂 | 丝袜人妻一区二区三区 | 小sao货水好多真紧h无码视频 | 国产熟女一区二区三区四区五区 | 亚洲爆乳精品无码一区二区三区 | 激情人妻另类人妻伦 | 久久综合色之久久综合 | 中文字幕乱妇无码av在线 | 免费无码一区二区三区蜜桃大 | 久久久中文久久久无码 | 免费国产成人高清在线观看网站 | 99久久精品无码一区二区毛片 | 欧美35页视频在线观看 | 中文字幕久久久久人妻 | 无码人妻久久一区二区三区不卡 | 动漫av网站免费观看 | 蜜臀av无码人妻精品 | 在线а√天堂中文官网 | 久久久久久国产精品无码下载 | 男人扒开女人内裤强吻桶进去 | 国产极品美女高潮无套在线观看 | 国产精品多人p群无码 | 麻豆精产国品 | 精品国偷自产在线 | 国产综合色产在线精品 | 久久亚洲中文字幕精品一区 | 99久久亚洲精品无码毛片 | 成人动漫在线观看 | 国产真实乱对白精彩久久 | 国产成人综合在线女婷五月99播放 | 亚洲第一无码av无码专区 | 真人与拘做受免费视频一 | 成人影院yy111111在线观看 | 国产精品久久久久久久影院 | 乱码av麻豆丝袜熟女系列 | 丝袜美腿亚洲一区二区 | 午夜熟女插插xx免费视频 | 东京热一精品无码av | 久久久久人妻一区精品色欧美 | 国产亚洲日韩欧美另类第八页 | 蜜桃无码一区二区三区 | 夜夜躁日日躁狠狠久久av | 国精产品一品二品国精品69xx | 欧美老妇交乱视频在线观看 | 偷窥村妇洗澡毛毛多 | 熟妇人妻激情偷爽文 | 国产亚洲精品久久久ai换 | 精品少妇爆乳无码av无码专区 | 熟女俱乐部五十路六十路av | 白嫩日本少妇做爰 | 亚洲成av人片天堂网无码】 | a在线观看免费网站大全 | 精品成在人线av无码免费看 | 亚洲精品中文字幕久久久久 | 小泽玛莉亚一区二区视频在线 | 国产女主播喷水视频在线观看 | 又色又爽又黄的美女裸体网站 | 大色综合色综合网站 | 午夜精品久久久久久久久 | 天天躁夜夜躁狠狠是什么心态 | 网友自拍区视频精品 | 久久亚洲日韩精品一区二区三区 | 亚洲欧洲日本综合aⅴ在线 | 精品国产av色一区二区深夜久久 | 性欧美疯狂xxxxbbbb | 久久99精品久久久久婷婷 | 真人与拘做受免费视频 | 免费无码的av片在线观看 | 色综合久久网 | 久久久久久国产精品无码下载 | 波多野结衣一区二区三区av免费 | 成人动漫在线观看 | 日韩少妇内射免费播放 | 老熟女乱子伦 | 国产无遮挡又黄又爽又色 | 国产精品理论片在线观看 | 18禁止看的免费污网站 | 日本一区二区三区免费播放 | 国产亚洲精品久久久久久大师 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 亚洲啪av永久无码精品放毛片 | √天堂中文官网8在线 | 亚洲国产精品成人久久蜜臀 | 亚洲综合伊人久久大杳蕉 | 东京一本一道一二三区 | 色婷婷av一区二区三区之红樱桃 | 午夜熟女插插xx免费视频 | 国产精品毛多多水多 | 野外少妇愉情中文字幕 | 久久精品国产99精品亚洲 | 嫩b人妻精品一区二区三区 | 久久午夜无码鲁丝片午夜精品 | 日本一本二本三区免费 | 精品久久久无码中文字幕 | 欧美高清在线精品一区 | 2019nv天堂香蕉在线观看 | 天海翼激烈高潮到腰振不止 | 亚洲男人av天堂午夜在 | 人妻人人添人妻人人爱 | 久久综合色之久久综合 | 色综合视频一区二区三区 | 牲欲强的熟妇农村老妇女 | 国产亚洲精品久久久ai换 | 男女爱爱好爽视频免费看 | 亚洲天堂2017无码中文 | 国产热a欧美热a在线视频 | 兔费看少妇性l交大片免费 | 人人超人人超碰超国产 | 波多野结衣乳巨码无在线观看 | 久久综合狠狠综合久久综合88 | 一本加勒比波多野结衣 | 久久久久免费看成人影片 | 久久zyz资源站无码中文动漫 | 国产精品久久久久影院嫩草 | 欧美人与禽猛交狂配 | 麻豆精品国产精华精华液好用吗 | 国产亚洲精品精品国产亚洲综合 | 亚洲欧美综合区丁香五月小说 | 国产成人综合色在线观看网站 | 亚洲国产一区二区三区在线观看 | 亚洲色www成人永久网址 | 伊人久久大香线蕉亚洲 | 亚洲国产欧美国产综合一区 | 在线观看欧美一区二区三区 | 欧美三级不卡在线观看 | 搡女人真爽免费视频大全 | 欧美人与禽zoz0性伦交 | 欧美性生交活xxxxxdddd | 成在人线av无码免费 | 精品无人区无码乱码毛片国产 | 亚洲人亚洲人成电影网站色 | 久久99精品国产.久久久久 | 久久久久99精品成人片 | 国产深夜福利视频在线 | 国产suv精品一区二区五 | 国产精品美女久久久 | 亚洲自偷自拍另类第1页 | 女人被男人躁得好爽免费视频 | 精品久久久久久人妻无码中文字幕 | 玩弄人妻少妇500系列视频 | 中国女人内谢69xxxx | 亚洲欧洲日本无在线码 | 久久国产自偷自偷免费一区调 | 十八禁真人啪啪免费网站 | 亚洲色欲色欲欲www在线 | 亚洲小说春色综合另类 | 亚洲综合无码久久精品综合 | 动漫av网站免费观看 | 欧美一区二区三区 | 欧美日本日韩 | 学生妹亚洲一区二区 | 纯爱无遮挡h肉动漫在线播放 | 国产精品资源一区二区 | 久久精品视频在线看15 | 麻豆人妻少妇精品无码专区 | 亚洲日韩一区二区三区 | 熟女少妇人妻中文字幕 | 中文毛片无遮挡高清免费 | 激情亚洲一区国产精品 | 久久婷婷五月综合色国产香蕉 | 偷窥村妇洗澡毛毛多 | 夜夜躁日日躁狠狠久久av | 欧美性黑人极品hd | 人人妻人人澡人人爽人人精品 | 久久国产精品偷任你爽任你 | 窝窝午夜理论片影院 | 日日噜噜噜噜夜夜爽亚洲精品 | 中文无码成人免费视频在线观看 | 亚洲精品一区国产 | 亚洲天堂2017无码中文 | 女人色极品影院 | 亚洲中文字幕久久无码 | 国精品人妻无码一区二区三区蜜柚 | 日韩精品无码免费一区二区三区 | 免费无码av一区二区 | 无码播放一区二区三区 | 国产午夜无码精品免费看 | 黑人玩弄人妻中文在线 | 久久久www成人免费毛片 | 99er热精品视频 | 国产精品人人妻人人爽 | 午夜理论片yy44880影院 | 2020久久香蕉国产线看观看 | 国产97人人超碰caoprom | 国产综合色产在线精品 | 亚洲熟悉妇女xxx妇女av | 亚洲gv猛男gv无码男同 | 久久久精品欧美一区二区免费 | 久久成人a毛片免费观看网站 | 2020久久香蕉国产线看观看 | 久久天天躁狠狠躁夜夜免费观看 | 精品厕所偷拍各类美女tp嘘嘘 | 亚洲精品久久久久久一区二区 | 澳门永久av免费网站 | 日韩欧美中文字幕公布 | 波多野结衣乳巨码无在线观看 | 色欲av亚洲一区无码少妇 | 久久99精品国产麻豆 | 99久久婷婷国产综合精品青草免费 | 国产精品久久久 | 熟女体下毛毛黑森林 | 国产成人无码av一区二区 | 无码毛片视频一区二区本码 | 97人妻精品一区二区三区 | 国产精品va在线观看无码 | 日本熟妇人妻xxxxx人hd | 成人影院yy111111在线观看 | 欧美老人巨大xxxx做受 | 无码av免费一区二区三区试看 | 国产乱码精品一品二品 | 国产综合在线观看 | 人妻天天爽夜夜爽一区二区 | 欧美人与动性行为视频 | 夜夜夜高潮夜夜爽夜夜爰爰 | 97无码免费人妻超级碰碰夜夜 | 亚洲综合无码久久精品综合 | 亚洲熟妇色xxxxx欧美老妇y | 小sao货水好多真紧h无码视频 | 欧美喷潮久久久xxxxx | 午夜福利一区二区三区在线观看 | 亚洲人成网站免费播放 | 岛国片人妻三上悠亚 | 欧美 日韩 亚洲 在线 | 自拍偷自拍亚洲精品被多人伦好爽 | 狠狠色丁香久久婷婷综合五月 | 国産精品久久久久久久 | 大地资源网第二页免费观看 | 丰满少妇女裸体bbw | 国产精品人人爽人人做我的可爱 | 久久无码中文字幕免费影院蜜桃 | 亚洲精品午夜无码电影网 | 亚洲国产精品一区二区美利坚 | 国产农村乱对白刺激视频 | 欧美性生交活xxxxxdddd | 任你躁在线精品免费 | 麻豆精产国品 | 无码毛片视频一区二区本码 | 日本精品久久久久中文字幕 | 久久久久亚洲精品男人的天堂 | 成人动漫在线观看 | а天堂中文在线官网 | 狠狠色丁香久久婷婷综合五月 | 色综合视频一区二区三区 | 久久99精品久久久久久动态图 | 久久久久久av无码免费看大片 | 亚洲色大成网站www国产 | 国产无遮挡又黄又爽又色 | 欧美刺激性大交 | 中文字幕无码免费久久9一区9 | 久久久国产精品无码免费专区 | 无码人妻出轨黑人中文字幕 | 久久综合久久自在自线精品自 | 久久精品一区二区三区四区 | 成 人 网 站国产免费观看 | 国产精品亚洲专区无码不卡 | 18精品久久久无码午夜福利 | 国产熟妇另类久久久久 | 成人亚洲精品久久久久 | 欧美35页视频在线观看 | 亚洲 a v无 码免 费 成 人 a v | 国产精品久久久一区二区三区 | 亚洲精品国产精品乱码不卡 | 高潮毛片无遮挡高清免费视频 | 久久久国产一区二区三区 | 国产人妻精品一区二区三区不卡 | 三级4级全黄60分钟 | 国产精品亚洲一区二区三区喷水 | 国产香蕉尹人视频在线 | 妺妺窝人体色www在线小说 | 亚洲 a v无 码免 费 成 人 a v | 日韩人妻系列无码专区 | 亚洲色www成人永久网址 | 亚洲爆乳大丰满无码专区 | 国产热a欧美热a在线视频 | 一二三四社区在线中文视频 | 小sao货水好多真紧h无码视频 | 亚洲成a人片在线观看日本 | 成人无码视频在线观看网站 | 欧美freesex黑人又粗又大 | 亚洲综合另类小说色区 | 国产网红无码精品视频 | 无码任你躁久久久久久久 | 香港三级日本三级妇三级 | 国产精品无码成人午夜电影 | 欧美日韩一区二区综合 | 国产激情无码一区二区app | 欧美色就是色 | 亚洲精品无码国产 | 内射爽无广熟女亚洲 | 亚洲成av人综合在线观看 | 国产精品成人av在线观看 | 帮老师解开蕾丝奶罩吸乳网站 | 日韩少妇内射免费播放 | 精品国产一区二区三区av 性色 | 国产精品高潮呻吟av久久 | 欧美日韩一区二区综合 | 性啪啪chinese东北女人 | 老熟妇乱子伦牲交视频 | 日日噜噜噜噜夜夜爽亚洲精品 | 中文精品无码中文字幕无码专区 | 狠狠色欧美亚洲狠狠色www | 免费无码的av片在线观看 | 真人与拘做受免费视频一 | 中文字幕无码热在线视频 | 午夜不卡av免费 一本久久a久久精品vr综合 | 国产超级va在线观看视频 | 中文字幕无码人妻少妇免费 | 少妇性l交大片 | 国产内射爽爽大片视频社区在线 | 国产精品久久久久久无码 | 国产性生大片免费观看性 | 色综合久久88色综合天天 | 少妇无套内谢久久久久 | 丰满少妇人妻久久久久久 | 国产成人无码午夜视频在线观看 | 欧美成人免费全部网站 | 国产精品久久久av久久久 | 亚洲自偷自拍另类第1页 | 日韩精品久久久肉伦网站 | yw尤物av无码国产在线观看 | 亚洲中文字幕成人无码 | 亚洲国产午夜精品理论片 | 永久免费观看国产裸体美女 | 精品无码av一区二区三区 | 亚洲综合另类小说色区 | 帮老师解开蕾丝奶罩吸乳网站 | 扒开双腿疯狂进出爽爽爽视频 | 无码精品人妻一区二区三区av | 一本久道久久综合婷婷五月 | 中文毛片无遮挡高清免费 | 亚洲欧美色中文字幕在线 | 丰满人妻精品国产99aⅴ | 国产在线无码精品电影网 | 四虎永久在线精品免费网址 | 亚洲一区二区三区国产精华液 | 成人亚洲精品久久久久软件 | 性生交大片免费看l | 露脸叫床粗话东北少妇 | 欧美丰满熟妇xxxx性ppx人交 | 装睡被陌生人摸出水好爽 | 中文字幕人成乱码熟女app | 国产精品理论片在线观看 | 无码人妻丰满熟妇区五十路百度 | 成人精品视频一区二区 | 午夜理论片yy44880影院 | 欧美zoozzooz性欧美 | 精品欧洲av无码一区二区三区 | 帮老师解开蕾丝奶罩吸乳网站 | 色 综合 欧美 亚洲 国产 | 俺去俺来也www色官网 | 国产女主播喷水视频在线观看 | 性欧美熟妇videofreesex | 一本色道久久综合亚洲精品不卡 | 狠狠cao日日穞夜夜穞av | 国产综合色产在线精品 | 动漫av一区二区在线观看 | 国产精品鲁鲁鲁 | 久久综合九色综合欧美狠狠 | 亚洲国产精品毛片av不卡在线 | 女人被爽到呻吟gif动态图视看 | 伊在人天堂亚洲香蕉精品区 | 无码人妻精品一区二区三区不卡 | 两性色午夜视频免费播放 | 麻豆果冻传媒2021精品传媒一区下载 | 亚洲成av人综合在线观看 | 麻豆国产丝袜白领秘书在线观看 | 97精品国产97久久久久久免费 | 秋霞特色aa大片 | 在线看片无码永久免费视频 | 成人无码精品一区二区三区 | 亚洲区欧美区综合区自拍区 | 国产手机在线αⅴ片无码观看 | 高清国产亚洲精品自在久久 | 亚洲自偷精品视频自拍 | 国产内射爽爽大片视频社区在线 | 国产成人综合色在线观看网站 | 日本熟妇乱子伦xxxx | 青草视频在线播放 | 欧美性生交xxxxx久久久 | 老子影院午夜伦不卡 | 欧美怡红院免费全部视频 | 蜜桃视频韩日免费播放 | 在线播放无码字幕亚洲 | 国产另类ts人妖一区二区 | 无码国产乱人伦偷精品视频 | 精品一区二区三区波多野结衣 | 色综合久久久无码网中文 | 久久久久se色偷偷亚洲精品av | 男女猛烈xx00免费视频试看 | 国产精品无码一区二区桃花视频 | 久久这里只有精品视频9 | 国产极品视觉盛宴 | 在线亚洲高清揄拍自拍一品区 | 欧美一区二区三区 | 5858s亚洲色大成网站www | 国产精品va在线观看无码 | 亚洲色欲色欲天天天www |