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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

《C++ Primer 5th》笔记(3 / 19):字符串、向量、迭代器和数组

發(fā)布時間:2023/12/13 c/c++ 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《C++ Primer 5th》笔记(3 / 19):字符串、向量、迭代器和数组 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 命名空間的using聲明
    • 標(biāo)準(zhǔn)庫類型string
      • 定義和初始化string對象
        • 直接初始化和拷貝初始化
      • string對象上的操作
        • 讀寫string對象
        • 讀取未知數(shù)量的string對象
        • 使用getline讀取一整行
        • string的empty和size操作
        • string::size_type類型
        • 比較string對象
        • 為string對象賦值
        • 兩個string對象相加
        • 字面值和string對象相加
      • 處理string對象中的字符
        • 建議:使用C++版本的C標(biāo)準(zhǔn)庫頭文件
        • 處理每個字符,就使用基于范圍的for語句
        • 使用范圍for語句改變字符串中的字符
        • 只處理一部分字符
        • 使用下標(biāo)執(zhí)行迭代
        • 提示:注意檢查下標(biāo)的合法性
        • 使用下標(biāo)執(zhí)行隨機(jī)訪問
    • 標(biāo)準(zhǔn)庫類型vector
      • 定義和初始化vector對象
        • 列表初始化vector對象
        • 創(chuàng)建指定數(shù)量的元素
        • 值初始化
        • 列表初始值還是元素數(shù)量
      • 向vector對象中添加元素
        • 關(guān)鍵概念:vector對象能高效增長
        • 向vector對象添加元素蘊(yùn)含的編程假定
      • 其他vector操作
        • 計算vector內(nèi)對象的索引
        • 不能用下標(biāo)形式添加元素
        • 提示:只能對確知已存在的元素執(zhí)行下標(biāo)操作!
    • 迭代器介紹
      • 使用迭代器
        • 迭代器運(yùn)算符
        • 將迭代器從一個元素移動到另外一個元素
        • 關(guān)鍵概念:泛型編程
        • 迭代器類型
        • 術(shù)語:迭代器和迭代器類型
        • begin和end運(yùn)算符
        • 結(jié)合解引用和成員訪問操作
        • 某些對vector對象的操作會使迭代器失效
      • 迭代器運(yùn)算
        • 迭代器的算術(shù)運(yùn)算
        • 使用迭代器運(yùn)算
    • 數(shù)組
      • 定義和初始化內(nèi)置數(shù)組
        • 顯式初始化數(shù)組元素
        • 字符數(shù)組的特殊性
        • 不允許拷貝和賦值
        • 理解復(fù)雜的數(shù)組聲明
      • 訪問數(shù)組元素
        • 檢查下標(biāo)的值
      • 指針和數(shù)組
        • 指針也是迭代器
        • 標(biāo)準(zhǔn)庫函數(shù)begin和end
        • 指針運(yùn)算
        • 解引用和指針運(yùn)算的交互
        • 下標(biāo)和指針
      • C風(fēng)格字符串
        • C標(biāo)準(zhǔn)庫String函數(shù)
        • 比較字符串
        • 目標(biāo)字符串的大小由調(diào)用者指定
      • 與舊代碼的接口
        • 混用string對象和C風(fēng)格字符串
        • 使用數(shù)組初始化vector對象
        • 建議:盡量使用標(biāo)準(zhǔn)庫類型而非數(shù)組
    • 多維數(shù)組
      • 多維數(shù)組的初始化
      • 多維數(shù)組的下標(biāo)引用
      • 使用范圍for語句處理多維數(shù)組
      • 指針和多維數(shù)組
      • 類別別名簡化多維數(shù)組的指針
    • 一些術(shù)語

命名空間的using聲明

目前為止,我們用到的庫函數(shù)基本上都屬于命名空間std,而程序也顯式地將這一點(diǎn)標(biāo)示了出來。

例如,std::cin表示從標(biāo)準(zhǔn)輸入中讀取內(nèi)容。此處使用作用域操作符(::)的含義是:編譯器應(yīng)從操作符左側(cè)名字所示的作用域中尋找右側(cè)那個名字。因此,std::cin 的意思就是要使用命名空間std中的名字cin。

上面的方法顯得比較煩瑣,然而幸運(yùn)的是,通過更簡單的途徑也能使用到命名空間中的成員,也就是使用using聲明(using declaration),還會有其他途徑,敬請期待。

有了using聲明就無須專門的前綴(形如命名空間::)也能使用所需的名字了。using聲明具有如下的形式:

using namespace::name;

一旦聲明了上述語句,就可以直接訪問命名空間中的名字:

#include <iostream> // using declaration; when we use the name cin, we get the one from the namespace std using std::cin; int main() {int i;cin >> i; // ok: cin is a synonym for std::cincout << i; // error: no using declaration; we must use the full namestd::cout << i; // ok: explicitly use cout from namepsace stdreturn 0; }

每個名字都需要獨(dú)立的using聲明

#include <iostream> // using declarations for names from the standard library using std::cin; using std::cout; using std::endl;int main() {cout << "Enter two numbers:" << endl;int v1, v2;cin >> v1 >> v2;cout << "The sum of " << v1 << " and " << v2<< " is " << v1 + v2 << endl;return 0; }

頭文件不應(yīng)包含using 聲明

位于頭文件的代碼一般來說不應(yīng)該使用using聲明。這是因?yàn)轭^文件的內(nèi)容會拷貝到所有引用它的文件中去,如果頭文件里有某個using聲明,那么每個使用了該頭文件的文件就都會有這個聲明。對于某些程序來說,由于不經(jīng)意間包含了一些名字,反而可能產(chǎn)生始料未及的名字沖突。

一點(diǎn)注意事項

之后的所有例子將假設(shè),但凡用到的標(biāo)準(zhǔn)庫中的名字都已經(jīng)使用using語句聲明過了。例如,我們將在代碼中直接使用cin,而不再使用std::cin。

為了讓書中的代碼盡量簡潔,今后將不會再把所有using聲明和#include指令一一標(biāo)出。

標(biāo)準(zhǔn)庫類型string

標(biāo)準(zhǔn)庫類型string表示可變長的字符序列,使用string類型必須首先包含string頭文件。作為標(biāo)準(zhǔn)庫的一部分,string定義在命名空間std中。接下來的示例都假定已包含了下述代碼:

#include <string> using std::string;

本節(jié)描述最常用的string操作,將來還將介紹另外一些。

C++標(biāo)準(zhǔn)一方面對庫類型所提供的操作做了詳細(xì)規(guī)定,另一方面也對庫的實(shí)現(xiàn)者做出一些性能上的需求。因此,標(biāo)準(zhǔn)庫類型對于一般應(yīng)用場合來說有足夠的效率。(也就是說,你放心用標(biāo)準(zhǔn)庫類型吧!)

定義和初始化string對象

副本的本義是指同一書抄出的復(fù)本。link

string s1; // default initialization; s1 is the empty string string s2 = s1; // s2 is a copy of s1 string s3 = "hiya"; // s3 is a copy of the string literal string s4(10, 'c'); // s4 is cccccccccc

初始化string對象的方式

..
string s1默認(rèn)初始化,s1是一個空串
string s2(s1)s2是s1的副本
string s2 = s1等價于s2(s1),s2是s1的副本
string s3(“value”)s3是字面值"value"的副本,除了字面值最后的那個空字符外
string s3 = “value”等價于s3(“value”),s3是字面值"value"的副本
string s4(n, ‘c’)把s4初始化為由連續(xù)n個字符c組成的串

直接初始化和拷貝初始化

C++語言有幾種不同的初始化方式,通過string我們可以清楚地看到在這些初始化方式之間到底有什么區(qū)別和聯(lián)系。

  • 如果使用等號(=)初始化一個變量,實(shí)際上執(zhí)行的是拷貝初始化(copy initialization),編譯器把等號右側(cè)的初始值拷貝到新創(chuàng)建的對象中去。
  • 與之相反,如果不使用等號,則執(zhí)行的是直接初始化(direct initialization)

當(dāng)初始值只有一個時,使用直接初始化或拷貝初始化都行:

string s5 = "hiya"; // copy initialization string s6("hiya"); // direct initialization string s7(10, 'c'); // direct initialization; s7 is cccccccccc

對于用多個值進(jìn)行初始化的情況,非要用拷貝初始化的方式來處理也不是不可以,不過需要顯式地創(chuàng)建一個(臨時)對象用于拷貝:

string s8 = string(10, 'c');//拷貝初始化,s8的內(nèi)容是cccccccccc

相當(dāng)于

string temp(10, 'c'); // temp is cccccccccc string s8 = temp; // copy temp into s8

其實(shí)我們可以看到,盡管初始化s8的語句合法,但和初始化s7的方式比較起來可讀性較差,也沒有任何補(bǔ)償優(yōu)勢。(沒什么卵用)

string對象上的操作

..
os<<s將s寫到輸出流os當(dāng)中,返回os
is>>s從is中讀取字符串賦給s,字符串以空白分隔,返回is
getline(is, s)從is中讀取一行賦給s,返回is
s.empty()s為空返回true,否則返回false
s.size()返回s中字符的個數(shù)
s[n]返回s中第n個字符的引用,位置n從0計起
s1+s2返回s1和s2連接后的結(jié)果
s1=s2用s2的副本代替s1中原來的字符
s1==s2如果s1和s2中所含的字符完全一樣,則它們相等;string對象的相等性判斷對字母的大小寫敏感
s1!=s2判斷s1和s2中所含的字符是否完全一樣
<, <=, >, >=利用字符在字典中的順序進(jìn)行比較,且對字母的大小寫敏感

讀寫string對象

// Note: #include and using declarations must be added to compile this code int main() {string s; // empty stringcin >> s; // read a whitespace-separated string into scout << s << endl; // write s to the outputreturn 0; }

string對象會自動忽略開頭的空白(即空格符、換行符、制表符等)并從第一個真正的字符開始讀起,直到遇見下一處空白為止。

如上所述,如果程序的輸入是“ Hello World! ”(注意開頭和結(jié)尾處的空格),則輸出將是“Hello”,輸出結(jié)果中沒有任何空格。

和內(nèi)置類型的輸入輸出操作一樣,string對象的此類操作也是返回運(yùn)算符左側(cè)的運(yùn)算對象作為其結(jié)果。因此,多個輸入或者多個輸出可以連寫在一起:

string s1, s2; cin >> s1 >> s2; // read first input into s1, second into s2 cout << s1 << s2 << endl; // write both strings

假設(shè)給上面這段程序輸入與之前一樣的內(nèi)容“ Hello World! ”,輸出將是“HelloWorld!”。

讀取未知數(shù)量的string對象

int main() {string word;while (cin >> word) // read until end-of-file (Ctrl + Z)cout << word << endl; // write each word followed by a new linereturn 0; }

使用getline讀取一整行

有時我們希望能在最終得到的字符串中保留輸入時的空白符,這時應(yīng)該用getline函數(shù)代替原來的>>運(yùn)算符。getline函數(shù)的參數(shù)是一個輸入流和一個string對象,函數(shù)從給定的輸入流中讀入內(nèi)容,直到遇到換行符為止(注意換行符也被讀進(jìn)來了),然后把所讀的內(nèi)容存入到那個string對象中去(注意不存換行符)。

getline只要一遇到換行符就結(jié)束讀取操作并返回流參數(shù),哪怕輸入的一開始就是換行符也是如此。如果輸入真的一開始就是換行符,那么所得的結(jié)果是個空string。

int main() {string line;// read input a line at a time until end-of-filewhile (getline(cin, line))cout << line << endl;return 0; }

因?yàn)閘ine中不包含換行符,所以我們手動地加上換行操作符。和往常一樣,使用endl結(jié)束當(dāng)前行并刷新顯示緩沖區(qū)。

觸發(fā)getline函數(shù)返回的那個換行符實(shí)際上被丟棄掉了,得到的string對象中并不包含該換行符。

string的empty和size操作

empty函數(shù)根據(jù)string對象是否為空返回一個對應(yīng)的布爾值。

// read input a line at a time and discard blank lines while (getline(cin, line))if (!line.empty())cout << line << endl;

size函數(shù)返回string對象的長度(即string對象中字符的個數(shù)),可以使用size函數(shù)只輸出長度超過80個字符的行:

string line; // read input a line at a time and print lines that are longer than 80 characters while (getline(cin, line))if (line.size() > 80)cout << line << endl;

string::size_type類型

對于size函數(shù)來說,返回一個int或者一個unsigned似乎都是合情合理的。但其實(shí) size函數(shù)返回的是一個string::size_type類型的值。

string類及其他大多數(shù)標(biāo)準(zhǔn)庫類型都定義了幾種配套的類型。這些配套類型體現(xiàn)了標(biāo)準(zhǔn)庫類型與機(jī)器無關(guān)的特性,類型size_type即是其中的一種。在具體使用的時候,通過作用域操作符來表明名字size_type是在類string中定義的。

盡管我們不太清楚string::size_type類型的細(xì)節(jié),但有一點(diǎn)是肯定的:它是一個無符號類型的值而且能足夠存放下任何string對象的大小。所有用于存放string類的size函數(shù)返回值的變量,都應(yīng)該是string::size_type類型的。

過去,string::size_type這種類型有點(diǎn)兒神秘,不太容易理解和使用。在C++11新標(biāo)準(zhǔn)中,允許編譯器通過auto或者decltype來推斷變量的類型:

auto len = line.size (); //len的類型是string::size_type

由于size函數(shù)返回的是一個無符號整型數(shù),因此切記,如果在表達(dá)式中混用了帶符號數(shù)和無符號數(shù)將可能產(chǎn)生意想不到的結(jié)果。例如,假設(shè)n 是一個具有負(fù)值的int,則表達(dá)式s.size()<n的判斷結(jié)果幾乎肯定是true。

這是因?yàn)?strong>負(fù)值n會自動地轉(zhuǎn)換成一個比較大的無符號值。

如果一條表達(dá)式中已經(jīng)有了size()函數(shù)就不要再使用int了,這樣可以避免混用int和unsigned可能帶來的問題。

比較string對象

string類定義了幾種用于比較字符串的運(yùn)算符。這些比較運(yùn)算符逐一比較string對象中的字符,并且對大小寫敏感,也就是說,在比較時同一個字母的大寫形式和小寫形式是不同的。

相等性運(yùn)算符(==和!=)分別檢驗(yàn)兩個string對象相等或不相等,string對象相等意味著它們的長度相同而且所包含的字符也全都相同。關(guān)系運(yùn)算符<、<=、>、>=分別檢驗(yàn)一個string對象是否小于、小于等于、大于、大于等于另外一個string對象。上述這些運(yùn)算符都依照(大小寫敏感的)字典順序:

  • 如果兩個string對象的長度不同,而且較短string對象的每個字符都與較長string對象對應(yīng)位置上的字符相同,就說較短string對象小于較長 string對象。
  • 如果兩個string對象在某些對應(yīng)的位置上不一致,則string對象比較的結(jié)果其實(shí)是string對象中第一對相異字符比較的結(jié)果。
  • string s1 = "Hello"; string s2 = "Hello World"; string s3 = "Hiya";

    根據(jù)規(guī)則1可判斷,對象s1小于對象s2;根據(jù)規(guī)則2可判斷,對象s3既大于s1也大于s2。

    為string對象賦值

    一般來說,在設(shè)計標(biāo)準(zhǔn)庫類型時都力求在易用性上向內(nèi)置類型看齊,因此大多數(shù)庫類型都支持賦值操作。對于string類而言,允許把一個對象的值賦給另外一個對象:

    string st1(10, 'c'), st2; // st1 is cccccccccc; st2 is an empty string st1 = st2; // assignment: replace contents of st1 with a copy of st2 // both st1 and st2 are now the empty string

    兩個string對象相加

    兩個string對象相加得到一個新的string對象,其內(nèi)容是把左側(cè)的運(yùn)算對象與右側(cè)的運(yùn)算對象串接而成。

    也就是說,對string對象使用加法運(yùn)算符(+)的結(jié)果是一個新的string對象,它所包含的字符由兩部分組成:前半部分是加號左側(cè)string對象所含的字符、后半部分是加號右側(cè)string對象所含的字符。

    另外,復(fù)合賦值運(yùn)算符(+=)負(fù)責(zé)把右側(cè)string對象的內(nèi)容追加到左側(cè)string對象的后面:

    string s1 = "hello, ", s2 = "world\n"; string s3 = s1 + s2; // s3 is hello, world\n s1 += s2; // equivalent to s1 = s1 + s2

    字面值和string對象相加

    上一章節(jié)說過所講的,即使一種類型并非所需,我們也可以使用它,不過前提是該種類型可以自動轉(zhuǎn)換成所需的類型。因?yàn)闃?biāo)準(zhǔn)庫允許把字符字面值字符串字面值轉(zhuǎn)換成string對象,所以在需要string對象的地方就可以使用這兩種字面值來替代。利用這一點(diǎn)將之前的程序改寫為如下形式:

    string s1 = "hello", s2 = "world"; // no punctuation in s1 or s2 string s3 = s1 + ", " + s2 + '\n';

    當(dāng)把string對象和字符字面值及字符串字面值混在一條語句中使用時,必須確保每個加法運(yùn)算符(+)的兩側(cè)的運(yùn)算對象至少有一個是string:

    string s4 = s1 + ", "; // ok: adding a string and a literal string s5 = "hello" + ", "; // error: no string operand string s6 = s1 + ", " + "world"; // ok: each + has a string operand//字符串字面值不能直接相加 string s7 = "hello" + ", " + s2; // error: can't add string literals

    s4和s5初始化時只用到了一個加法運(yùn)算符,因此很容易判斷是否合法。s6的初始化形式之前沒有出現(xiàn)過,但其實(shí)它的工作機(jī)理和連續(xù)輸入連續(xù)輸出是一樣的,可以用如下的形式分組:

    string s6 = (s1 + ", ") + "world";

    其中子表達(dá)式sl +", "的結(jié)果是一個string對象,它同時作為第二個加法運(yùn)算符的左側(cè)運(yùn)算對象,因此上述語句和下面的兩個語句是等價的:

    string tmp = s1 + ", "; // ok: + has a string operand s6 = tmp + "world"; // ok: + has a string operand

    另一方面,s7的初始化是非法的,根據(jù)其語義加上括號后就成了下面的形式:

    string s7 = ("hello" + ", ") + s2; // error: can't add string literals

    很容易看到,括號內(nèi)的子表達(dá)式試圖把兩個字符串字面值加在一起,而編譯器根本沒法做到這一點(diǎn),所以這條語句是錯誤的。

    因?yàn)槟承v史原因,也為了與C兼容,所以C++語言中的字符串字面值并不是標(biāo)準(zhǔn)庫類型string的對象。切記,C++中字符串字面值與string是不同的類型。

    處理string對象中的字符

    cctype頭文件中的函數(shù)

    ..
    isalnum?當(dāng)c是字母或數(shù)字時為真
    isalpha?當(dāng)c是字母時為真
    iscntrl?當(dāng)c是控制字符時為真
    isdigit?當(dāng)c是數(shù)字時為真
    isgraph?當(dāng)c不是空格但可打印時為真
    islower?當(dāng)c是小寫字母時為真
    isprint?當(dāng)c是可打印字符時為真(即c是空格或c具有可視形式)
    ispunct?當(dāng)c是標(biāo)點(diǎn)符號時為真(即c不是控制字符、數(shù)字、字母、可打印空白中的一種)
    isspace?當(dāng)c是空白時為真(即c是空格、橫向制表符、縱向制表符、回車符、換行符、進(jìn)紙符中的一種)
    isupper?當(dāng)c是大寫字母時為真
    isxdigit?當(dāng)c是十六進(jìn)制數(shù)字時為真
    tolower?如果c是大寫字母,輸出對應(yīng)的小寫字母;否則原樣輸出c
    toupper?如果c是小寫字母,輸出對應(yīng)的大寫字母;否則原樣輸出c

    建議:使用C++版本的C標(biāo)準(zhǔn)庫頭文件

    C++標(biāo)準(zhǔn)庫中除了定義C++語言特有的功能外,也兼容了C語言的標(biāo)準(zhǔn)庫。C語言的頭文件形如 name.h,C++則將這些文件命名為cname。也就是去掉了.h后綴,而在文件名name之前添加了字母c,這里的c表示這是一個屬于C語言標(biāo)準(zhǔn)庫的頭文件。

    因此,cctype頭文件和 ctype.h頭文件的內(nèi)容是一樣的,只不過從命名規(guī)范上來講更符合C++語言的要求。特別的,在名為cname的頭文件中定義的名字從屬于命名空間std,而定義在名為.h的頭文件中的則不然。

    一般來說,C++程序應(yīng)該使用名為cname的頭文件而不使用name.h的形式,標(biāo)準(zhǔn)庫中的名字總能在命名空間std中找到。如果使用.h形式的頭文件,程序員就不得不時刻牢記哪些是從C語言那兒繼承過來的,哪些又是C++語言所獨(dú)有的。

    處理每個字符,就使用基于范圍的for語句

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

    范圍for (range for)語句。這種語句遍歷給定序列中的每個元素并對序列中的每個值執(zhí)行某種操作,其語法形式是:

    for (declaration : expression)statement

    其中,expression部分是一個對象,用于表示一個序列。declaration部分負(fù)責(zé)定義一個變量,該變量將被用于訪問序列中的基礎(chǔ)元素。每次迭代,declaration部分的變量會被初始化為expression部分的下一個元素值。

    (Note:與Java的forEach循環(huán)類似)

    一個string對象表示一個字符的序列,因此 string對象可以作為范圍for語句中的expression部分。

    舉一個簡單的例子,我們可以使用范圍for語句把string對象中的字符每行一個輸出出來:

    string str("some string"); // print the characters in str one character to a line for (auto c : str) // for every char in strcout << c << endl; // print the current character followed by a newline

    再舉一點(diǎn)的例子,使用范圍for語句和 ispunct函數(shù)來統(tǒng)計string對象中標(biāo)點(diǎn)符號的個數(shù):

    string s("Hello World!!!"); // punct_cnt has the same type that s.size returns;//decltype具體查看上一章 decltype(s.size()) punct_cnt = 0; // count the number of punctuation characters in s for (auto c : s) // for every char in sif (ispunct(c)) // if the character is punctuation++punct_cnt; // increment the punctuation counter cout << punct_cnt<< " punctuation characters in " << s << endl;

    輸出結(jié)果:

    3 punctuation characters in Hello wor1d!!!

    使用范圍for語句改變字符串中的字符

    如果想要改變string對象中字符的值,必須把循環(huán)變量定義成引用類型

    記住,所謂引用只是給定對象的一個別名,因此當(dāng)使用引用作為循環(huán)控制變量時,這個變量實(shí)際上被依次綁定到了序列的每個元素上。使用這個引用,我們就能改變它綁定的字符。

    舉一個簡單的例子,假設(shè)我們想要把字符串改寫為大寫字母的形式。

    string s("Hello World!!!"); // convert s to uppercase for (auto &c : s) // for every char in s (note: c is a reference)c = toupper(c); // c is a reference, so the assignment changes the char in s cout << s << endl;

    輸出結(jié)果:

    HELLO WORLD!!!

    只處理一部分字符

    如果要處理string對象中的每一個字符,使用范圍for語句是個好主意。然而,有時我們需要訪問的只是其中一個字符,或者訪問多個字符但遇到某個條件就要停下來。例如,同樣是將字符改為大寫形式,不過新的要求不再是對整個字符串都這樣做,而僅僅把string對象中的第一個字母或第一個單詞大寫化。

    要想訪問string對象中的單個字符有兩種方式:

  • 使用下標(biāo),
  • 使用迭代器
  • 先介紹下標(biāo)運(yùn)算符(The subscript operator) ([])接收的輸入?yún)?shù)是string::size_type類型的值,這個參數(shù)表示要訪問的字符的位置;返回值是該位置上字符的引用。

    string對象的下標(biāo)從0計起。如果string對象s至少包含兩個字符,則s[0]是第1個字符、s[1]是第2個字符、s[s.size()-1]是最后一個字符。

    string對象的下標(biāo)必須大于等于0而小于s.size()。

    使用超出此范圍的下標(biāo)將引發(fā)不可預(yù)知的結(jié)果,以此推斷,使用下標(biāo)訪問空string也會引發(fā)不可預(yù)知的結(jié)果。

    下標(biāo)的值稱作“下標(biāo)(a subscript)”或“索引(an index )”,任何表達(dá)式只要它的值是一個整型值就能作為索引。不過,如果某個索引是帶符號類型的值將自動轉(zhuǎn)換成由string::size_type表達(dá)的無符號類型。

    舉一個例子,使用下標(biāo)運(yùn)算符輸出string對象中的第一個字符:

    if (!s.empty()) // make sure there's a character to printcout << s[0] << endl; // print the first character in s

    再舉一個例子,將字符串首字母變?yōu)榇髮?#xff1a;(只要字符串不是常量,就能為下標(biāo)運(yùn)算符返回的字符賦新值。)

    string s("some string"); if (!s.empty()) // make sure there's a character in s[0]s[0] = toupper(s[0]); // assign a new value to the first character in s

    輸出s:

    Some string

    使用下標(biāo)執(zhí)行迭代

    另一個例子是把s的第一個詞改成大寫形式:

    // process characters in s until we run out of characters or we hit a whitespace for (decltype(s.size()) index = 0;index != s.size() && !isspace(s[index]); ++index)s[index] = toupper(s[index]); // capitalize the current character

    輸出s:

    SOME string

    提示:注意檢查下標(biāo)的合法性

    使用下標(biāo)時必須確保其在合理范圍之內(nèi),也就是說,下標(biāo)必須大于等于0而小于字符串的size()的值。一種簡便易行的方法是,總是設(shè)下標(biāo)的類型為string::size_type,因?yàn)榇祟愋褪菬o符號數(shù),可以確保下標(biāo)不會小于0。此時,代碼只需保證下標(biāo)小于size()的值就可以了。

    C++標(biāo)準(zhǔn)并不要求標(biāo)準(zhǔn)庫檢測下標(biāo)是否合法。一旦使用了一個超出范圍的下標(biāo),就會產(chǎn)生不可預(yù)知的結(jié)果。

    使用下標(biāo)執(zhí)行隨機(jī)訪問

    在之前的示例中,我們讓字符串的下標(biāo)每次加1從而按順序把所有字符改寫成了大寫形式。其實(shí)也能通過計算得到某個下標(biāo)值,然后直接獲取對應(yīng)位置的字符,并不是每次都得從前往后依次訪問。

    例如,想要編寫一個程序把0到15之間的十進(jìn)制數(shù)轉(zhuǎn)換成對應(yīng)的十六進(jìn)制形式,只需初始化一個字符串令其存放16個十六進(jìn)制“數(shù)字”:

    const string hexdigits = "0123456789ABCDEF"; // possible hex digits cout << "Enter a series of numbers between 0 and 15"<< " separated by spaces. Hit ENTER when finished: "<< endl; string result; // will hold the resulting hexify'd string string::size_type n; // hold numbers from the input while (cin >> n)if (n < hexdigits.size()) // ignore invalid inputresult += hexdigits[n]; // fetch the indicated hex digit cout << "Your hex number is: " << result << endl;

    假設(shè)輸入的內(nèi)容如下:

    12 0 5 15 8 15

    程序的輸出結(jié)果將是:

    Your hex number is: C05F8F

    標(biāo)準(zhǔn)庫類型vector

    vector
    英 [?vekt??] 美 [?vekt?r]
    n. 矢量; 向量; (傳染疾病的)介體,載體; (航空器的)航線

    標(biāo)準(zhǔn)庫類型vector表示對象的集合,其中所有對象的類型都相同。集合中的每個對象都有一個與之對應(yīng)的索引,索引用于訪問對象。因?yàn)関ector“容納著”其他對象,所以它也常被稱作容器(container)。

    要想使用vector,必須包含適當(dāng)?shù)念^文件。在后續(xù)的例子中,都將假定做了如下using聲明:

    #include <vector> using std::vector;

    C++語言既有類模板(class template),也有函數(shù)模板,其中vector是一個類模板。只有對C++有了相當(dāng)深入的理解才能寫出模板,事實(shí)上,我們直到最后階段的章節(jié)才會學(xué)習(xí)如何自定義模板。幸運(yùn)的是,即使還不會創(chuàng)建模板,我們也可以先試著用用它。

    模板本身不是類或函數(shù),相反可以將模板看作為編譯器生成類或函數(shù)編寫的指令。(Templates are not themselves functions or classes. Instead, they can be thought of as instructions to the compiler for generating classes or functions. )編譯器根據(jù)模板創(chuàng)建類或函數(shù)的過程稱為實(shí)例化( instantiation),當(dāng)使用模板時,需要指出編譯器應(yīng)把類或函數(shù)實(shí)例化成何種類型。

    對于類模板來說,我們通過提供一些額外信息來指定模板到底實(shí)例化成什么樣的類,需要提供哪些信息由模板決定。提供信息的方式總是這樣:即在模板名字后面跟一對尖括號,在括號內(nèi)放上信息。

    以vector為例,提供的額外信息是vector內(nèi)所存放對象的類型:

    vector<int> ivec; // ivec holds objects of type int vector<Sales_item> Sales_vec; // holds Sales_items vector<vector<string>> file; // vector whose elements are vectors

    在上面的例子中,編譯器根據(jù)模板vector生成了三種不同的類型:

    • vector<int>
    • vector<Sales_item>
    • vector<vector<string>>

    vector是模板而非類型,由vector生成的類型必須包含vector中元素的類型,例如vector<int>。

    vector能容納絕大多數(shù)類型的對象作為其元素,但是因?yàn)橐貌皇菍ο?#xff0c;所以不存在包含引用的vector。除此之外,其他大多數(shù)(非引用)內(nèi)置類型和類類型都可以構(gòu)成vector對象,甚至組成vector的元素也可以是vector。

    (與Java中的List類似)

    關(guān)于舊版本的vector

    需要指出的是,在早期版本的C++標(biāo)準(zhǔn)中如果vector的元素還是vector(或者其他模板類型),則其定義的形式與現(xiàn)在的C++11新標(biāo)準(zhǔn)略有不同。過去,必須在外層vector對象的右尖括號和其元素類型之間添加一個空格,如應(yīng)該寫成vector<vector<int> >而非vector<vector<int>>。

    某些編譯器可能仍需以老式的聲明語句來處理元素為 vector的vector對象,如 vector<vector<int> >。

    定義和初始化vector對象

    初始化vector對象的方法:

    ..
    vector<T> v1v1是一個空vector,它潛在的元素是T類型的,執(zhí)行默認(rèn)初始化
    vector<T> v2(v1)v2中包含有v1所有元素的副本
    vector<T> v2 = v1等價于v2(v1),v2中包含有v1所有元素的副本
    vector<T> v3 (n, val)v3包含了n個重復(fù)的元素,每個元素的值都是val
    vector<T> v4 (n)v4包含了n個重復(fù)地執(zhí)行了值初始化的對象
    vector<T> v5{a, b, c…}v5包含了初始值個數(shù)的元素,每個元素被賦予相應(yīng)的初始值
    vector<T> v5={a, b, c…}等價于v5{a,b,c…}

    可以默認(rèn)初始化 vector對象,從而創(chuàng)建一個指定類型的空vector:

    vector<string> svec; //默認(rèn)初始化,svec不含任何元素

    看起來空vector好像沒什么用,但是很快我們就會知道程序在運(yùn)行時可以很高效地往vector對象中添加元素。事實(shí)上,最常見的方式就是先定義一個空vector,然后當(dāng)運(yùn)行時獲取到元素的值后再逐一添加。

    當(dāng)然也可以在定義vector對象時指定元素的初始值。

    例如,允許把一個vector對象的元素拷貝給另外一個vector對象。此時,新vector對象的元素就是原vector對象對應(yīng)元素的副本。注意兩個vector對象的類型必須相同:

    vector<int> ivec; // initially empty // give ivec some values vector<int> ivec2(ivec); // copy elements of ivec into ivec2 vector<int> ivec3 = ivec; // copy elements of ivec into ivec3 vector<string> svec(ivec2); // error: svec holds strings, not ints

    列表初始化vector對象

    C++11新標(biāo)準(zhǔn)還提供了另外一種為vector對象的元素賦初值的方法,即列表初始化。此時,用花括號括起來的0個或多個初始元素值被賦給vector對象:

    vector<string> articles = {"a", "an", "the"};

    之前已經(jīng)講過,C++語言提供了幾種不同的初始化方式。在大多數(shù)情況下這些初始化方式可以相互等價地使用,不過也并非一直如此。目前已經(jīng)介紹過的兩種例外情況是:

  • 使用拷貝初始化時(即使用=時),只能提供一個初始值;
  • 如果提供的是一個類內(nèi)初始值,則只能使用拷貝初始化或使用花括號的形式初始化。
  • 第三種特殊的要求是,如果提供的是初始元素值的列表,則只能把初始值都放在花括號里進(jìn)行列表初始化,而不能放在圓括號里:

    vector<string> v1{"a", "an", "the"}; // list initialization vector<string> v2("a", "an", "the"); // error

    創(chuàng)建指定數(shù)量的元素

    還可以用vector對象容納的元素數(shù)量和所有元素的統(tǒng)一初始值來初始化vector對象:

    vector<int> ivec(10, -1); // ten int elements, each initialized to -1 vector<string> svec(10, "hi!"); // ten strings; each element is "hi!"

    值初始化

    通常情況下,可以只提供vector對象容納的元素數(shù)量而不用略去初始值。此時庫會創(chuàng)建一個值初始化的(value-initialized)元素初值,并把它賦給容器中的所有元素。這個初值由vector對象中元素的類型決定。

    如果vector對象的元素是內(nèi)置類型,比如 int,則元素初始值自動設(shè)為0。如果元素是某種類類型,比如 string,則元素由類默認(rèn)初始化:

    vector<int> ivec(10); // ten elements, each initialized to 0 vector<string> svec(10); // ten elements, each an empty string

    對這種初始化的方式有兩個特殊限制:其一,有些類要求必須明確地提供初始值,如果vector對象中元素的類型不支持默認(rèn)初始化,我們就必須提供初始的元素值。對這種類型的對象來說,只提供元素的數(shù)量而不設(shè)定初始值無法完成初始化工作。

    其二,如果只提供了元素的數(shù)量而沒有設(shè)定初始值,只能使用直接初始化:

    vector<int> vi = 10; // error: must use direct initialization to supply a size

    這里的10是用來說明如何初始化vector對象的,我們用它的本意是想創(chuàng)建含有10個值初始化了的元素的vector對象,而非把數(shù)字10“拷貝”到vector中。因此,此時不宜使用拷貝初始化。

    列表初始值還是元素數(shù)量

    在某些情況下,初始化的真實(shí)含義依賴于傳遞初始值時用的是花括號還是圓括號

    例如,用一個整數(shù)來初始化vector<int>時,整數(shù)的含義可能是vector對象的容量也可能是元素的值。類似的,用兩個整數(shù)來初始化vector<int>時,這兩個整數(shù)可能一個是vector對象的容量,另一個是元素的初值,也可能它們是容量為2的vector對象中兩個元素的初值。通過使用花括號或圓括號可以區(qū)分上述這些含義:

    vector<int> v1(10); // v1 has ten elements with value 0 vector<int> v2{10}; // v2 has one element with value 10 vector<int> v3(10, 1); // v3 has ten elements with value 1 vector<int> v4{10, 1}; // v4 has two elements with values 10 and 1

    如果用的是圓括號,可以說提供的值是用來構(gòu)造(construct)vector對象的。例如,v1的初始值說明了vector對象的容量; v3的兩個初始值則分別說明了vector對象的容量和元素的初值。

    如果用的是花括號,可以表述成我們想列表初始化(list initialize)該vector對象。也就是說,初始化過程會盡可能地把花括號內(nèi)的值當(dāng)成是元素初始值的列表來處理,只有在無法執(zhí)行列表初始化時才會考慮其他初始化方式。

    在上例中,給v2和v4提供的初始值都能作為元素的值,所以它們都會執(zhí)行列表初始化,vector對象v2包含一個元素而vector對象v4包含兩個元素。

    另一方面,如果初始化時使用了花括號的形式但是提供的值又不能用來列表初始化,就要考慮用這樣的值來構(gòu)造vector對象了。例如,要想列表初始化一個含有string對象的vector對象,應(yīng)該提供能賦給string對象的初值。此時不難區(qū)分到底是要列表初始化vector對象的元素還是用給定的容量值來構(gòu)造vector對象:(Note:勉強(qiáng)初始化

    vector<string> v5{"hi"}; // list initialization: v5 has one element vector<string> v6("hi"); // error: can't construct a vector from a string literal vector<string> v7{10}; // v7 has ten default-initialized elements vector<string> v8{10, "hi"}; // v8 has ten elements with value "hi"

    盡管在上面的例子中除了第二條語句之外都用了花括號,但其實(shí)只有v5是列表初始化。要想列表初始化 vector對象,花括號里的值必須與元素類型相同。顯然不能用int初始化 string對象,所以v7和v8提供的值不能作為元素的初始值。確認(rèn)無法執(zhí)行列表初始化后,編譯器會嘗試用默認(rèn)值初始化vector對象

    向vector對象中添加元素

    對vector對象來說,直接初始化的方式適用于三種情況:

  • 初始值已知且數(shù)量較少,vector<T> v5{a, b, c…}
  • 初始值是另一個vector對象的副本,vector<T> v2(v1)
  • 所有元素的初始值都一樣。vector<T> v3 (n, val)
  • 然而更常見的情況是:創(chuàng)建一個vector對象時并不清楚實(shí)際所需的元素個數(shù),元素的值也經(jīng)常無法確定。還有些時候即使元素的初值已知,但如果這些值總量較大而各不相同,那么在創(chuàng)建vector對象的時候執(zhí)行初始化操作也會顯得過于煩瑣。

    舉個例子,如果想創(chuàng)建一個vector對象令其包含從0到9共10個元素,使用列表初始化的方法很容易做到這一點(diǎn),但如果vector對象包含的元素是從0到99或者從0到999呢?這時通過列表初始化把所有元素都一一羅列出來就不太合適了。

    對于此例來說,更好的處理方法是先創(chuàng)建一個空vector,然后在運(yùn)行時再利用vector的成員函數(shù)push_back向其中添加元素。push_back 負(fù)責(zé)把一個值當(dāng)成vector對象的尾元素“壓到(push)” vector對象的“尾端(back)”。例如:

    vector<int> v2; // empty vector for (int i = 0; i != 100; ++i)v2.push_back(i); // append sequential integers to v2 // at end of loop v2 has 100 elements, values 0 . . . 99

    同樣的,如果直到運(yùn)行時才能知道vector對象中元素的確切個數(shù),也應(yīng)該使用剛剛這種方法創(chuàng)建vector對象并為其賦值。例如,有時需要實(shí)時讀入數(shù)據(jù)然后將其賦予vector對象:

    // read words from the standard input and store them as elements in a vector string word; vector<string> text; // empty vector while (cin >> word) {text.push_back(word); // append word to text }

    關(guān)鍵概念:vector對象能高效增長

    C++標(biāo)準(zhǔn)要求vector應(yīng)該能在運(yùn)行時高效快速地添加元素。因此既然 vector對象能高效地增長,那么在定義vector對象的時候設(shè)定其大小也就沒什么必要了,事實(shí)上如果這么做性能可能更差。只有一種例外情況,就是所有(all)元素的值都一樣。一旦元素的值有所不同,更有效的辦法是先定義一個空的vector對象,再在運(yùn)行時向其中添加具體值。此外,在未來將介紹vector還提供了方法,允許我們進(jìn)一步提升動態(tài)添加元素的性能。

    開始的時候創(chuàng)建空的vector對象,在運(yùn)行時再動態(tài)添加元素,這一做法與C語言及其他大多數(shù)語言中內(nèi)置數(shù)組類型的用法不同。特別是如果用慣了C或者Java,可以預(yù)計在創(chuàng)建vector對象時順便指定其容量是最好的。然而事實(shí)上,通常的情況是恰恰相反。

    (在Java中,如果你一開始知道容器的容量,就設(shè)定容器的容量,這樣可以減少容器擴(kuò)容時所帶來的消耗)

    向vector對象添加元素蘊(yùn)含的編程假定

    由于能高效便捷地向vector對象中添加元素,很多編程工作被極大簡化了。然而,這種簡便性也伴隨著一些對編寫程序更高的要求:其中一條就是必須要確保所寫的循環(huán)正確無誤,特別是在循環(huán)有可能改變vector對象容量的時候。

    隨著對vector的更多使用,我們還會逐漸了解到其他一些隱含的要求,其中一條是現(xiàn)在就要指出的:如果循環(huán)體內(nèi)部包含有向vector對象添加元素的語句,則不能使用范圍for循環(huán),具體原因在日后詳細(xì)解釋。

    范圍for語句體內(nèi)不應(yīng)改變其所遍歷序列的大小。

    (在Java中,如果for循環(huán)遍歷一個List時,增刪元素,后臺會拋出ConcurrentModificationException)

    其他vector操作

    ..
    v.empty()如果v不含有任何元素,返回真;否則返回假
    v.size()返回v中元素的個數(shù)
    v.push_back(t)向v的尾端添加一個值為t的元素
    v[n]返回v中第n個位置上元素的引用
    v1 = v2用v2中元素的拷貝替換v1中的元素
    v1 ={a,b,c…}用列表中元素的拷貝替換v1中的元素
    vl == v2v1和v2相等當(dāng)且僅當(dāng)它們的元素數(shù)量相同且對應(yīng)位置的元素值都相同
    v1 != v2.
    <, <=, >, >=顧名思義,以字典順序進(jìn)行比較

    訪問vector對象中元素的方法和訪問string對象中字符的方法差不多,也是通過元素在vector對象中的位置。例如,可以使用范圍for語句處理vector對象中的所有元素:

    vector<int> v{1,2,3,4,5,6,7,8,9}; for (auto &i : v) // for each element in v (note: i is a reference)i *= i; // square the element value for (auto i : v) // for each element in vcout << i << " "; // print the element cout << endl;

    vector的empty和size兩個成員與string 的同名成員功能完全一致:

    • empty檢查vector對象是否包含元素然后返回一個布爾值;

    • size則返回vector對象中元素的個數(shù),返回值的類型是由vector定義的size_type類型。

    要使用size type,需首先指定它是由哪種類型定義的。vector對象的類型總是包含著元素的類型:

    vector<int>::size_type //正確 vector::size_type//錯誤

    vector比較

    各個相等性運(yùn)算符和關(guān)系運(yùn)算符也與string 的相應(yīng)運(yùn)算符功能一致。

    兩個vector對象相等當(dāng)且僅當(dāng)它們所含的元素個數(shù)相同,而且對應(yīng)位置的元素值也相同。

    關(guān)系運(yùn)算符依照字典順序進(jìn)行比較:

    • 如果兩個vector對象的容量不同,但是在相同位置上的元素值都一樣,則元素較少的vector對象小于元素較多的vector對象;

    • 若元素的值有區(qū)別,則vector對象的大小關(guān)系由第一對相異的元素值的大小關(guān)系決定。

    只有當(dāng)元素的值可比較時,vector對象才能被比較。

    • 一些類,如 string等,確實(shí)定義了自己的相等性運(yùn)算符和關(guān)系運(yùn)算符;
    • 另外一些,如 Sales_item類支持的運(yùn)算已經(jīng)全都羅列在第一章中了,顯然并不支持相等性判斷和關(guān)系運(yùn)算等操作。因此,不能比較兩個vector<Sales_item>對象。

    計算vector內(nèi)對象的索引

    使用下標(biāo)運(yùn)算符能獲取到指定的元素。和 string一樣,vector對象的下標(biāo)也是從О開始計起,下標(biāo)的類型是相應(yīng)的 size_type類型。只要vector對象不是一個常量,就能向下標(biāo)運(yùn)算符返回的元素賦值。此外,也能通過計算得到 vector 內(nèi)對象的索引,然后直接獲取索引位置上的元素。

    舉個例子,假設(shè)有一組成績的集合,其中成績的取值是從0到100。以10分為一個分?jǐn)?shù)段,要求統(tǒng)計各個分?jǐn)?shù)段各有多少個成績。顯然,從0到100總共有101種可能的成績?nèi)≈?#xff0c;這些成績分布在11個分?jǐn)?shù)段上:每10個分?jǐn)?shù)構(gòu)成一個分?jǐn)?shù)段,這樣的分?jǐn)?shù)段有10個,額外還有一個分?jǐn)?shù)段表示滿分100分。這樣第一個分?jǐn)?shù)段將統(tǒng)計成績在0到9之間的數(shù)量;第二個分?jǐn)?shù)段將統(tǒng)計成績在10到19之間的數(shù)量,以此類推。最后一個分?jǐn)?shù)段統(tǒng)計滿分100分的數(shù)量。

    // count the number of grades by clusters of ten: 0--9, 10--19, . .. 90--99, 100 vector<unsigned> scores(11, 0); // 11 buckets, all initially 0 unsigned grade; while (cin >> grade) { // read the gradesif (grade <= 100) // handle only valid grades++scores[grade/10]; // increment the counter for the current cluster }

    輸入:

    42 65 95 100 39 67 95 76 88 76 83 92 76 93

    如果輸出scores,則為:

    0 0 0 1 1 0 2 3 2 4 1

    不能用下標(biāo)形式添加元素

    剛接觸C++語言的程序員也許會認(rèn)為可以通過vector對象的下標(biāo)形式來添加元素,事實(shí)并非如此。下面的代碼試圖為vector對象ivec添加10個元素:

    vector<int> ivec; // empty vector for (decltype(ivec.size()) ix = 0; ix != 10; ++ix)ivec[ix] = ix; // disaster: ivec has no elements

    然而,這段代碼是錯誤的:ivec是一個空 vector,根本不包含任何元素,當(dāng)然也就不能通過下標(biāo)去訪問任何元素!如前所述,正確的方法是使用push_back:

    for (decltype(ivec.size()) ix = 0; ix != 10; ++ix)ivec.push_back(ix); // ok: adds a new element with value ix

    vector對象(以及string對象)的下標(biāo)運(yùn)算符可用于訪問已存在的元素,而不能用于添加元素。

    提示:只能對確知已存在的元素執(zhí)行下標(biāo)操作!

    關(guān)于下標(biāo)必須明確的一點(diǎn)是:只能對確知已存在的元素執(zhí)行下標(biāo)操作。例如,

    vector<int> ivec; // empty vector cout << ivec[0]; // error: ivec has no elements!vector<int> ivec2(10); // vector with ten elements cout << ivec2[10]; // error: ivec2 has elements 0 . . . 9

    試圖用下標(biāo)的形式去訪問一個不存在的元素將引發(fā)錯誤,不過這種錯誤不會被編譯器發(fā)現(xiàn),而是在運(yùn)行時產(chǎn)生一個不可預(yù)知的值。

    不幸的是,這種通過下標(biāo)訪問不存在的元素的行為非常常見,而且會產(chǎn)生很嚴(yán)重的后果。所謂的緩沖區(qū)溢出(buffer overflow)指的就是這類錯誤,這也是導(dǎo)致PC及其他設(shè)備上應(yīng)用程序出現(xiàn)安全問題的一個重要原因。

    確保下標(biāo)合法的一種有效手段就是盡可能使用范圍for語句。

    迭代器介紹

    已經(jīng)知道可以使用下標(biāo)運(yùn)算符來訪問string 對象的字符或vector對象的元素,還有另外一種更通用的機(jī)制也可以實(shí)現(xiàn)同樣的目的,這就是迭代器( iterator)。

    除了vector之外,標(biāo)準(zhǔn)庫還定義了其他幾種容器。所有標(biāo)準(zhǔn)庫容器都可以使用迭代器,但是其中只有少數(shù)幾種才同時支持下標(biāo)運(yùn)算符。(Note:日后就用迭代器迭代)

    嚴(yán)格來說,string對象不屬于容器類型,但是string支持很多與容器類型類似的操作。vector支持下標(biāo)運(yùn)算符,這點(diǎn)和 string一樣;string支持迭代器,這也和 vector是一樣的。

    類似于指針類型,迭代器也提供了對對象的間接訪問

    • 就迭代器而言,其對象是容器中的元素或者string對象中的字符。
    • 使用迭代器可以訪問某個元素,迭代器也能從一個元素移動到另外一個元素。
    • 迭代器有有效和無效之分,這一點(diǎn)和指針差不多。有效的迭代器或者指向某個元素,或者指向容器中尾元素的下一位置;其他所有情況都屬于無效。

    使用迭代器

    和指針不一樣的是,獲取迭代器不是使用取地址符,有迭代器的類型同時擁有返回迭代器的成員。比如,這些類型都擁有名為beginend的成員,其中 begin 成員負(fù)責(zé)返回指向第一個元素(或第一個字符)的迭代器。如有下述語句:

    // the compiler determines the type of b and e; see § 2.5.2 (p. 68) // b denotes the first element and e denotes one past the last element in v auto b = v.begin(), e = v.end(); // b and e have the same type

    end成員則負(fù)責(zé)返回指向容器(或string對象)“尾元素的下一位置(one past the end)"的迭代器,也就是說,該迭代器指示的是容器的一個本不存在的“尾后(off the end)”元素。這樣的迭代器沒什么實(shí)際含義,僅是個標(biāo)記而已,表示我們已經(jīng)處理完了容器中的所有元素。end成員返回的迭代器常被稱作尾后迭代器(off-the-end iterator)或者簡稱為尾迭代器(end iterator)。特殊情況下如果容器為空,則 begin和 end返回的是同一個迭代器。

    如果容器為空,則begin和end返回的是同一個迭代器,都是尾后迭代器。

    一般來說,我們不清楚(不在意)迭代器準(zhǔn)確的類型到底是什么。在上面的例子中,使用auto關(guān)鍵字定義變量b和e ,這兩個變量的類型也就是begin和 end的返回值類型,稍后做更詳細(xì)的介紹。

    迭代器運(yùn)算符

    下表列舉了迭代器支持的一些運(yùn)算。使用==和!=來比較兩個合法的迭代器是否相等,如果兩個迭代器指向的元素相同或者都是同一個容器的尾后迭代器,則它們相等;否則就說這兩個迭代器不相等。

    ..
    *iter返回迭代器iter所指元素的引用
    iter->mem解引用iter并獲取該元素的名為mem的成員,等價于(*iter).mem
    ++iter令iter指示容器中的下一個元素
    –iter令iter指示容器中的上一個元素
    iter1 == iter2判斷兩個迭代器是否相等,如果兩個迭代器指示的是同一個元素或者它們是同一個容器的尾后迭代器,則相等;反之,不相等
    iter1 != iter2判斷兩個迭代器是否不相等

    和指針類似,也能通過解引用迭代器來獲取它所指示的元素,執(zhí)行解引用的迭代器必須合法并確實(shí)指示著某個元素。試圖解引用一個非法迭代器或者尾后迭代器都是未被定義的行為。

    舉個例子,用迭代器把string對象的第一個字母改為了大寫形式:

    string s("some string"); if (s.begin() != s.end()) { // make sure s is not empty auto it = s.begin(); // it denotes the first character in s*it = toupper(*it); // make that character uppercase }

    若輸出s,結(jié)果將是:

    Some string

    將迭代器從一個元素移動到另外一個元素

    迭代器使用遞增(++)運(yùn)算符來從一個元素移動到下一個元素。從邏輯上來說,迭代器的遞增和整數(shù)的遞增類似,整數(shù)的遞增是在整數(shù)值上“加1“,迭代器的遞增則是將迭代器“向前移動一個位置”。

    因?yàn)閑nd返回的迭代器并不實(shí)際指示某個元素,所以不能對其進(jìn)行遞增或解引用的操作。

    之前有一個程序把string對象中第一個單詞改寫為大寫形式,現(xiàn)在利用迭代器及其遞增運(yùn)算符可以實(shí)現(xiàn)相同的功能:

    // process characters in s until we run out of characters or we hit a whitespace for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it)*it = toupper(*it); // capitalize the current character

    關(guān)鍵概念:泛型編程

    原來使用C或Java的程序員在轉(zhuǎn)而使用C++語言之后,會對for循環(huán)中使用!=而非<進(jìn)行判斷有點(diǎn)兒奇怪。C++程序員習(xí)慣性地使用!=,其原因和他們更愿意使用迭代器而非下標(biāo)的原因一樣(支持下標(biāo)的容器只有少數(shù));因?yàn)?strong>這種編程風(fēng)格在標(biāo)準(zhǔn)庫提供的所有容器上都有效。

    之前已經(jīng)說過,只有string和 vector等一些標(biāo)準(zhǔn)庫類型有下標(biāo)運(yùn)算符,而并非全都如此。

    與之類似,所有標(biāo)準(zhǔn)庫容器的迭代器都定義了==和!=,但是它們中的大多數(shù)都沒有定義<運(yùn)算符。因此,只要我們養(yǎng)成使用迭代器和!=的習(xí)慣,就不用太在意用的到底是哪種容器類型。

    迭代器類型

    就像不知道string 和 vector的size_type成員到底是什么類型一樣,一般來說我們也不知道(其實(shí)是無須知道)迭代器的精確類型。而實(shí)際上,那些擁有迭代器的標(biāo)準(zhǔn)庫類型使用iterator和const_iterator來表示迭代器的類型:

    vector<int>::iterator it; // it can read and write vector<int> elements string::iterator it2; // it2 can read and write characters in a string vector<int>::const_iterator it3; // it3 can read but not write elements string::const_iterator it4; // it4 can read but not write characters

    const_iterator和常量指針差不多,能讀取但不能修改它所指的元素值。相反,iterator的對象可讀可寫。

    • 如果vector對象或string對象是一個常量,只能使用const_iterator;
    • 如果vector對象或string對象不是常量,那么既能使用iterator也能使用const_iterator。

    術(shù)語:迭代器和迭代器類型

    迭代器這個名詞有三種不同的含義:

  • 可能是迭代器概念本身,
  • 可能是指容器定義的迭代器類型,
  • 可能是指某個迭代器對象。
  • 重點(diǎn)是理解存在一組概念上相關(guān)的類型,我們認(rèn)定某個類型是迭代器當(dāng)且僅當(dāng)它支持一套操作,這套操作使得我們能訪問容器的元素或者從某個元素移動到另外一個元素。

    每個容器類定義了一個名為 iterator的類型,該類型支持迭代器概念所規(guī)定的一套操作。

    begin和end運(yùn)算符

    begin和end返回的具體類型由對象是否是常量決定,

    • 如果對象是常量,begin和end返回const_iterator;
    • 如果對象不是常量,返回iterator:
    vector<int> v; const vector<int> cv ; auto itl = v.begin();//it1的類型是vector<int>::iterator auto it2 = cv.begin ();//it2的類型是vector<int>::const_iterator

    有時候這種默認(rèn)的行為并非我們所要。

    如果對象只需讀操作而無須寫操作的話最好使用常量類型(比如 const_iterator)。為了便于專門得到const_iterator類型的返回值,C++11新標(biāo)準(zhǔn)引入了兩個新函數(shù),分別是cbegin和cend:

    auto it3 = v.cbegin();//it3的類型是vector<int>::const_iterator

    類似于begin和 end,上述兩個新函數(shù)也分別返回指示容器第一個元素或最后元素下一位置的迭代器。有所不同的是,不論vector對象(或string對象)本身是否是常量,返回值都是const_iterator。

    結(jié)合解引用和成員訪問操作

    解引用迭代器可獲得迭代器所指的對象,如果該對象的類型恰好是類,就有可能希望進(jìn)一步訪問它的成員。例如,對于一個由字符串組成的vector對象來說,要想檢查其元素是否為空,令it是該vector對象的迭代器,只需檢查it所指字符串是否為空就可以了,其代碼如下所示:

    (*it).empty()

    注意,(*it). empty()中的圓括號必不可少,具體原因稍后介紹,該表達(dá)式的含義是先對it解引用,然后解引用的結(jié)果再執(zhí)行點(diǎn)運(yùn)算符。如果不加圓括號,點(diǎn)運(yùn)算符將由it來執(zhí)行,而非it解引用的結(jié)果:

    (*it).empty() // dereferences it and calls the member empty on the resulting object *it.empty() // error: attempts to fetch the member named empty from it// but it is an iterator and has no member named empty

    上面第二個表達(dá)式的含義是從名為it的對象中尋找其 empty成員,顯然it是一個迭代器,它沒有哪個成員是叫empty的,所以第二個表達(dá)式將發(fā)生錯誤。

    為了簡化上述表達(dá)式,C++語言定義了箭頭運(yùn)算符(->)。箭頭運(yùn)算符把解引用和成員訪問兩個操作結(jié)合在一起,也就是說,it->mem和(*it).mem表達(dá)的意思相同。

    例如,假設(shè)用一個名為text的字符串向量存放文本文件中的數(shù)據(jù),其中的元素或者是一句話或者是一個用于表示段落分隔的空字符串。如果要輸出text中第一段的內(nèi)容,可以利用迭代器寫一個循環(huán)令其遍歷text,直到遇到空字符串的元素為止:

    // print each line in text up to the first blank line for (auto it = text.cbegin(); it != text.cend() && !it->empty(); ++it)cout << *it << endl;

    某些對vector對象的操作會使迭代器失效

    曾經(jīng)介紹過,雖然vector對象可以動態(tài)地增長,但是也會有一些副作用。已知的一個限制是不能在范圍for循環(huán)中向vector對象添加元素。另外一個限制是任何一種可能改變vector對象容量的操作,比如 push_back,都會使該vector對象的迭代器失效。日后將詳細(xì)解釋迭代器是如何失效的。

    謹(jǐn)記,但凡是使用了迭代器的循環(huán)體,都不要向迭代器所屬的容器添加元素。

    迭代器運(yùn)算

    迭代器的遞增運(yùn)算令迭代器每次移動一個元素,所有的標(biāo)準(zhǔn)庫容器都有支持遞增運(yùn)算的迭代器。類似的,也能用==和!=對任意標(biāo)準(zhǔn)庫類型的兩個有效迭代器進(jìn)行比較。

    string和 vector的迭代器提供了更多額外的運(yùn)算符,一方面可使得迭代器的每次移動跨過多個元素,另外也支持迭代器進(jìn)行關(guān)系運(yùn)算。所有這些運(yùn)算被稱作迭代器運(yùn)算(iterator arithmetic),其細(xì)節(jié)如表列出:

    ..
    iter + n迭代器加上一個整數(shù)值仍得一個迭代器,迭代器指示的新位置與原來相比向前移動了若干個元素。結(jié)果迭代器或者指示容器內(nèi)的一個元素,或者指示容器尾元素的下一位置
    iter - n迭代器減去一個整數(shù)值仍得一個迭代器,迭代器指示的新位置與原來相比向后移動了若干個元素。結(jié)果迭代器或者指示容器內(nèi)的一個元素,或者指示容器尾元素的下一位置
    iter1 += n迭代器加法的復(fù)合賦值語句,將iter1加n的結(jié)果賦給iter1
    iter1 -= n迭代器減法的復(fù)合賦值語句,將iter1減n的結(jié)果賦給iter1
    iter1 - iter2兩個迭代器相減的結(jié)果是它們之間的距離,也就是說,將運(yùn)算符右側(cè)的迭代器向前移動差值個元素后將得到左側(cè)的迭代器。參與運(yùn)算的兩個迭代器必須指向的是同一個容器中的元素或者尾元素的下一位置
    >、>=、<、<=迭代器的關(guān)系運(yùn)算符,如果某迭代器指向的容器位置在另一個迭代器所指位置之前,則說前者小于后者。參與運(yùn)算的兩個迭代器必須指向的是同一個容器中的元素或者尾元素的下一位置

    迭代器的算術(shù)運(yùn)算

    可以令迭代器和一個整數(shù)值相加(或相減),其返回值是向前(或向后)移動了若干個位置的迭代器。執(zhí)行這樣的操作時,結(jié)果迭代器或者指示原vector對象(或string對象)內(nèi)的一個元素,或者指示原vector對象(或string對象)尾元素的下一位置。

    舉個例子,下面的代碼得到一個迭代器,它指向某vector對象中間位置的元素:

    // compute an iterator to the element closest to the midpoint of vi auto mid = vi.begin() + vi.size() / 2;

    對于string或vector的迭代器來說,除了判斷是否相等,還能使用關(guān)系運(yùn)算符(<、<=、>、>=)對其進(jìn)行比較。參與比較的兩個迭代器必須合法而且指向的是同一個容器的元素(或者尾元素的下一位置)。例如,假設(shè)it和mid是同一個vector對象的兩個迭代器,可以用下面的代碼來比較它們所指的位置孰前孰后:

    if (it < mid)// process elements in the first half of vi

    只要兩個迭代器指向的是同一個容器中的元素或者尾元素的下一位置,就能將其相減,所得結(jié)果是兩個迭代器的距離。所謂距離指的是右側(cè)的迭代器向前移動多少位置就能追上左側(cè)的迭代器,其類型是名為 difference_type 的帶符號整型數(shù)。string和vector都定義了difference_type,因?yàn)檫@個距離可正可負(fù),所以difference_type是帶符號類型的。

    使用迭代器運(yùn)算

    使用迭代器運(yùn)算的一個經(jīng)典算法是二分搜索。

    二分搜索從有序序列中尋找某個給定的值。二分搜索從序列中間的位置開始搜索,

    • 如果中間位置的元素正好就是要找的元素,搜索完成;
    • 如果不是,
      • 假如該元素小于要找的元素,則在序列的后半部分繼續(xù)搜素;
      • 假如該元素大于要找的元素,則在序列的前半部分繼續(xù)搜索。

    在縮小的范圍中計算一個新的中間元素并重復(fù)之前的過程,直至最終找到目標(biāo)或者沒有元素可供繼續(xù)搜索。

    // text must be sorted // beg and end will denote the range we're searching auto beg = text.begin(), end = text.end(); auto mid = text.begin() + (end - beg)/2; // original midpoint // while there are still elements to look at and we haven't yet found sought while (mid != end && *mid != sought) {if (sought < *mid) // is the element we want in the first half?end = mid; // if so, adjust the range to ignore the second halfelse // the element we want is in the second halfbeg = mid + 1; // start looking with the element just after midmid = beg + (end - beg)/2; // new midpoint }

    數(shù)組

    數(shù)組是一種類似于標(biāo)準(zhǔn)庫類型vector的數(shù)據(jù)結(jié)構(gòu),但是在性能和靈活性的權(quán)衡上又與vector有所不同。

    與vector相似的地方是,數(shù)組也是存放類型相同的對象的容器,這些對象本身沒有名字,需要通過其所在位置訪問。

    與vector不同的地方是,數(shù)組的大小確定不變,不能隨意向數(shù)組中增加元素。因?yàn)閿?shù)組的大小固定,因此對某些特殊的應(yīng)用來說程序的運(yùn)行時性能較好,但是相應(yīng)地也損失了一些靈活性。

    如果不清楚元素的確切個數(shù),請使用vector。

    定義和初始化內(nèi)置數(shù)組

    數(shù)組是一種復(fù)合類型。數(shù)組的聲明形如 a[d],其中 a是數(shù)組的名字,d是數(shù)組的維度。維度說明了數(shù)組中元素的個數(shù),因此必須大于0。數(shù)組中元素的個數(shù)也屬于數(shù)組類型的一部分,編譯的時候維度應(yīng)該是已知的。也就是說,維度必須是一個常量表達(dá)式:

    unsigned cnt = 42; // not a constant expression constexpr unsigned sz = 42; // constant expression// constexpr see § 2.4.4 (p. 66) int arr[10]; // array of ten ints int *parr[sz]; // array of 42 pointers to int string bad[cnt]; // error: cnt is not a constant expression string strs[get_size()]; // ok if get_size is constexpr, error otherwise

    默認(rèn)情況下,數(shù)組的元素被默認(rèn)初始化。

    和內(nèi)置類型的變量一樣,如果在函數(shù)內(nèi)部定義了某種內(nèi)置類型的數(shù)組,那么默認(rèn)初始化會令數(shù)組含有未定義的值。

    定義數(shù)組的時候必須指定數(shù)組的類型,不允許用auto關(guān)鍵字由初始值的列表推斷類型。另外和 vector一樣,數(shù)組的元素應(yīng)為對象,因此不存在引用的數(shù)組。

    顯式初始化數(shù)組元素

    可以對數(shù)組的元素進(jìn)行列表初始化,此時允許忽略數(shù)組的維度。

    • 如果在聲明時沒有指明維度,編譯器會根據(jù)初始值的數(shù)量計算并推測出來;
    • 相反,如果指明了維度,那么初始值的總數(shù)量不應(yīng)該超出指定的大小。
    • 如果維度比提供的初始值數(shù)量大,則用提供的初始值初始化靠前的元素,剩下的元素被初始化成默認(rèn)值:
    const unsigned sz = 3; int ia1[sz] = {0,1,2}; // array of three ints with values 0, 1, 2 int a2[] = {0, 1, 2}; // an array of dimension 3 int a3[5] = {0, 1, 2}; // equivalent to a3[] = {0, 1, 2, 0, 0} string a4[3] = {"hi", "bye"}; // same as a4[] = {"hi", "bye", ""} int a5[2] = {0,1,2}; // error: too many initializers

    字符數(shù)組的特殊性

    字符數(shù)組有一種額外的初始化形式,我們可以用字符串字面值對此類數(shù)組初始化。當(dāng)使用這種方式時,一定要注意字符串字面值的結(jié)尾處還有一個空字符,這個空字符也會像字符串的其他字符一樣被拷貝到字符數(shù)組中去:

    char a1[] = {'C', '+', '+'}; // list initialization, no null char a2[] = {'C', '+', '+', '\0'}; // list initialization, explicit null char a3[] = "C++"; // null terminator added automatically const char a4[6] = "Daniel"; // error: no space for the null!

    不允許拷貝和賦值

    不能將數(shù)組的內(nèi)容拷貝給其他數(shù)組作為其初始值,也不能用數(shù)組為其他數(shù)組賦值:

    int a[] = {0, 1, 2}; // array of three ints int a2[] = a; // error: cannot initialize one array with another a2 = a; // error: cannot assign one array to another

    一些編譯器支持?jǐn)?shù)組的賦值,這就是所謂的編譯器擴(kuò)展(compiler extension)。但一般來說,最好避免使用非標(biāo)準(zhǔn)特性,因?yàn)楹蟹菢?biāo)準(zhǔn)特性的程序很可能在其他編譯器上無法正常工作。

    理解復(fù)雜的數(shù)組聲明

    和 vector一樣,數(shù)組能存放大多數(shù)類型的對象。例如,可以定義一個存放指針的數(shù)組。又因?yàn)閿?shù)組本身就是對象,所以允許定義數(shù)組的指針及數(shù)組的引用。在這幾種情況中,定義存放指針的數(shù)組比較簡單和直接,但是定義數(shù)組的指針或數(shù)組的引用就稍微復(fù)雜一點(diǎn)了:

    int *ptrs[10]; // ptrs is an array of ten pointers to int int &refs[10] = /* ? */; // error: no arrays of references int (*Parray)[10] = &arr; // Parray points to an array of ten ints int (&arrRef)[10] = arr; // arrRef refers to an array of ten ints

    默認(rèn)情況下,類型修飾符從右向左依次綁定。

    對于ptrs來說,從右向左理解其含義比較簡單:首先知道我們定義的是一個大小為10的數(shù)組,它的名字是ptrs,然后知道數(shù)組中存放的是指向int的指針。

    但是對于Parray來說,從右向左理解就不太合理了。因?yàn)閿?shù)組的維度是緊跟著被聲明的名字的,所以就數(shù)組而言,由內(nèi)向外閱讀要比從右向左好多了。

    由內(nèi)向外的順序可幫助我們更好地理解 Parray 的含義:

    • 首先是圓括號括起來的部分,*Parray意味著Parray是個指針,

    • 接下來觀察右邊,可知道Parray是個指向大小為10的數(shù)組的指針,

    • 最后觀察左邊,知道數(shù)組中的元素是int。

    這樣最終的含義就明白無誤了,Parray是一個指針,它指向一個int數(shù)組,數(shù)組中包含10個元素。

    同理,(&arrRef)表示arrRef是一個引用,它引用的對象是一個大小為10的數(shù)組,數(shù)組中元素的類型是int。

    當(dāng)然,對修飾符的數(shù)量并沒有特殊限制:

    int *(&arry)[10] = ptrs; // arry is a reference to an array of ten pointers

    按照由內(nèi)向外的順序閱讀上述語句,

    • 首先知道arry是一個引用,
    • 然后觀察右邊知道, arry引用的對象是一個大小為10的數(shù)組,
    • 最后觀察左邊知道,數(shù)組的元素類型是指向int的指針。

    這樣,arry就是一個含有10個int型指針的數(shù)組的引用。

    要想理解數(shù)組聲明的含義,最好的辦法是從數(shù)組的名字開始按照由內(nèi)向外的順序閱讀

    訪問數(shù)組元素

    與標(biāo)準(zhǔn)庫類型vector和 string一樣,數(shù)組的元素也能使用范圍for語句或下標(biāo)運(yùn)算符來訪問。數(shù)組的索引從О開始,以一個包含10個元素的數(shù)組為例,它的索引從0到9,而非從1到10。

    在使用數(shù)組下標(biāo)的時候,通常將其定義為size_t類型。size_t是一種機(jī)器相關(guān)的無符號類型,它被設(shè)計得足夠大以便能表示內(nèi)存中任意對象的大小。在 cstddef頭文件中定義了size_t類型,這個文件是C標(biāo)準(zhǔn)庫stddef.h頭文件的C++語言版本。

    數(shù)組除了大小固定這一特點(diǎn)外,其他用法與vector基本類似。例如,可以用數(shù)組來記錄各分?jǐn)?shù)段的成績個數(shù):

    // count the number of grades by clusters of ten: 0--9, 10--19, ... 90--99, 100 unsigned scores[11] = {}; // 11 buckets, all value initialized to 0 unsigned grade; while (cin >> grade) {if (grade <= 100)++scores[grade/10]; // increment the counter for the current cluster }

    數(shù)組下標(biāo)運(yùn)算符與vector下標(biāo)運(yùn)算符不太明顯的區(qū)別是,

    • 數(shù)組的下標(biāo)運(yùn)算符是由C++語言直接定義的,這個運(yùn)算符能用在數(shù)組類型的運(yùn)算對象上。

    • vector所用的下標(biāo)運(yùn)算符是庫模板vector定義的,只能用于vector類型的運(yùn)算對象。

    與vector和 string一樣,當(dāng)需要遍歷數(shù)組的所有元素時,最好的辦法也是使用范圍for語句。例如,下面的程序輸出所有的scores:

    for (auto i : scores) // for each counter in scorescout << i << " "; // print the value of that counter cout << endl;

    因?yàn)榫S度是數(shù)組類型的一部分,所以系統(tǒng)知道數(shù)組scores 中有多少個元素,使用范圍for語句可以減輕人為控制遍歷過程的負(fù)擔(dān)。

    檢查下標(biāo)的值

    與vector和 string一樣,數(shù)組的下標(biāo)是否在合理范圍之內(nèi)由程序員負(fù)責(zé)檢查,所謂合理就是說下標(biāo)應(yīng)該大于等于0而且小于數(shù)組的大小。要想防止數(shù)組下標(biāo)越界,除了小心謹(jǐn)慎注意細(xì)節(jié)以及對代碼進(jìn)行徹底的測試之外,沒有其他好辦法。對于一個程序來說,即使順利通過編譯并執(zhí)行,也不能肯定它不包含此類致命的錯誤。

    大多數(shù)常見的安全問題都源于緩沖區(qū)溢出錯誤。當(dāng)數(shù)組或其他類似數(shù)據(jù)結(jié)構(gòu)的下標(biāo)越界并試圖訪問非法內(nèi)存區(qū)域時,就會產(chǎn)生此類錯誤。

    指針和數(shù)組

    在C++語言中,指針和數(shù)組有非常緊密的聯(lián)系。就如即將介紹的,使用數(shù)組的時候編譯器一般會把它轉(zhuǎn)換成指針。

    通常情況下,使用取地址符來獲取指向某個對象的指針,取地址符可以用于任何對象。數(shù)組的元素也是對象,對數(shù)組使用下標(biāo)運(yùn)算符得到該數(shù)組指定位置的元素。因此像其他對象一樣,對數(shù)組的元素使用取地址符就能得到指向該元素的指針:

    string nums[] = {"one", "two", "three"}; // array of strings string *p = &nums[0]; // p points to the first element in nums

    然而,數(shù)組還有一個特性:在很多用到數(shù)組名字的地方,編譯器都會自動地將其替換為一個指向數(shù)組首元素的指針:

    string *p2 = nums; // equivalent to p2 = &nums[0]

    在大多數(shù)表達(dá)式中,使用數(shù)組類型的對象其實(shí)是使用一個指向該數(shù)組首元素的指針。

    由上可知,在一些情況下數(shù)組的操作實(shí)際上是指針的操作,這一結(jié)論有很多隱含的意思。其中一層意思是當(dāng)使用數(shù)組作為一個auto變量的初始值時,推斷得到的類型是指針而非數(shù)組:

    int ia[] = {0,1,2,3,4,5,6,7,8,9}; // ia is an array of ten ints auto ia2(ia); // ia2 is an int* that points to the first element in ia ia2 = 42; // error: ia2 is a pointer, and we can't assign an int to a pointer

    盡管ia是由10個整數(shù)構(gòu)成的數(shù)組,但當(dāng)使用ia作為初始值時,編譯器實(shí)際執(zhí)行的初始化過程類似于下面的形式:

    auto ia2(&ia[0]); // now it's clear that ia2 has type int*

    必須指出的是,當(dāng)使用decltype關(guān)鍵字時上述轉(zhuǎn)換不會發(fā)生,decltype(ia)返回的類型是由10個整數(shù)構(gòu)成的數(shù)組:

    // ia3 is an array of ten ints decltype(ia) ia3 = {0,1,2,3,4,5,6,7,8,9}; ia3 = p; // error: can't assign an int* to an array ia3[4] = i; // ok: assigns the value of i to an element in ia3

    指針也是迭代器

    與介紹的內(nèi)容相比,指向數(shù)組元素的指針擁有更多功能。vector和 string 的迭代器支持的運(yùn)算,數(shù)組的指針全都支持。例如,允許使用遞增運(yùn)算符將指向數(shù)組元素的指針向前移動到下一個位置上:

    int arr[] = {0,1,2,3,4,5,6,7,8,9}; int *p = arr; // p points to the first element in arr ++p; // p points to arr[1]

    就像使用迭代器遍歷vector對象中的元素一樣,使用指針也能遍歷數(shù)組中的元素。

    當(dāng)然,這樣做的前提是先得獲取到指向數(shù)組第一個元素的指針和指向數(shù)組尾元素的下一位置的指針。

    之前已經(jīng)介紹過,通過數(shù)組名字或者數(shù)組中首元素的地址都能得到指向首元素的指針;不過獲取尾后指針就要用到數(shù)組的另外一個特殊性質(zhì)了。我們可以設(shè)法獲取數(shù)組尾元素之后的那個并不存在的元素的地址:

    int *e = &arr[10]; // pointer just past the last element in arr

    這里顯然使用下標(biāo)運(yùn)算符索引了一個不存在的元素,arr有10個元素,尾元素所在位置的索引是9,接下來那個不存在的元素唯一的用處就是提供其地址用于初始化 e。就像尾后迭代器一樣,尾后指針也不指向具體的元素。因此,不能對尾后指針執(zhí)行解引用或遞增的操作。

    利用上面得到的指針能重寫之前的循環(huán),令其輸出arr的全部元素:

    for (int *b = arr; b != e; ++b)cout << *b << endl; // print the elements in arr

    標(biāo)準(zhǔn)庫函數(shù)begin和end

    盡管能計算得到尾后指針,但這種用法極易出錯。為了讓指針的使用更簡單、更安全,C++11新標(biāo)準(zhǔn)引入了兩個名為 begin和 end的函數(shù)。這兩個函數(shù)與容器中的兩個同名成員功能類似,不過數(shù)組畢竟不是類類型,因此這兩個函數(shù)不是成員函數(shù)。正確的使用形式是將數(shù)組作為它們的參數(shù):

    #include <iterator>int ia[] = {0,1,2,3,4,5,6,7,8,9}; // ia is an array of ten ints int *beg = begin(ia); // pointer to the first element in ia int *last = end(ia); // pointer one past the last element in ia

    begin函數(shù)返回指向ia首元素的指針,end函數(shù)返回指向ia尾元素下一位置的指針,這兩個函數(shù)定義在iterator頭文件中

    使用begin和 end可以很容易地寫出一個循環(huán)并處理數(shù)組中的元素。例如,假設(shè)arr是一個整型數(shù)組,下面的程序負(fù)責(zé)找到arr中的第一個負(fù)數(shù):

    // pbeg points to the first and pend points just past the last element in arr int *pbeg = begin(arr), *pend = end(arr); // find the first negative element, stopping if we've seen all the elements while (pbeg != pend && *pbeg >= 0)++pbeg;

    一個指針如果指向了某種內(nèi)置類型數(shù)組的尾元素的“下一位置”,則其具備與vector的end函數(shù)返回的與迭代器類似的功能。特別要注意,尾后指針不能執(zhí)行解引用和遞增操作

    指針運(yùn)算

    指向數(shù)組元素的指針可以執(zhí)行所有迭代器運(yùn)算。這些運(yùn)算,包括

    • 解引用、
    • 遞增、
    • 比較、
    • 與整數(shù)相加、
    • 兩個指針相減

    用在指針和用在迭代器上意義完全一致。

    與整數(shù)相加

    給(從)一個指針加上(減去)某整數(shù)值,結(jié)果仍是指針。新指針指向的元素與原來
    的指針相比前進(jìn)了(后退了)該整數(shù)值個位置:

    constexpr size_t sz = 5; int arr[sz] = {1,2,3,4,5}; int *ip = arr; // equivalent to int *ip = &arr[0] int *ip2 = ip + 4; // ip2 points to arr[4], the last element in arr

    ip加上4所得的結(jié)果仍是一個指針,該指針?biāo)傅脑嘏cip原來所指的元素相比前進(jìn)了4個位置。

    給指針加上一個整數(shù),得到的新指針仍需指向同一數(shù)組的其他元素,或者指向同一數(shù)組的尾元素的下一位置(如果計算所得的指針超出了上述范圍就將產(chǎn)生錯誤,而且這種錯誤編譯器一般發(fā)現(xiàn)不了。):

    // ok: arr is converted to a pointer to its first element; p points one past the end of arr int *p = arr + sz; // use caution -- do not dereference!//指向同一數(shù)組的尾元素的下一位置 int *p2 = arr + 10; // error: arr has only 5 elements; p2 has undefined value

    當(dāng)給arr加上sz時,編譯器自動地將arr轉(zhuǎn)換成指向數(shù)組 arr中首元素的指針。執(zhí)行加法后,指針從首元素開始向前移動了sz(這里是5)個位置,指向新位置的元素。也就是說,它指向了數(shù)組arr尾元素的下一位置。

    兩個指針相減

    和迭代器一樣,兩個指針相減的結(jié)果是它們之間的距離。參與運(yùn)算的兩個指針必須指向同一個數(shù)組當(dāng)中的元素:

    auto n = end(arr) - begin(arr); // n is 5, the number of elements in arr

    兩個指針相減的結(jié)果的類型是一種名為ptrdiff_t 的標(biāo)準(zhǔn)庫類型,和 size_t一樣,ptrdiff_t 也是一種定義在 cstddef頭文件中的機(jī)器相關(guān)的類型。因?yàn)椴钪悼赡転樨?fù)值,所以ptrdiff_t是一種帶符號類型。

    只要兩個指針指向同一個數(shù)組的元素,或者指向該數(shù)組的尾元素的下一位置,就能利用關(guān)系運(yùn)算符對其進(jìn)行比較。例如,可以按照如下的方式遍歷數(shù)組中的元素:

    int *b = arr, *e = arr + sz; while (b < e) {// use *b++b; }

    如果兩個指針分別指向不相關(guān)的對象,則不能比較它們:

    int i = 0, sz = 42; int *p = &i, *e = &sz; // undefined: p and e are unrelated; comparison is meaningless! while (p < e)

    盡管作用可能不是特別明顯,但必須說明的是,上述指針運(yùn)算同樣適用于空指針和所指對象并非數(shù)組的指針。在后一種情況下,兩個指針必須指向同一個對象或該對象的下一位置。如果p 是空指針,允許給 p加上或減去一個值為o的整型常量表達(dá)式。兩個空指針也允許彼此相減,結(jié)果當(dāng)然是0。

    解引用和指針運(yùn)算的交互

    指針加上一個整數(shù)所得的結(jié)果還是一個指針。假設(shè)結(jié)果指針指向了一個元素,則允許解引用該結(jié)果指針:

    int ia[] = {0,2,4,6,8}; // array with 5 elements of type int int last = *(ia + 4); // ok: initializes last to 8, the value of ia[4]

    表達(dá)式* (ia+4)計算ia前進(jìn)4個元素后的新地址,解引用該結(jié)果指針的效果等價于表達(dá)式ia[ 4 ]。

    回憶一下先前介紹過如果表達(dá)式含有解引用運(yùn)算符點(diǎn)運(yùn)算符,最好在必要的地方加上圓括號。類似的,此例中指針加法的圓括號也不可缺少。如果寫成下面的形式:

    last = *ia + 4; // ok: last = 4, equivalent to ia[0] + 4

    含義就與之前完全不同了,此時先解引用ia,然后給解引用的結(jié)果再加上4。

    下標(biāo)和指針

    如前所述,在很多情況下使用數(shù)組的名字其實(shí)用的是一個指向數(shù)組首元素的指針。一個典型的例子是當(dāng)對數(shù)組使用下標(biāo)運(yùn)算符時,編譯器會自動執(zhí)行上述轉(zhuǎn)換操作。給定

    int ia[] = {0,2,4,6,8}; // array with 5 elements of type int

    此時,ia[0]是一個使用了數(shù)組名字的表達(dá)式,對數(shù)組執(zhí)行下標(biāo)運(yùn)算其實(shí)是對指向數(shù)組元素的指針執(zhí)行下標(biāo)運(yùn)算:

    int i = ia[2]; // ia is converted to a pointer to the first element in ia // ia[2] fetches the element to which (ia + 2) points int *p = ia; // p points to the first element in ia i = *(p + 2); // equivalent to i = ia[2]

    只要指針指向的是數(shù)組中的元素(或者數(shù)組中尾元素的下一位置),都可以執(zhí)行下標(biāo)運(yùn)算:

    int *p = &ia[2]; // p points to the element indexed by 2 int j = p[1]; // p[1] is equivalent to *(p + 1), // p[1] is the same element as ia[3] int k = p[-2]; // p[-2] is the same element as ia[0]

    雖然標(biāo)準(zhǔn)庫類型string和vector也能執(zhí)行下標(biāo)運(yùn)算,但是數(shù)組與它們相比還是有所不同。

    • 標(biāo)準(zhǔn)庫類型限定使用的下標(biāo)必須是無符號類型,而內(nèi)置的下標(biāo)運(yùn)算無此要求,上面的最后一個例子很好地說明了這一點(diǎn)。

    • 內(nèi)置的下標(biāo)運(yùn)算符可以處理負(fù)值,當(dāng)然,結(jié)果地址必須指向原來的指針?biāo)竿粩?shù)組中的元素(或是同一數(shù)組尾元素的下一位置)。

    內(nèi)置的下標(biāo)運(yùn)算符所用的索引值不是無符號類型,這一點(diǎn)與vector和string不一樣。

    C風(fēng)格字符串

    盡管C++支持C風(fēng)格字符串,但在C++程序中最好還是不要使用它們。這是因?yàn)镃風(fēng)格字符串不僅使用起來不太方便,而且極易引發(fā)程序漏洞,是諸多安全問題的根本原因。

    字符串字面值是一種通用結(jié)構(gòu)的實(shí)例,這種結(jié)構(gòu)即是C++由C繼承而來的C風(fēng)格字符串(C-style character string)。C風(fēng)格字符串不是一種類型,而是為了表達(dá)和使用字符串而形成的一種約定俗成的寫法。按此習(xí)慣書寫的字符串存放在字符數(shù)組中并以空字符結(jié)束(null terminated)。以空字符結(jié)束的意思是在字符串最后一個字符后面跟著一個空字符(’\0‘)。一般利用指針來操作這些字符串。

    C標(biāo)準(zhǔn)庫String函數(shù)

    下表列舉了C語言標(biāo)準(zhǔn)庫提供的一組函數(shù),這些函數(shù)可用于操作C風(fēng)格字符串,它們定義在cstring頭文件中,cstring是C語言頭文件string.h的C++版本。

    ..
    strlen§返回p的長度,空字符不計算在內(nèi)
    strcmp(pi, p2)比較p1和p2的相等性。如果p1==p2,返回0;如果p1>p2,返回一個正值;如果pl<p2,返回一個負(fù)值
    strcat(pl, p2)將p2附加到p1之后,返回p1
    strcpy(p1, p2)將p2拷貝給p1,返回p1

    所列的函數(shù)不負(fù)責(zé)驗(yàn)證其字符串參數(shù)。

    傳入此類函數(shù)的指針必須指向以空字符作為結(jié)束的數(shù)組:

    char ca[] = {'C', '+', '+'}; // not null terminated cout << strlen(ca) << endl; // disaster: ca isn't null terminated

    此例中,ca雖然也是一個字符數(shù)組但它不是以空字符作為結(jié)束的,因此上述程序?qū)a(chǎn)生未定義的結(jié)果。strlen函數(shù)將有可能沿著ca在內(nèi)存中的位置不斷向前尋找,直到遇到空字符才停下來。

    比較字符串

    比較兩個C風(fēng)格字符串的方法和之前學(xué)習(xí)過的比較標(biāo)準(zhǔn)庫string對象的方法大相徑庭。比較標(biāo)準(zhǔn)庫string對象的時候,用的是普通的關(guān)系運(yùn)算符和相等性運(yùn)算符:

    string s1 = "A string example"; string s2 = "A different string"; if (s1 < s2) // false: s2 is less than s1

    如果把這些運(yùn)算符用在兩個C風(fēng)格字符串上,實(shí)際比較的將是指針而非字符串本身:

    const char ca1[] = "A string example"; const char ca2[] = "A different string"; if (ca1 < ca2) // undefined: compares two unrelated addresses

    謹(jǐn)記之前介紹過的,當(dāng)使用數(shù)組的時候其實(shí)真正用的是指向數(shù)組首元素的指針。因此,上面的if條件實(shí)際上比較的是兩個const char*的值。這兩個指針指向的并非同一對象,所以將得到未定義的結(jié)果。

    要想比較兩個C風(fēng)格字符串需要調(diào)用strcmp函數(shù),此時比較的就不再是指針了。如果兩個字符串相等,strcmp返回0;如果前面的字符串較大,返回正值;如果后面的字符串較大,返回負(fù)值:

    if (strcmp(ca1, ca2) < 0) // same effect as string comparison s1 < s2

    目標(biāo)字符串的大小由調(diào)用者指定

    連接或拷貝C風(fēng)格字符串也與標(biāo)準(zhǔn)庫string對象的同類操作差別很大。例如,要想把剛剛定義的那兩個string對象s1和 s2連接起來,可以直接寫成下面的形式:

    // initialize largeStr as a concatenation of s1, a space, and s2 string largeStr = s1 + " " + s2;

    同樣的操作如果放到cal和 ca2這兩個數(shù)組身上就會產(chǎn)生錯誤了。表達(dá)式cal + ca2試圖將兩個指針相加,顯然這樣的操作沒什么意義,也肯定是非法的。

    正確的方法是使用strcat函數(shù)和strcpy函數(shù)。不過要想使用這兩個函數(shù),還必須提供一個用于存放結(jié)果字符串的數(shù)組,該數(shù)組必須足夠大以便容納下結(jié)果字符串及末尾的空字符。下面的代碼雖然很常見,但是充滿了安全風(fēng)險,極易引發(fā)嚴(yán)重錯誤:

    // disastrous if we miscalculated the size of largeStr strcpy(largeStr, ca1); // copies ca1 into largeStr strcat(largeStr, " "); // adds a space at the end of largeStr strcat(largeStr, ca2); // concatenates ca2 onto largeStr

    一個潛在的問題是,我們在估算 largestr所需的空間時不容易估準(zhǔn),而且 largestr所存的內(nèi)容一旦改變,就必須重新檢查其空間是否足夠。不幸的是,這樣的代碼到處都是,程序員根本沒法照顧周全。這類代碼充滿了風(fēng)險而且經(jīng)常導(dǎo)致嚴(yán)重的安全泄漏。

    對大多數(shù)應(yīng)用來說,使用標(biāo)準(zhǔn)庫string要比使用C風(fēng)格字符串更安全、更高效。

    (Note:放心去用標(biāo)準(zhǔn)庫string)

    與舊代碼的接口

    很多C++程序在標(biāo)準(zhǔn)庫出現(xiàn)之前就已經(jīng)寫成了,它們肯定沒用到string和 vector類型。而且,有一些C+程序?qū)嶋H上是與C語言或其他語言的接口程序,當(dāng)然也無法使用C++標(biāo)準(zhǔn)庫。因此,現(xiàn)代的C++程序不得不與那些充滿了數(shù)組和/或C風(fēng)格字符串的代碼銜接,為了使這一工作簡單易行,C++專門提供了一組功能。

    混用string對象和C風(fēng)格字符串

    前文介紹過允許使用字符串字面值來初始化string對象:

    string s("Hello World"); // s holds Hello World

    更一般的情況是,任何出現(xiàn)字符串字面值的地方都可以用以空字符結(jié)束的字符數(shù)組來替代:

    • 允許使用以空字符結(jié)束的字符數(shù)組來初始化string對象或?yàn)?string對象賦值。

    • 在string 對象的加法運(yùn)算中允許使用以空字符結(jié)束的字符數(shù)組作為其中一個運(yùn)算對象(不能兩個運(yùn)算對象都是);

    • 在string對象的復(fù)合賦值運(yùn)算中允許使用以空字符結(jié)束的字符數(shù)組作為右側(cè)的運(yùn)算對象。

    上述性質(zhì)反過來就不成立了:如果程序的某處需要一個C風(fēng)格字符串,無法直接用string對象來代替它。例如,不能用string對象直接初始化指向字符的指針。

    為了完成該功能,string專門提供了一個名為c_str的成員函數(shù):

    char *str = s; // error: can't initialize a char* from a string const char *str = s.c_str(); // ok

    顧名思義,c_str函數(shù)的返回值是一個C風(fēng)格的字符串。也就是說,函數(shù)的返回結(jié)果是一個指針,該指針指向一個以空字符結(jié)束的字符數(shù)組,而這個數(shù)組所存的數(shù)據(jù)恰好與那個string對象的一樣。結(jié)果指針的類型是const char*,從而確保我們不會改變字符數(shù)組的內(nèi)容。

    我們無法保證c_str函數(shù)返回的數(shù)組一直有效,事實(shí)上,如果后續(xù)的操作改變了s的值就可能讓之前返回的數(shù)組失去效用。

    如果執(zhí)行完c_str()函數(shù)后程序想一直都能使用其返回的數(shù)組,最好將該數(shù)組重新拷貝一份。

    使用數(shù)組初始化vector對象

    前文介紹過不允許使用一個數(shù)組為另一個內(nèi)置類型的數(shù)組賦初值,也不允許使用vector對象初始化數(shù)組。相反的,允許使用數(shù)組來初始化vector對象。要實(shí)現(xiàn)這一目的,只需指明要拷貝區(qū)域的首元素地址和尾后地址就可以了:

    int int_arr[] = {0, 1, 2, 3, 4, 5}; // ivec has six elements; each is a copy of the corresponding element in int_arr vector<int> ivec(begin(int_arr), end(int_arr));

    在上述代碼中,用于創(chuàng)建ivec的兩個指針實(shí)際上指明了用來初始化的值在數(shù)組int_arr中的位置,其中第二個指針應(yīng)指向待拷貝區(qū)域尾元素的下一位置。此例中,使用標(biāo)準(zhǔn)庫函數(shù)begin和 end來分別計算int_arr 的首指針和尾后指針。在最終的結(jié)果中,ivec將包含6個元素,它們的次序和值都與數(shù)組int_arr完全一樣。

    用于初始化 vector對象的值也可能僅是數(shù)組的一部分:

    // copies three elements: int_arr[1], int_arr[2], int_arr[3] vector<int> subVec(int_arr + 1, int_arr + 4);

    這條初始化語句用3個元素創(chuàng)建了對象subvec,3個元素的值分別來自int_arr[1]、int_arr[2]和 int_arr[3]。

    建議:盡量使用標(biāo)準(zhǔn)庫類型而非數(shù)組

    使用指針和數(shù)組很容易出錯。一部分原因是概念上的問題:指針常用于底層操作,因此容易引發(fā)一些與煩瑣細(xì)節(jié)有關(guān)的錯誤。其他問題則源于語法錯誤,特別是聲明指針時的語法錯誤。

    現(xiàn)代的C++程序應(yīng)當(dāng)盡量使用vector和迭代器,避免使用內(nèi)置數(shù)組和指針;應(yīng)該盡量使用string,避免使用C風(fēng)格的基于數(shù)組的字符串。

    多維數(shù)組

    嚴(yán)格來說,C++語言中沒有多維數(shù)組,通常所說的多維數(shù)組其實(shí)是數(shù)組的數(shù)組。謹(jǐn)記這一點(diǎn),對今后理解和使用多維數(shù)組大有益處。

    當(dāng)一個數(shù)組的元素仍然是數(shù)組時,通常使用兩個維度來定義它:一個維度表示數(shù)組本身大小,另外一個維度表示其元素(也是數(shù)組)大小:

    int ia[3][4]; // array of size 3; each element is an array of ints of size 4 // array of size 10; each element is a 20-element array whose elements are arrays of 30 ints int arr[10][20][30] = {0}; // initialize all elements to 0

    如前文所介紹的,按照由內(nèi)而外的順序閱讀此類定義有助于更好地理解其真實(shí)含義。

    在第一條語句中,我們定義的名字是ia,顯然ia是一個含有3個元素的數(shù)組。接著觀察右邊發(fā)現(xiàn),ia的元素也有自己的維度,所以ia的元素本身又都是含有4個元素的數(shù)組。再觀察左邊知道,真正存儲的元素是整數(shù)。因此最后可以明確第一條語句的含義:它定義了一個大小為3的數(shù)組,該數(shù)組的每個元素都是含有4個整數(shù)的數(shù)組

    使用同樣的方式理解arr的定義。首先arr是一個大小為10的數(shù)組,它的每個元素都是大小為20的數(shù)組,這些數(shù)組的元素又都是含有30個整數(shù)的數(shù)組。

    實(shí)際上,定義數(shù)組時對下標(biāo)運(yùn)算符的數(shù)量并沒有限制,因此只要愿意就可以定義這樣一個數(shù)組:它的元素還是數(shù)組,下一級數(shù)組的元素還是數(shù)組,再下一級數(shù)組的元素還是數(shù)組,以此類推。

    對于二維數(shù)組來說,常把第一個維度稱作行,第二個維度稱作列。

    多維數(shù)組的初始化

    允許使用花括號括起來的一組值初始化多維數(shù)組,這點(diǎn)和普通的數(shù)組一樣。下面的初始化形式中,多維數(shù)組的每一行分別用花括號括了起來:

    int ia[3][4] = { // three elements; each element is an array of size 4{0, 1, 2, 3}, // initializers for the row indexed by 0{4, 5, 6, 7}, // initializers for the row indexed by 1{8, 9, 10, 11} // initializers for the row indexed by 2 };

    其中內(nèi)層嵌套著的花括號并非必需的,例如下面的初始化語句,形式上更為簡潔,完成的功能和上面這段代碼完全一樣:

    // equivalent initialization without the optional nested braces for each row int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

    類似于一維數(shù)組,在初始化多維數(shù)組時也并非所有元素的值都必須包含在初始化列表之內(nèi)。如果僅僅想初始化每一行的第一個元素,通過如下的語句即可:

    // explicitly initialize only element 0 in each row int ia[3][4] = {{ 0 }, { 4 }, { 8 }};

    其他未列出的元素執(zhí)行默認(rèn)值初始化,這個過程和一維數(shù)組一樣。在這種情況下如果再省略掉內(nèi)層的花括號,結(jié)果就大不一樣了。下面的代碼

    // explicitly initialize row 0; the remaining elements are value initialized int ix[3][4] = {0, 3, 6, 9};

    含義發(fā)生了變化,它初始化的是第一行的4個元素,其他元素被初始化為0。

    多維數(shù)組的下標(biāo)引用

    可以使用下標(biāo)運(yùn)算符來訪問多維數(shù)組的元素,此時數(shù)組的每個維度對應(yīng)一個下標(biāo)運(yùn)算符。

    如果表達(dá)式含有的下標(biāo)運(yùn)算符數(shù)量和數(shù)組的維度一樣多,該表達(dá)式的結(jié)果將是給定類型的元素;反之,如果表達(dá)式含有的下標(biāo)運(yùn)算符數(shù)量比數(shù)組的維度小,則表達(dá)式的結(jié)果將是給定索引處的一個內(nèi)層數(shù)組:

    // assigns the first element of arr to the last element in the last row of ia ia[2][3] = arr[0][0][0];//int arr[10][20][30] = {0}; int (&row)[4] = ia[1]; // binds row to the second four-element array in ia

    第一個例子中,對于用到的兩個數(shù)組來說,表達(dá)式提供的下標(biāo)運(yùn)算符數(shù)量都和它們各自的維度相同。在等號左側(cè),ia[2]得到數(shù)組ia的最后一行,此時返回的是表示ia最后一行的那個一維數(shù)組而非任何實(shí)際元素;對這個一維數(shù)組再取下標(biāo),得到編號為[3]的元素,也就是這一行的最后一個元素。

    類似的,等號右側(cè)的運(yùn)算對象包含3個維度。首先通過索引0得到最外層的數(shù)組,它是一個大小為20的(多維)數(shù)組;接著獲取這20個元素數(shù)組的第一個元素,得到一個大小為30的一維數(shù)組;最后再取出其中的第一個元素。

    第二個例子中,把 row定義成一個含有4個整數(shù)的數(shù)組的引用,然后將其綁定到ia的第2行。

    再舉一個例子,程序中經(jīng)常會用到兩層嵌套的for循環(huán)來處理多維數(shù)組的元素:

    constexpr size_t rowCnt = 3, colCnt = 4; int ia[rowCnt][colCnt]; // 12 uninitialized elements // for each row for (size_t i = 0; i != rowCnt; ++i) {// for each column within the rowfor (size_t j = 0; j != colCnt; ++j) {// assign the element's positional index as its valueia[i][j] = i * colCnt + j;} }

    外層的for循環(huán)遍歷ia的所有元素,注意這里的元素是一維數(shù)組;內(nèi)層的for循環(huán)則遍歷那些一維數(shù)組的整數(shù)元素。此例中,我們將元素的值設(shè)為該元素在整個數(shù)組中的序號。

    使用范圍for語句處理多維數(shù)組

    由于在C++11新標(biāo)準(zhǔn)中新增了范圍for語句,所以前一個程序可以簡化為如下形式:

    size_t cnt = 0; for (auto &row : ia) // for every element in the outer arrayfor (auto &col : row) { // for every element in the inner arraycol = cnt; // give this element the next value++cnt; // increment cnt}

    這個循環(huán)賦給ia元素的值和之前那個循環(huán)是完全相同的,區(qū)別之處是通過使用范圍for語句把管理數(shù)組索引的任務(wù)交給了系統(tǒng)來完成。因?yàn)橐淖冊氐闹?#xff0c;所以得把控制變量row和 col聲明成引用類型。

    • 第一個for循環(huán)遍歷ia的所有元素,這些元素是大小為4的數(shù)組,因此row的類型就應(yīng)該是含有4個整數(shù)的數(shù)組的引用。

    • 第二個for循環(huán)遍歷那些4元素數(shù)組中的某一個,因此 col的類型是整數(shù)的引用。每次迭代把cnt的值賦給ia的當(dāng)前元素,然后將cnt加1。

    在上面的例子中,因?yàn)橐淖償?shù)組元素的值,所以我們選用引用類型作為循環(huán)控制變量,但其實(shí)還有一個深層次的原因促使我們這么做。

    舉一個例子,考慮如下的循環(huán):

    for (const auto &row : ia) // for every element in the outer arrayfor (auto col : row) // for every element in the inner arraycout << col << endl;

    這個循環(huán)中并沒有任何寫操作,可是我們還是將外層循環(huán)的控制變量聲明成了引用類型,這是為了避免數(shù)組被自動轉(zhuǎn)成指針

    假設(shè)不用引用類型,則循環(huán)如下述形式:

    for (auto row : ia)for (auto col : row)

    程序?qū)o法通過編譯。這是因?yàn)?#xff0c;像之前一樣第一個循環(huán)遍歷ia的所有元素,注意這些元素實(shí)際上是大小為4的數(shù)組。因?yàn)閞ow不是引用類型,所以編譯器初始化row時會自動將這些數(shù)組形式的元素(和其他類型的數(shù)組一樣)轉(zhuǎn)換成指向該數(shù)組內(nèi)首元素的指針。這樣得到的row 的類型就是 int*,顯然內(nèi)層的循環(huán)就不合法了,編譯器將試圖在一個int*內(nèi)遍歷,這顯然和程序的初衷相去甚遠(yuǎn)。

    要使用范圍 for語句處理多維數(shù)組,除了最內(nèi)層的循環(huán)外,其他所有循環(huán)的控制變量都應(yīng)該是引用類型。

    指針和多維數(shù)組

    當(dāng)程序使用多維數(shù)組的名字時,也會自動將其轉(zhuǎn)換成指向數(shù)組首元素的指針。

    定義指向多維數(shù)組的指針時,千萬別忘了這個多維數(shù)組實(shí)際上是數(shù)組的數(shù)組。

    因?yàn)槎嗑S數(shù)組實(shí)際上是數(shù)組的數(shù)組,所以由多維數(shù)組名轉(zhuǎn)換得來的指針實(shí)際上是指向第一個內(nèi)層數(shù)組的指針:

    int ia[3][4]; // array of size 3; each element is an array of ints of size 4 int (*p)[4] = ia; // p points to an array of four ints//ia的第一行 p = &ia[2]; // p now points to the last element in ia//ia的第三行

    我們首先明確(*p)意味著p是一個指針。接著觀察右邊發(fā)現(xiàn),指針p所指的是一個維度為4的數(shù)組;再觀察左邊知道,數(shù)組中的元素是整數(shù)。因此,p就是指向含有4個整數(shù)的數(shù)組的指針。

    在上述聲明中,圓括號必不可少:

    int *ip[4]; // array of pointers to int int (*ip)[4]; // pointer to an array of four ints

    隨著C++11新標(biāo)準(zhǔn)的提出,通過使用auto或者decltype就能盡可能地避免在數(shù)組前面加上一個指針類型了:

    // print the value of each element in ia, with each inner array on its own line // p points to an array of four ints for (auto p = ia; p != ia + 3; ++p) { // q points to the first element of an array of four ints; that is, q points to an intfor (auto q = *p; q != *p + 4; ++q)cout << *q << ' ';cout << endl; }

    使用標(biāo)準(zhǔn)庫函數(shù)begin和end也能實(shí)現(xiàn)同樣的功能,而且看起來更簡潔一些:

    #include <iterator>// p points to the first array in ia for (auto p = begin(ia); p != end(ia); ++p) {// q points to the first element in an inner arrayfor (auto q = begin(*p); q != end(*p); ++q)cout << *q << ' '; // prints the int value to which q pointscout << endl; }

    類別別名簡化多維數(shù)組的指針

    讀、寫和理解一個指向多維數(shù)組的指針是一個讓人不勝其煩的工作,使用類型別名能讓這項工作變得簡單一點(diǎn)兒,例如:

    using int_array = int[4]; // new style type alias declaration; typedef int int_array[4]; // equivalent typedef declaration; // print the value of each element in ia, with each inner array on its own line for (int_array *p = ia; p != ia + 3; ++p) {for (int *q = *p; q != *p + 4; ++q)cout << *q << ' ';cout << endl; }

    程序?qū)㈩愋汀?個整數(shù)組成的數(shù)組”命名為 int_array,用類型名int_array 定義外層循環(huán)的控制變量讓程序顯得簡潔明了。

    一些術(shù)語

    緩沖區(qū)溢出(buffer overflow)一種嚴(yán)重的程序故障,主要的原因是試圖通過一個越界的索引訪問容器內(nèi)容,容器類型包括string、vector和數(shù)組等。

    類模板(class template)用于創(chuàng)建具體類類型的模板。要想使用類模板,必須提供關(guān)于類型的輔助信息。例如,要定義一個vector對象需要指定元素的類型:vector<int>包含int類型的元素。

    拷貝初始化 (copy initialization) 使用賦值號(=)的初始化形式。新創(chuàng)建的對象是初始值的一個副本。

    直接初始化(direct initialization)不使用賦值號(=)的初始化形式。

    實(shí)例化(instantiation)編譯器生成一個指定的模板類或函數(shù)的過程。

    值初始化(value initialization)是一種初始化過程。內(nèi)置類型初始化為0,類類型由類的默認(rèn)構(gòu)造函數(shù)初始化。只有當(dāng)類包含默認(rèn)構(gòu)造函數(shù)時,該類的對象才會被值初始化。對于容器的初始化來說,如果只說明了容器的大小而沒有指定初始值的話,就會執(zhí)行值初始化。此時編譯器會生成一個值,而容器的元素被初始化為該值。

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結(jié)

    以上是生活随笔為你收集整理的《C++ Primer 5th》笔记(3 / 19):字符串、向量、迭代器和数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

    精品国产av色一区二区深夜久久 | 国产免费无码一区二区视频 | 极品嫩模高潮叫床 | 99久久精品日本一区二区免费 | 永久黄网站色视频免费直播 | 亚洲午夜福利在线观看 | 牲欲强的熟妇农村老妇女视频 | 亚洲乱码国产乱码精品精 | 日日噜噜噜噜夜夜爽亚洲精品 | 国产精品久久福利网站 | 国产香蕉尹人视频在线 | 精品欧美一区二区三区久久久 | 久久午夜无码鲁丝片午夜精品 | 亚洲国产精品美女久久久久 | 国产亚洲精品久久久久久大师 | 日本丰满护士爆乳xxxx | 人妻与老人中文字幕 | 少妇高潮喷潮久久久影院 | 国产日产欧产精品精品app | 亚洲の无码国产の无码步美 | 国产精品福利视频导航 | 好爽又高潮了毛片免费下载 | 好男人www社区 | av无码不卡在线观看免费 | 国产sm调教视频在线观看 | 欧美老妇交乱视频在线观看 | 男人和女人高潮免费网站 | 国产69精品久久久久app下载 | 国产av无码专区亚洲awww | 国产精品久久久久久久9999 | 98国产精品综合一区二区三区 | 午夜熟女插插xx免费视频 | 黑人大群体交免费视频 | 日韩亚洲欧美中文高清在线 | 玩弄中年熟妇正在播放 | 国产精品无套呻吟在线 | 国产精品第一国产精品 | 老子影院午夜伦不卡 | 色情久久久av熟女人妻网站 | 麻花豆传媒剧国产免费mv在线 | 丰满岳乱妇在线观看中字无码 | 国产又爽又猛又粗的视频a片 | 蜜桃视频插满18在线观看 | av在线亚洲欧洲日产一区二区 | 精品久久久久久人妻无码中文字幕 | 亚洲国产av精品一区二区蜜芽 | 色欲av亚洲一区无码少妇 | 成人亚洲精品久久久久 | 亚洲一区二区三区 | 精品aⅴ一区二区三区 | 熟女少妇在线视频播放 | 领导边摸边吃奶边做爽在线观看 | 无码av免费一区二区三区试看 | 亚洲一区二区三区国产精华液 | 婷婷综合久久中文字幕蜜桃三电影 | √8天堂资源地址中文在线 | 国产热a欧美热a在线视频 | 7777奇米四色成人眼影 | 极品嫩模高潮叫床 | 色综合视频一区二区三区 | 国产色在线 | 国产 | 精品国产成人一区二区三区 | 国产极品美女高潮无套在线观看 | 国产亚洲人成在线播放 | 偷窥村妇洗澡毛毛多 | 99国产欧美久久久精品 | 99久久精品日本一区二区免费 | 国产精品国产三级国产专播 | 精品夜夜澡人妻无码av蜜桃 | 最近中文2019字幕第二页 | 老头边吃奶边弄进去呻吟 | 熟妇人妻中文av无码 | 国产内射爽爽大片视频社区在线 | 欧美人与动性行为视频 | 51国偷自产一区二区三区 | 欧美日韩综合一区二区三区 | 亚洲国产欧美国产综合一区 | 日日噜噜噜噜夜夜爽亚洲精品 | 国内少妇偷人精品视频免费 | 中文亚洲成a人片在线观看 | 欧美成人家庭影院 | 中文字幕无码免费久久99 | 奇米影视7777久久精品人人爽 | 中文亚洲成a人片在线观看 | √天堂中文官网8在线 | 国产成人精品三级麻豆 | 天天拍夜夜添久久精品 | 亚洲成色在线综合网站 | 少女韩国电视剧在线观看完整 | 国产在线一区二区三区四区五区 | 亚洲精品午夜国产va久久成人 | 亚洲啪av永久无码精品放毛片 | а天堂中文在线官网 | 欧美日本免费一区二区三区 | 中文字幕色婷婷在线视频 | 55夜色66夜色国产精品视频 | 亚洲精品综合五月久久小说 | 蜜桃av抽搐高潮一区二区 | 7777奇米四色成人眼影 | 色欲av亚洲一区无码少妇 | 久久久久久九九精品久 | 国产一区二区三区影院 | 国产无av码在线观看 | 精品久久8x国产免费观看 | 国产成人午夜福利在线播放 | 性欧美熟妇videofreesex | 97se亚洲精品一区 | 天海翼激烈高潮到腰振不止 | 粗大的内捧猛烈进出视频 | 午夜不卡av免费 一本久久a久久精品vr综合 | 天下第一社区视频www日本 | 亚洲男人av天堂午夜在 | 中文字幕+乱码+中文字幕一区 | 在线播放免费人成毛片乱码 | 国产亲子乱弄免费视频 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 亚洲色欲色欲天天天www | a片免费视频在线观看 | 国産精品久久久久久久 | 久久国语露脸国产精品电影 | 亚洲s码欧洲m码国产av | 噜噜噜亚洲色成人网站 | 精品亚洲韩国一区二区三区 | 久久zyz资源站无码中文动漫 | 六十路熟妇乱子伦 | 久久久www成人免费毛片 | 大乳丰满人妻中文字幕日本 | 国内少妇偷人精品视频免费 | 无码人妻久久一区二区三区不卡 | 亚洲熟妇色xxxxx欧美老妇y | 国产人妻大战黑人第1集 | 在线a亚洲视频播放在线观看 | 又紧又大又爽精品一区二区 | 97精品人妻一区二区三区香蕉 | 鲁大师影院在线观看 | 欧美老熟妇乱xxxxx | 精品久久8x国产免费观看 | 国产极品美女高潮无套在线观看 | 国产亚洲精品久久久久久大师 | 国产欧美亚洲精品a | 亚洲精品成a人在线观看 | 少妇高潮一区二区三区99 | 欧美xxxx黑人又粗又长 | 秋霞特色aa大片 | 精品国产乱码久久久久乱码 | 激情内射亚州一区二区三区爱妻 | 国产精品久久国产精品99 | 国产精品久久久久久久9999 | 内射巨臀欧美在线视频 | 乱人伦人妻中文字幕无码 | 国产亚洲精品久久久久久久久动漫 | 国产性生交xxxxx无码 | 精品久久久无码中文字幕 | 婷婷五月综合激情中文字幕 | 亚洲啪av永久无码精品放毛片 | 国产成人一区二区三区在线观看 | 性欧美牲交xxxxx视频 | 久久综合色之久久综合 | 国产极品美女高潮无套在线观看 | 爆乳一区二区三区无码 | 国内精品久久毛片一区二区 | 国产在线aaa片一区二区99 | 亚洲色大成网站www国产 | 国产亚洲美女精品久久久2020 | 日韩少妇内射免费播放 | 久久99精品国产麻豆 | 亚洲国产精品久久久久久 | 国产成人无码av一区二区 | 理论片87福利理论电影 | 国内揄拍国内精品少妇国语 | 亚洲色欲色欲欲www在线 | 中文无码伦av中文字幕 | 精品国产一区二区三区四区在线看 | 精品亚洲韩国一区二区三区 | 精品欧美一区二区三区久久久 | 午夜肉伦伦影院 | 亚洲精品一区二区三区大桥未久 | 强伦人妻一区二区三区视频18 | 乱中年女人伦av三区 | 巨爆乳无码视频在线观看 | 色欲久久久天天天综合网精品 | 两性色午夜视频免费播放 | 男人和女人高潮免费网站 | 九九热爱视频精品 | 国产精品-区区久久久狼 | 噜噜噜亚洲色成人网站 | 国产成人无码av片在线观看不卡 | 老司机亚洲精品影院无码 | 婷婷五月综合激情中文字幕 | 国精产品一品二品国精品69xx | 又紧又大又爽精品一区二区 | 少妇性俱乐部纵欲狂欢电影 | 亚洲精品一区二区三区在线 | 亚洲色欲色欲欲www在线 | 亚洲一区二区三区无码久久 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产精品.xx视频.xxtv | 欧美老熟妇乱xxxxx | 国产午夜无码视频在线观看 | 午夜精品一区二区三区在线观看 | 女人被爽到呻吟gif动态图视看 | 中文字幕无码av波多野吉衣 | 午夜福利电影 | 女人高潮内射99精品 | 免费播放一区二区三区 | 精品夜夜澡人妻无码av蜜桃 | 日韩精品无码一本二本三本色 | 大肉大捧一进一出好爽视频 | 无套内射视频囯产 | 精品一区二区三区无码免费视频 | 国产成人人人97超碰超爽8 | 精品久久久中文字幕人妻 | 亚洲成在人网站无码天堂 | 国产免费观看黄av片 | 18禁黄网站男男禁片免费观看 | 成在人线av无码免观看麻豆 | 久久国产精品二国产精品 | 亚洲热妇无码av在线播放 | 国产特级毛片aaaaaaa高清 | 午夜不卡av免费 一本久久a久久精品vr综合 | 丝袜 中出 制服 人妻 美腿 | 国产真实伦对白全集 | 无码国产乱人伦偷精品视频 | 国产黑色丝袜在线播放 | www国产亚洲精品久久网站 | 好爽又高潮了毛片免费下载 | 午夜福利电影 | 成人无码精品一区二区三区 | 国产美女精品一区二区三区 | 亚洲成av人在线观看网址 | 又色又爽又黄的美女裸体网站 | 欧美兽交xxxx×视频 | 人人超人人超碰超国产 | 亚洲日韩av一区二区三区中文 | 98国产精品综合一区二区三区 | 丝袜美腿亚洲一区二区 | 无码国产色欲xxxxx视频 | 日韩无套无码精品 | 日本爽爽爽爽爽爽在线观看免 | 日韩精品成人一区二区三区 | 欧美35页视频在线观看 | 国产精品久久久久久久9999 | 午夜精品久久久久久久久 | 3d动漫精品啪啪一区二区中 | 强奷人妻日本中文字幕 | 曰本女人与公拘交酡免费视频 | 成人精品天堂一区二区三区 | 亚洲精品综合一区二区三区在线 | 野外少妇愉情中文字幕 | 人人妻人人澡人人爽欧美一区九九 | 丁香啪啪综合成人亚洲 | 午夜福利电影 | 精品无码一区二区三区爱欲 | 国产偷抇久久精品a片69 | 日本丰满护士爆乳xxxx | 给我免费的视频在线观看 | 久久久久久九九精品久 | 免费观看黄网站 | 亚洲色成人中文字幕网站 | 噜噜噜亚洲色成人网站 | 亚洲毛片av日韩av无码 | 久久无码中文字幕免费影院蜜桃 | 国产va免费精品观看 | 国内精品一区二区三区不卡 | 欧美变态另类xxxx | 美女扒开屁股让男人桶 | 在线欧美精品一区二区三区 | 亚洲国产精品一区二区美利坚 | 日本乱偷人妻中文字幕 | 高中生自慰www网站 | 天堂亚洲2017在线观看 | 蜜桃av抽搐高潮一区二区 | 久久精品一区二区三区四区 | 国产精品二区一区二区aⅴ污介绍 | 真人与拘做受免费视频一 | 又粗又大又硬又长又爽 | 未满成年国产在线观看 | 中文字幕av无码一区二区三区电影 | 亚洲无人区午夜福利码高清完整版 | 久久精品国产大片免费观看 | 久久久久国色av免费观看性色 | 婷婷色婷婷开心五月四房播播 | 亚洲精品成人av在线 | 对白脏话肉麻粗话av | 曰韩无码二三区中文字幕 | 无码中文字幕色专区 | 国产精品怡红院永久免费 | 精品一区二区三区无码免费视频 | 国产肉丝袜在线观看 | 日韩精品无码免费一区二区三区 | 国产极品美女高潮无套在线观看 | 人妻少妇精品视频专区 | 色欲综合久久中文字幕网 | 丝袜人妻一区二区三区 | 97资源共享在线视频 | 久久精品无码一区二区三区 | 亚洲中文字幕无码中文字在线 | 中文字幕无码热在线视频 | 日韩 欧美 动漫 国产 制服 | 无码任你躁久久久久久久 | 又大又硬又爽免费视频 | 日日鲁鲁鲁夜夜爽爽狠狠 | 久久精品国产大片免费观看 | 亚洲国产精品毛片av不卡在线 | 国产三级精品三级男人的天堂 | 久久99精品久久久久久动态图 | 精品久久久久久人妻无码中文字幕 | 人妻无码αv中文字幕久久琪琪布 | 久久综合网欧美色妞网 | 成人一区二区免费视频 | 成人三级无码视频在线观看 | 精品国产一区av天美传媒 | 亚洲国产精品成人久久蜜臀 | 日韩av无码一区二区三区不卡 | 天天躁夜夜躁狠狠是什么心态 | 国产亚洲精品久久久久久国模美 | 色婷婷综合激情综在线播放 | 国产乱人偷精品人妻a片 | 日日夜夜撸啊撸 | 亚洲大尺度无码无码专区 | 97色伦图片97综合影院 | 亚洲色欲色欲欲www在线 | 国产精品自产拍在线观看 | 131美女爱做视频 | 亚洲熟女一区二区三区 | 婷婷综合久久中文字幕蜜桃三电影 | 国产av一区二区精品久久凹凸 | 黄网在线观看免费网站 | 亚洲精品国产品国语在线观看 | 99久久婷婷国产综合精品青草免费 | 久久国产精品偷任你爽任你 | 久久亚洲a片com人成 | 国产精品办公室沙发 | 国产办公室秘书无码精品99 | 久久久久久亚洲精品a片成人 | 国产 精品 自在自线 | 亚洲 高清 成人 动漫 | 日韩av无码一区二区三区不卡 | 久久综合给合久久狠狠狠97色 | 日本www一道久久久免费榴莲 | 麻豆果冻传媒2021精品传媒一区下载 | 在线观看欧美一区二区三区 | 日韩欧美中文字幕在线三区 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 久久久精品欧美一区二区免费 | 亚洲天堂2017无码中文 | 国产日产欧产精品精品app | 粉嫩少妇内射浓精videos | 精品亚洲成av人在线观看 | 最近的中文字幕在线看视频 | 国产精品自产拍在线观看 | 欧美亚洲国产一区二区三区 | 在线a亚洲视频播放在线观看 | 玩弄人妻少妇500系列视频 | 少妇邻居内射在线 | www国产亚洲精品久久久日本 | 国产精品福利视频导航 | 亚洲高清偷拍一区二区三区 | 亚洲一区二区三区四区 | 亚洲欧美综合区丁香五月小说 | 亚洲a无码综合a国产av中文 | 在线亚洲高清揄拍自拍一品区 | 人人妻人人澡人人爽欧美一区九九 | 激情国产av做激情国产爱 | 中文字幕色婷婷在线视频 | 老太婆性杂交欧美肥老太 | 午夜福利一区二区三区在线观看 | 99久久99久久免费精品蜜桃 | 精品aⅴ一区二区三区 | 国产成人无码av在线影院 | 中文字幕无码人妻少妇免费 | 国产精品久久久久9999小说 | 久久综合香蕉国产蜜臀av | 国产成人综合色在线观看网站 | 日韩欧美成人免费观看 | 日本www一道久久久免费榴莲 | 成人一区二区免费视频 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 亚无码乱人伦一区二区 | 国产性生大片免费观看性 | 骚片av蜜桃精品一区 | 女人被爽到呻吟gif动态图视看 | 中文字幕av日韩精品一区二区 | 人妻少妇精品视频专区 | 全球成人中文在线 | 在线观看国产午夜福利片 | 亚洲人成网站免费播放 | 日本精品人妻无码77777 天堂一区人妻无码 | 又湿又紧又大又爽a视频国产 | 天干天干啦夜天干天2017 | 亚洲精品一区二区三区婷婷月 | 亚洲国产成人av在线观看 | 麻豆国产97在线 | 欧洲 | 领导边摸边吃奶边做爽在线观看 | 日韩精品无码一本二本三本色 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 亚欧洲精品在线视频免费观看 | 又湿又紧又大又爽a视频国产 | v一区无码内射国产 | 国产精品手机免费 | 无码人中文字幕 | 67194成是人免费无码 | 国产激情精品一区二区三区 | 久久久国产精品无码免费专区 | 久久精品一区二区三区四区 | 国精产品一区二区三区 | 亚洲va中文字幕无码久久不卡 | 一个人看的www免费视频在线观看 | 扒开双腿吃奶呻吟做受视频 | 亚洲乱码中文字幕在线 | 中文字幕 人妻熟女 | 一本久久a久久精品亚洲 | 欧美猛少妇色xxxxx | 国产69精品久久久久app下载 | 亚洲乱码日产精品bd | 精品一区二区不卡无码av | 国产情侣作爱视频免费观看 | 国产后入清纯学生妹 | 国产色视频一区二区三区 | 4hu四虎永久在线观看 | 亚洲国产欧美在线成人 | 亚洲熟妇色xxxxx欧美老妇 | 午夜熟女插插xx免费视频 | 丰满人妻一区二区三区免费视频 | 国产真实乱对白精彩久久 | 日本高清一区免费中文视频 | 四虎影视成人永久免费观看视频 | 久久久久久国产精品无码下载 | 无码国产乱人伦偷精品视频 | 国产av无码专区亚洲a∨毛片 | 狠狠亚洲超碰狼人久久 | 成年美女黄网站色大免费视频 | 强辱丰满人妻hd中文字幕 | 午夜精品久久久久久久 | 国产精品高潮呻吟av久久 | 岛国片人妻三上悠亚 | 色综合天天综合狠狠爱 | 久久精品国产日本波多野结衣 | 国产69精品久久久久app下载 | 无码帝国www无码专区色综合 | 天下第一社区视频www日本 | 日日碰狠狠躁久久躁蜜桃 | 欧美人与善在线com | 久久99精品国产麻豆蜜芽 | 亚洲成av人在线观看网址 | 亚洲人成人无码网www国产 | 国产亚洲精品久久久久久大师 | 熟女少妇人妻中文字幕 | 亚洲人成人无码网www国产 | 中文字幕乱妇无码av在线 | 精品国产国产综合精品 | 精品无码av一区二区三区 | 动漫av网站免费观看 | 国产av一区二区精品久久凹凸 | 18无码粉嫩小泬无套在线观看 | 沈阳熟女露脸对白视频 | 国产艳妇av在线观看果冻传媒 | 亚洲综合在线一区二区三区 | 99国产精品白浆在线观看免费 | 综合激情五月综合激情五月激情1 | 欧美国产日韩久久mv | 亚洲精品综合五月久久小说 | 天天做天天爱天天爽综合网 | 亚洲a无码综合a国产av中文 | 国产精品永久免费视频 | 秋霞成人午夜鲁丝一区二区三区 | 小泽玛莉亚一区二区视频在线 | 国产精品无码mv在线观看 | 色婷婷综合激情综在线播放 | 亚洲va欧美va天堂v国产综合 | 亚洲色成人中文字幕网站 | 人妻尝试又大又粗久久 | 一个人免费观看的www视频 | 日韩av无码中文无码电影 | 免费看男女做好爽好硬视频 | 欧洲熟妇色 欧美 | 日韩欧美群交p片內射中文 | 日本熟妇人妻xxxxx人hd | 男人的天堂av网站 | 午夜精品一区二区三区的区别 | 在线欧美精品一区二区三区 | 精品乱码久久久久久久 | 熟妇人妻激情偷爽文 | 欧美自拍另类欧美综合图片区 | 99久久婷婷国产综合精品青草免费 | 国产乱人伦av在线无码 | 久久 国产 尿 小便 嘘嘘 | 精品国产一区二区三区av 性色 | 少妇性俱乐部纵欲狂欢电影 | 国产做国产爱免费视频 | 丝袜美腿亚洲一区二区 | 欧美第一黄网免费网站 | 国产一区二区三区日韩精品 | 成人无码视频免费播放 | 亚洲一区二区三区无码久久 | 性欧美熟妇videofreesex | 最新国产乱人伦偷精品免费网站 | 色一情一乱一伦一视频免费看 | 精品久久综合1区2区3区激情 | 成人精品视频一区二区三区尤物 | 久久午夜无码鲁丝片秋霞 | 综合激情五月综合激情五月激情1 | 亚洲经典千人经典日产 | 国产精品对白交换视频 | 婷婷五月综合缴情在线视频 | 成人无码视频免费播放 | 国产精品亚洲五月天高清 | 久久久久人妻一区精品色欧美 | 青春草在线视频免费观看 | 成人免费视频在线观看 | 天天躁夜夜躁狠狠是什么心态 | 纯爱无遮挡h肉动漫在线播放 | 亚洲中文字幕在线无码一区二区 | 日产国产精品亚洲系列 | 欧美国产日韩久久mv | 午夜福利一区二区三区在线观看 | 无套内谢老熟女 | 国内少妇偷人精品视频 | 人妻互换免费中文字幕 | 色五月丁香五月综合五月 | 三上悠亚人妻中文字幕在线 | 精品日本一区二区三区在线观看 | 国产97人人超碰caoprom | 激情内射日本一区二区三区 | 一本久久a久久精品vr综合 | 丰满岳乱妇在线观看中字无码 | 国产香蕉尹人视频在线 | 国产情侣作爱视频免费观看 | 亚洲热妇无码av在线播放 | 精品无码一区二区三区爱欲 | 国产三级精品三级男人的天堂 | 久久综合给合久久狠狠狠97色 | 欧美精品国产综合久久 | 久久久婷婷五月亚洲97号色 | 精品国产一区二区三区四区在线看 | 最新国产麻豆aⅴ精品无码 | 精品欧美一区二区三区久久久 | 300部国产真实乱 | 大肉大捧一进一出视频出来呀 | 国语精品一区二区三区 | 成人精品一区二区三区中文字幕 | 99在线 | 亚洲 | 免费无码一区二区三区蜜桃大 | 亚洲欧美精品aaaaaa片 | 99久久精品无码一区二区毛片 | 老太婆性杂交欧美肥老太 | 小泽玛莉亚一区二区视频在线 | 午夜理论片yy44880影院 | 亚洲一区二区三区香蕉 | 曰韩无码二三区中文字幕 | 思思久久99热只有频精品66 | 亚洲欧美日韩综合久久久 | 欧美三级不卡在线观看 | 高潮毛片无遮挡高清免费视频 | 女人色极品影院 | 国内精品一区二区三区不卡 | 亚洲国产欧美国产综合一区 | 美女黄网站人色视频免费国产 | 亚洲va欧美va天堂v国产综合 | 亚洲日本va午夜在线电影 | 99久久久无码国产精品免费 | 中文无码伦av中文字幕 | 1000部夫妻午夜免费 | 日本www一道久久久免费榴莲 | 亚洲一区二区三区播放 | 久久久久久久人妻无码中文字幕爆 | 久精品国产欧美亚洲色aⅴ大片 | 2019nv天堂香蕉在线观看 | 午夜丰满少妇性开放视频 | 久久精品视频在线看15 | 国产无av码在线观看 | 国产午夜无码精品免费看 | 人妻少妇精品无码专区二区 | 国产精品无码一区二区桃花视频 | 欧美性生交活xxxxxdddd | 思思久久99热只有频精品66 | 免费无码的av片在线观看 | 大肉大捧一进一出视频出来呀 | 夫妻免费无码v看片 | 欧美丰满老熟妇xxxxx性 | 99在线 | 亚洲 | 亚洲a无码综合a国产av中文 | 国产av一区二区精品久久凹凸 | 高清国产亚洲精品自在久久 | 欧美喷潮久久久xxxxx | 亚洲精品国产精品乱码不卡 | 亚洲综合伊人久久大杳蕉 | 国产亚洲精品精品国产亚洲综合 | 国产一区二区不卡老阿姨 | 亚洲精品久久久久avwww潮水 | 99久久精品日本一区二区免费 | 精品无码国产自产拍在线观看蜜 | 老熟妇乱子伦牲交视频 | 99久久久国产精品无码免费 | 欧美日韩综合一区二区三区 | 亚洲人成人无码网www国产 | 国产精品久久国产三级国 | 国产精品人人爽人人做我的可爱 | 国产av剧情md精品麻豆 | 国色天香社区在线视频 | 国产成人综合美国十次 | 成人无码影片精品久久久 | 亚洲精品一区二区三区在线观看 | 性开放的女人aaa片 | av人摸人人人澡人人超碰下载 | 兔费看少妇性l交大片免费 | 永久免费观看美女裸体的网站 | 亚洲精品一区二区三区在线观看 | 熟妇女人妻丰满少妇中文字幕 | 国产亚洲精品久久久久久 | 人人妻人人澡人人爽欧美一区九九 | 国产特级毛片aaaaaa高潮流水 | 精品无码国产自产拍在线观看蜜 | 成 人 网 站国产免费观看 | 亚洲国产精品无码久久久久高潮 | 久久99热只有频精品8 | 色综合视频一区二区三区 | 国产成人av免费观看 | 亚洲爆乳精品无码一区二区三区 | 人人妻在人人 | 天天躁日日躁狠狠躁免费麻豆 | 好爽又高潮了毛片免费下载 | 丰满肥臀大屁股熟妇激情视频 | 色一情一乱一伦一视频免费看 | 蜜臀av无码人妻精品 | 国产一区二区三区四区五区加勒比 | 亚洲精品一区二区三区在线 | 国产无套内射久久久国产 | 一区二区三区高清视频一 | 玩弄人妻少妇500系列视频 | 在线精品国产一区二区三区 | 欧美日韩久久久精品a片 | 少妇被粗大的猛进出69影院 | 精品人妻人人做人人爽夜夜爽 | 久久午夜无码鲁丝片秋霞 | 香蕉久久久久久av成人 | 日韩人妻无码一区二区三区久久99 | 国产高清不卡无码视频 | 久青草影院在线观看国产 | 国产人妻精品午夜福利免费 | 97资源共享在线视频 | 国产乱码精品一品二品 | 中文精品久久久久人妻不卡 | 久久天天躁狠狠躁夜夜免费观看 | 精品无码av一区二区三区 | 国产内射爽爽大片视频社区在线 | 国产成人无码午夜视频在线观看 | 又大又黄又粗又爽的免费视频 | 日韩人妻少妇一区二区三区 | 99久久婷婷国产综合精品青草免费 | 日本精品人妻无码免费大全 | 国产成人综合色在线观看网站 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 日本在线高清不卡免费播放 | 秋霞成人午夜鲁丝一区二区三区 | 人妻体内射精一区二区三四 | 亚洲爆乳大丰满无码专区 | 嫩b人妻精品一区二区三区 | 兔费看少妇性l交大片免费 | 国产精品香蕉在线观看 | 久久综合香蕉国产蜜臀av | 亚洲精品一区二区三区大桥未久 | 东京热男人av天堂 | 亚洲成a人一区二区三区 | 国产成人综合色在线观看网站 | 宝宝好涨水快流出来免费视频 | 国产一区二区三区四区五区加勒比 | 东京热一精品无码av | 国产成人无码一二三区视频 | 国产va免费精品观看 | 嫩b人妻精品一区二区三区 | 国产97色在线 | 免 | 国产特级毛片aaaaaa高潮流水 | 久久久婷婷五月亚洲97号色 | 欧美亚洲日韩国产人成在线播放 | 欧美老妇交乱视频在线观看 | 国产片av国语在线观看 | 欧美成人午夜精品久久久 | 三上悠亚人妻中文字幕在线 | 国产亚洲人成a在线v网站 | 色综合久久久久综合一本到桃花网 | 丰满少妇弄高潮了www | 欧美肥老太牲交大战 | 午夜丰满少妇性开放视频 | 国产明星裸体无码xxxx视频 | 亚洲精品鲁一鲁一区二区三区 | 日韩精品乱码av一区二区 | 亚洲成av人影院在线观看 | 蜜臀av在线播放 久久综合激激的五月天 | 国产精品福利视频导航 | 久久久国产精品无码免费专区 | 久久综合香蕉国产蜜臀av | 精品久久久无码人妻字幂 | 欧美成人免费全部网站 | 久久人人爽人人爽人人片ⅴ | 熟妇人妻激情偷爽文 | 亚洲精品成人福利网站 | 捆绑白丝粉色jk震动捧喷白浆 | 国产亚洲美女精品久久久2020 | 中文字幕中文有码在线 | 台湾无码一区二区 | 亚洲男人av香蕉爽爽爽爽 | 亚洲日韩一区二区三区 | 精品无人国产偷自产在线 | 国产在线精品一区二区三区直播 | 伊在人天堂亚洲香蕉精品区 | 久久99久久99精品中文字幕 | 久久精品成人欧美大片 | 国产精品人人妻人人爽 | 久久99精品国产麻豆 | 图片区 小说区 区 亚洲五月 | 亚洲国产精华液网站w | 激情人妻另类人妻伦 | 麻豆国产丝袜白领秘书在线观看 | 中文字幕av无码一区二区三区电影 | 国产精品va在线播放 | 亚洲国产精华液网站w | 好男人社区资源 | 色综合久久久久综合一本到桃花网 | 亚洲色欲色欲欲www在线 | 欧美日韩一区二区免费视频 | 国产免费无码一区二区视频 | 欧美变态另类xxxx | 久久婷婷五月综合色国产香蕉 | 99久久人妻精品免费二区 | 精品偷自拍另类在线观看 | 免费观看又污又黄的网站 | 在线 国产 欧美 亚洲 天堂 | 狠狠色丁香久久婷婷综合五月 | 一个人看的视频www在线 | 一本色道久久综合亚洲精品不卡 | 九九久久精品国产免费看小说 | 少妇厨房愉情理9仑片视频 | 2019午夜福利不卡片在线 | 少妇激情av一区二区 | 蜜臀av无码人妻精品 | 国产一区二区三区日韩精品 | 野狼第一精品社区 | 99久久婷婷国产综合精品青草免费 | 亚洲综合色区中文字幕 | 男女猛烈xx00免费视频试看 | 老熟妇乱子伦牲交视频 | 九月婷婷人人澡人人添人人爽 | 一本无码人妻在中文字幕免费 | 又大又硬又爽免费视频 | 俺去俺来也在线www色官网 | 一本大道久久东京热无码av | 国产精品人妻一区二区三区四 | 国产成人午夜福利在线播放 | 中文字幕色婷婷在线视频 | 99久久精品国产一区二区蜜芽 | 小泽玛莉亚一区二区视频在线 | 国产精品久久久 | 亚洲中文字幕va福利 | 日产精品99久久久久久 | 色婷婷香蕉在线一区二区 | 一本久道久久综合狠狠爱 | 国产成人无码专区 | 国产办公室秘书无码精品99 | 精品人妻人人做人人爽夜夜爽 | 中文无码伦av中文字幕 | 日本大香伊一区二区三区 | 久久久久99精品国产片 | 疯狂三人交性欧美 | 欧美日韩人成综合在线播放 | 色欲综合久久中文字幕网 | 国产精品第一区揄拍无码 | 久久久无码中文字幕久... | 日产精品高潮呻吟av久久 | 国产精品无码成人午夜电影 | 亚洲国产成人a精品不卡在线 | 久久精品中文字幕一区 | 无套内射视频囯产 | 国产69精品久久久久app下载 | 国产明星裸体无码xxxx视频 | 国产精品福利视频导航 | 18禁黄网站男男禁片免费观看 | 欧美变态另类xxxx | 人妻少妇精品久久 | 中文无码成人免费视频在线观看 | 装睡被陌生人摸出水好爽 | 久久国语露脸国产精品电影 | 中文字幕乱码人妻二区三区 | 又黄又爽又色的视频 | 欧美喷潮久久久xxxxx | 亚洲一区二区三区 | 2019午夜福利不卡片在线 | 内射爽无广熟女亚洲 | 中文字幕精品av一区二区五区 | 夜夜影院未满十八勿进 | aⅴ亚洲 日韩 色 图网站 播放 | 成人无码影片精品久久久 | 任你躁在线精品免费 | 人妻天天爽夜夜爽一区二区 | 亚洲日韩一区二区三区 | 免费人成网站视频在线观看 | 国产亚洲精品久久久久久大师 | 狠狠躁日日躁夜夜躁2020 | 欧美三级a做爰在线观看 | 偷窥日本少妇撒尿chinese | 熟女少妇人妻中文字幕 | av在线亚洲欧洲日产一区二区 | 久久国产精品二国产精品 | 亚洲aⅴ无码成人网站国产app | 欧美丰满老熟妇xxxxx性 | 欧美刺激性大交 | 日本一卡2卡3卡四卡精品网站 | www成人国产高清内射 | 精品偷拍一区二区三区在线看 | 动漫av一区二区在线观看 | 国产做国产爱免费视频 | 久久亚洲中文字幕无码 | 永久免费精品精品永久-夜色 | 国产精品成人av在线观看 | 成人欧美一区二区三区 | 人人妻人人澡人人爽欧美一区九九 | 亚洲国产欧美在线成人 | 99精品无人区乱码1区2区3区 | 日本一卡二卡不卡视频查询 | 国产莉萝无码av在线播放 | 成人精品视频一区二区 | 大色综合色综合网站 | 精品久久久无码人妻字幂 | 中文字幕色婷婷在线视频 | 亚洲精品一区三区三区在线观看 | 国产亚洲精品久久久闺蜜 | 亚洲国产成人a精品不卡在线 | 国产一区二区三区日韩精品 | 99久久人妻精品免费二区 | 捆绑白丝粉色jk震动捧喷白浆 | 亚洲阿v天堂在线 | 亚洲无人区午夜福利码高清完整版 | 中文字幕色婷婷在线视频 | 色综合久久久无码中文字幕 | 国产女主播喷水视频在线观看 | 欧洲极品少妇 | 久久久久久av无码免费看大片 | 在线成人www免费观看视频 | 精品日本一区二区三区在线观看 | 亚洲中文字幕无码中文字在线 | 日日橹狠狠爱欧美视频 | 久久午夜无码鲁丝片秋霞 | 粗大的内捧猛烈进出视频 | 国产亚洲精品精品国产亚洲综合 | 丝袜 中出 制服 人妻 美腿 | 99久久久无码国产aaa精品 | 亚洲国产综合无码一区 | 中文字幕人妻无码一夲道 | 国产黄在线观看免费观看不卡 | 露脸叫床粗话东北少妇 | 中国女人内谢69xxxx | 亚洲精品无码国产 | 图片小说视频一区二区 | 日韩 欧美 动漫 国产 制服 | 日本va欧美va欧美va精品 | 少妇一晚三次一区二区三区 | 一区二区三区高清视频一 | 久激情内射婷内射蜜桃人妖 | 国内丰满熟女出轨videos | 亚洲成在人网站无码天堂 | 荡女精品导航 | 精品日本一区二区三区在线观看 | 亚洲无人区午夜福利码高清完整版 | 日韩av无码一区二区三区不卡 | 99久久久无码国产aaa精品 | 久久精品人人做人人综合试看 | 欧美日韩一区二区三区自拍 | 天天做天天爱天天爽综合网 | 国产超碰人人爽人人做人人添 | 国产成人精品久久亚洲高清不卡 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 人人爽人人澡人人人妻 | 东京热一精品无码av | 亚洲中文字幕乱码av波多ji | 蜜臀av在线播放 久久综合激激的五月天 | 成在人线av无码免观看麻豆 | 国产偷抇久久精品a片69 | 性啪啪chinese东北女人 | 67194成是人免费无码 | 国产精品无码mv在线观看 | 荫蒂被男人添的好舒服爽免费视频 | 18禁黄网站男男禁片免费观看 | 成人一区二区免费视频 | 又湿又紧又大又爽a视频国产 | 好男人www社区 | 国产香蕉97碰碰久久人人 | 一本久道久久综合狠狠爱 | 77777熟女视频在线观看 а天堂中文在线官网 | 永久免费观看美女裸体的网站 | av无码电影一区二区三区 | 久久伊人色av天堂九九小黄鸭 | 国产又爽又猛又粗的视频a片 | 人人妻人人澡人人爽欧美一区九九 | 亚洲精品一区二区三区四区五区 | 久久99精品国产麻豆 | 久久精品国产一区二区三区 | 偷窥日本少妇撒尿chinese | 成人无码视频免费播放 | 日韩少妇白浆无码系列 | 国产无套内射久久久国产 | 东京无码熟妇人妻av在线网址 | 久久国产36精品色熟妇 | 国产乡下妇女做爰 | 国产两女互慰高潮视频在线观看 | 一本久道久久综合狠狠爱 | 久久国产劲爆∧v内射 | 无码人妻精品一区二区三区不卡 | 麻豆av传媒蜜桃天美传媒 | 亚洲人成网站在线播放942 | 人人妻人人澡人人爽人人精品浪潮 | yw尤物av无码国产在线观看 | 亚洲成a人一区二区三区 | 国产乱人伦偷精品视频 | 国产精品对白交换视频 | 亚洲 激情 小说 另类 欧美 | 国产97色在线 | 免 | 国产区女主播在线观看 | 久久成人a毛片免费观看网站 | 熟妇女人妻丰满少妇中文字幕 | 丝袜足控一区二区三区 | 国产电影无码午夜在线播放 | 国产精品对白交换视频 | 欧美午夜特黄aaaaaa片 | 久久亚洲中文字幕无码 | 久久久国产一区二区三区 | 自拍偷自拍亚洲精品10p | 熟妇人妻无乱码中文字幕 | 宝宝好涨水快流出来免费视频 | 一本久久a久久精品vr综合 | 美女毛片一区二区三区四区 | 国产精品多人p群无码 | 久久精品女人天堂av免费观看 | 日韩人妻无码一区二区三区久久99 | 领导边摸边吃奶边做爽在线观看 | 欧美放荡的少妇 | 色噜噜亚洲男人的天堂 | 久久99精品久久久久久动态图 | 人人妻人人澡人人爽人人精品 | 狠狠躁日日躁夜夜躁2020 | 亚洲一区二区三区四区 | 亚洲热妇无码av在线播放 | 久久 国产 尿 小便 嘘嘘 | 精品无码国产自产拍在线观看蜜 | 天天综合网天天综合色 | 欧美野外疯狂做受xxxx高潮 | 中文字幕无码热在线视频 | 久久人人爽人人爽人人片av高清 | 亚洲第一网站男人都懂 | 小泽玛莉亚一区二区视频在线 | 国产真人无遮挡作爱免费视频 | 久久久久久av无码免费看大片 | 亚洲国产av精品一区二区蜜芽 | 久久国产自偷自偷免费一区调 | 精品无码成人片一区二区98 | 欧洲极品少妇 | www一区二区www免费 | 色综合久久久久综合一本到桃花网 | 精品久久久中文字幕人妻 | 欧美第一黄网免费网站 | 天堂亚洲2017在线观看 | 精品aⅴ一区二区三区 | 免费视频欧美无人区码 | 欧美精品无码一区二区三区 | 中文毛片无遮挡高清免费 | 亚洲中文字幕无码中字 | 精品亚洲韩国一区二区三区 | 亚洲人亚洲人成电影网站色 | 福利一区二区三区视频在线观看 | 伊在人天堂亚洲香蕉精品区 | 高潮喷水的毛片 | 亚洲人成无码网www | 东京无码熟妇人妻av在线网址 | 少妇厨房愉情理9仑片视频 | 久久综合九色综合97网 | 一本加勒比波多野结衣 | 欧美35页视频在线观看 | 婷婷六月久久综合丁香 | 97久久国产亚洲精品超碰热 | 真人与拘做受免费视频一 | 国产精品无码永久免费888 | 国产av无码专区亚洲awww | 亚洲va中文字幕无码久久不卡 | 四虎永久在线精品免费网址 | 人人妻人人澡人人爽欧美一区九九 | 色综合久久久久综合一本到桃花网 | av香港经典三级级 在线 | 国产精品亚洲а∨无码播放麻豆 | 国内老熟妇对白xxxxhd | 天堂а√在线中文在线 | 国产成人精品优优av | 初尝人妻少妇中文字幕 | 久久精品国产一区二区三区肥胖 | 男人和女人高潮免费网站 | 久久99精品国产.久久久久 | 99er热精品视频 | 精品无码国产自产拍在线观看蜜 | 久久国产劲爆∧v内射 | 漂亮人妻洗澡被公强 日日躁 | 97色伦图片97综合影院 | 国产香蕉尹人视频在线 | 亚洲乱码中文字幕在线 | 国产激情一区二区三区 | 思思久久99热只有频精品66 | 一区二区传媒有限公司 | 大肉大捧一进一出好爽视频 | 无码av最新清无码专区吞精 | 精品无码成人片一区二区98 | 国产偷抇久久精品a片69 | 亚洲国产一区二区三区在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 亚洲一区二区三区国产精华液 | 高清不卡一区二区三区 | 爆乳一区二区三区无码 | 久久国内精品自在自线 | 丁香花在线影院观看在线播放 | 最新国产乱人伦偷精品免费网站 | 最新国产乱人伦偷精品免费网站 | 精品人妻av区 | 强辱丰满人妻hd中文字幕 | 国产特级毛片aaaaaaa高清 | 亚洲精品一区二区三区在线观看 | av香港经典三级级 在线 | 成人免费视频视频在线观看 免费 | 日本熟妇浓毛 | 国产真实伦对白全集 | 老太婆性杂交欧美肥老太 | 久久亚洲国产成人精品性色 | 亚洲娇小与黑人巨大交 | 夜夜躁日日躁狠狠久久av | 亚洲精品国产精品乱码不卡 | 日本熟妇大屁股人妻 | 永久免费观看美女裸体的网站 | 亚洲爆乳大丰满无码专区 | 国产成人亚洲综合无码 | 欧美日韩色另类综合 | 国产精品久久久 | 老太婆性杂交欧美肥老太 | 国产另类ts人妖一区二区 | 亚洲人亚洲人成电影网站色 | 久久久久se色偷偷亚洲精品av | 人妻熟女一区 | 欧美日本日韩 | 亚洲色欲色欲天天天www | 久久综合狠狠综合久久综合88 | 久久 国产 尿 小便 嘘嘘 | 少妇高潮一区二区三区99 | 激情内射亚州一区二区三区爱妻 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 欧美猛少妇色xxxxx | 国产人妻人伦精品1国产丝袜 | 中文字幕精品av一区二区五区 | 人人妻人人澡人人爽人人精品浪潮 | 色一情一乱一伦一区二区三欧美 | 国产美女极度色诱视频www | 搡女人真爽免费视频大全 | 最新版天堂资源中文官网 | 扒开双腿吃奶呻吟做受视频 | 成人精品视频一区二区 | 特大黑人娇小亚洲女 | 色窝窝无码一区二区三区色欲 | 亚洲精品久久久久久久久久久 | 老司机亚洲精品影院 | 四十如虎的丰满熟妇啪啪 | 国内少妇偷人精品视频 | 人妻有码中文字幕在线 | 国产精品久久久久久久9999 | 欧美xxxx黑人又粗又长 | 国产精品a成v人在线播放 | 久久99热只有频精品8 | 国产成人精品久久亚洲高清不卡 | 麻豆国产人妻欲求不满谁演的 | 午夜理论片yy44880影院 | 性做久久久久久久免费看 | 国产另类ts人妖一区二区 | 中文字幕中文有码在线 | 国产特级毛片aaaaaa高潮流水 | 亚洲精品成人福利网站 | 给我免费的视频在线观看 | 欧美性猛交xxxx富婆 | 国产精品二区一区二区aⅴ污介绍 | 国产内射老熟女aaaa | 牲欲强的熟妇农村老妇女视频 | 永久免费观看美女裸体的网站 | 一区二区传媒有限公司 | 国产成人精品优优av | 粉嫩少妇内射浓精videos | 丰满人妻精品国产99aⅴ | 特黄特色大片免费播放器图片 | 欧美国产日产一区二区 | 久9re热视频这里只有精品 | 男女下面进入的视频免费午夜 | 97无码免费人妻超级碰碰夜夜 | 中文字幕av无码一区二区三区电影 | 中文字幕人妻无码一夲道 | 亚洲精品久久久久久一区二区 | 欧美自拍另类欧美综合图片区 | 十八禁视频网站在线观看 | 天天拍夜夜添久久精品大 | 国产日产欧产精品精品app | 女人高潮内射99精品 | 性生交大片免费看女人按摩摩 | 天堂在线观看www | 久久国产精品精品国产色婷婷 | 强开小婷嫩苞又嫩又紧视频 | 久激情内射婷内射蜜桃人妖 | 亚洲成av人综合在线观看 | 亚洲精品久久久久久一区二区 | 偷窥村妇洗澡毛毛多 | 亚洲成在人网站无码天堂 | 国产舌乚八伦偷品w中 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 综合人妻久久一区二区精品 | 免费国产黄网站在线观看 | 人妻天天爽夜夜爽一区二区 | 欧美兽交xxxx×视频 | 日韩精品无码一本二本三本色 | 激情国产av做激情国产爱 | 女人高潮内射99精品 | 精品久久久中文字幕人妻 | 中文字幕精品av一区二区五区 | 色爱情人网站 | 高中生自慰www网站 | 欧美 亚洲 国产 另类 | 无码任你躁久久久久久久 | 给我免费的视频在线观看 | 国产成人精品久久亚洲高清不卡 | 无人区乱码一区二区三区 | 熟妇人妻激情偷爽文 | 国产另类ts人妖一区二区 | 精品无码国产一区二区三区av | 亚洲日韩av一区二区三区中文 | 大屁股大乳丰满人妻 | 亚洲自偷自偷在线制服 | 国产精品亚洲专区无码不卡 | 丰满妇女强制高潮18xxxx | 麻豆精品国产精华精华液好用吗 | 亚洲日韩av片在线观看 | 久久成人a毛片免费观看网站 | 精品国产麻豆免费人成网站 | 国产精品福利视频导航 | 国产精品-区区久久久狼 | 国产精品久久久久影院嫩草 | 俺去俺来也www色官网 | 久久人人爽人人爽人人片ⅴ | 久久99精品国产.久久久久 | 色欲av亚洲一区无码少妇 | 77777熟女视频在线观看 а天堂中文在线官网 | 熟女体下毛毛黑森林 | 玩弄少妇高潮ⅹxxxyw | 99er热精品视频 | 久久无码专区国产精品s | 国产免费久久精品国产传媒 | 国产成人亚洲综合无码 | 欧美激情一区二区三区成人 | 少妇性l交大片欧洲热妇乱xxx | 国产精品无码mv在线观看 | 久久精品99久久香蕉国产色戒 | 久久国产劲爆∧v内射 | 天天燥日日燥 | 国产 精品 自在自线 | 亚洲精品久久久久avwww潮水 | 十八禁真人啪啪免费网站 | 99riav国产精品视频 | 天天躁日日躁狠狠躁免费麻豆 | 欧美老妇交乱视频在线观看 | 亚洲国产精品无码久久久久高潮 | 亚洲国产一区二区三区在线观看 | 国产黑色丝袜在线播放 | 欧美一区二区三区视频在线观看 | 国产后入清纯学生妹 | 国产精品高潮呻吟av久久4虎 | 男女性色大片免费网站 | 欧美日韩一区二区免费视频 | 国内综合精品午夜久久资源 | 纯爱无遮挡h肉动漫在线播放 | 一本久道久久综合婷婷五月 | 18精品久久久无码午夜福利 | 色一情一乱一伦一视频免费看 | 1000部啪啪未满十八勿入下载 | 国产亚洲人成a在线v网站 | √天堂中文官网8在线 | 中文字幕人妻无码一区二区三区 | 大肉大捧一进一出好爽视频 | 精品偷拍一区二区三区在线看 | 国产特级毛片aaaaaaa高清 | 又大又黄又粗又爽的免费视频 | 亚洲人成影院在线无码按摩店 | 人人超人人超碰超国产 | 中文字幕无码免费久久99 | 亚洲欧美色中文字幕在线 | 波多野结衣乳巨码无在线观看 | 欧美性黑人极品hd | 亚洲一区二区三区 | 最近的中文字幕在线看视频 | 亚洲无人区午夜福利码高清完整版 | 久久精品国产一区二区三区 | 国内精品久久久久久中文字幕 | 国产精品美女久久久 | 久热国产vs视频在线观看 | 日韩人妻无码一区二区三区久久99 | 无码成人精品区在线观看 | 5858s亚洲色大成网站www | 国产激情无码一区二区app | 人妻少妇被猛烈进入中文字幕 | 国产成人精品一区二区在线小狼 | 亚洲精品一区二区三区大桥未久 | 国产综合久久久久鬼色 | 国产精品国产自线拍免费软件 | 丰满肥臀大屁股熟妇激情视频 | 岛国片人妻三上悠亚 | 六十路熟妇乱子伦 | 亚洲欧美日韩国产精品一区二区 | 天堂亚洲免费视频 | 乌克兰少妇性做爰 | 最近中文2019字幕第二页 | 国产农村妇女高潮大叫 | 精品日本一区二区三区在线观看 | 日韩精品乱码av一区二区 | 国产亚av手机在线观看 | 亚洲日韩av片在线观看 | 国产精品-区区久久久狼 | 综合激情五月综合激情五月激情1 | а√资源新版在线天堂 | 十八禁真人啪啪免费网站 | 欧美老妇交乱视频在线观看 | 在线观看国产午夜福利片 | 少女韩国电视剧在线观看完整 | 国产在热线精品视频 | 小sao货水好多真紧h无码视频 | 人妻无码久久精品人妻 | 波多野结衣av一区二区全免费观看 | 国产成人无码专区 | 无码精品人妻一区二区三区av | 亚洲精品国偷拍自产在线观看蜜桃 | 国产精品a成v人在线播放 | 日本高清一区免费中文视频 | 久久精品国产精品国产精品污 | 欧美日韩在线亚洲综合国产人 | 亚洲乱码国产乱码精品精 | 少妇性俱乐部纵欲狂欢电影 | 亚洲国产欧美日韩精品一区二区三区 | 女人高潮内射99精品 | а√天堂www在线天堂小说 | 色婷婷香蕉在线一区二区 | 国产又爽又猛又粗的视频a片 | 亚洲中文字幕va福利 | 中文字幕无码人妻少妇免费 | 在线a亚洲视频播放在线观看 | 午夜无码人妻av大片色欲 | 在线播放免费人成毛片乱码 | 男人的天堂2018无码 | 国内丰满熟女出轨videos | 国产97色在线 | 免 | 亚洲综合在线一区二区三区 | 奇米影视888欧美在线观看 | 99视频精品全部免费免费观看 | 日韩人妻无码中文字幕视频 | 无遮无挡爽爽免费视频 | 中文字幕日韩精品一区二区三区 | 少妇无码吹潮 | 国产熟女一区二区三区四区五区 | 美女张开腿让人桶 | 国产免费观看黄av片 | 无码精品国产va在线观看dvd | 在线精品国产一区二区三区 | 久久久久国色av免费观看性色 | 偷窥村妇洗澡毛毛多 | 国产sm调教视频在线观看 | 亚洲色欲色欲欲www在线 | 人人爽人人澡人人高潮 | 国内揄拍国内精品少妇国语 | 国产精品久久久久9999小说 | 初尝人妻少妇中文字幕 | 亚洲欧美精品伊人久久 | 亚洲春色在线视频 | 中文字幕日韩精品一区二区三区 | 国产精品久久久久久亚洲影视内衣 | 人人妻在人人 | 奇米影视888欧美在线观看 | 日韩av无码中文无码电影 | 一二三四在线观看免费视频 | 图片区 小说区 区 亚洲五月 | 午夜男女很黄的视频 | 强辱丰满人妻hd中文字幕 | 天天拍夜夜添久久精品大 | 漂亮人妻洗澡被公强 日日躁 | 秋霞特色aa大片 | 亚洲国产精品久久久久久 | 99麻豆久久久国产精品免费 | 亚洲国精产品一二二线 | 国产在线精品一区二区高清不卡 | 女高中生第一次破苞av | 无码人妻精品一区二区三区下载 | yw尤物av无码国产在线观看 | 98国产精品综合一区二区三区 | 97精品人妻一区二区三区香蕉 | 88国产精品欧美一区二区三区 | 国产精品久久久久久亚洲毛片 | 强奷人妻日本中文字幕 | 国产精品久久久久久亚洲影视内衣 | 亚洲日韩精品欧美一区二区 | 亚洲成熟女人毛毛耸耸多 | 国产精品.xx视频.xxtv | 一本久久伊人热热精品中文字幕 | 曰本女人与公拘交酡免费视频 | 国产真实乱对白精彩久久 | 又大又硬又黄的免费视频 | 人妻熟女一区 | 久久人妻内射无码一区三区 | 亚洲一区二区三区播放 | 亚洲人成网站在线播放942 | 国产精品毛多多水多 | 国产超级va在线观看视频 | 久久国产自偷自偷免费一区调 | 日产国产精品亚洲系列 | 国产舌乚八伦偷品w中 | 少妇的肉体aa片免费 | 久久99精品国产麻豆蜜芽 | 欧美精品在线观看 | 国产午夜亚洲精品不卡下载 | 国内揄拍国内精品少妇国语 | 欧美变态另类xxxx | 国产成人综合在线女婷五月99播放 | 未满成年国产在线观看 | 99久久久无码国产aaa精品 | 亚洲区小说区激情区图片区 | 扒开双腿疯狂进出爽爽爽视频 | 亚洲人成影院在线观看 | 丰满少妇女裸体bbw | 女人被男人躁得好爽免费视频 | 亲嘴扒胸摸屁股激烈网站 | 国产精品亚洲五月天高清 | 亚洲日韩av片在线观看 | 国产精品嫩草久久久久 | 日本熟妇大屁股人妻 | 男女爱爱好爽视频免费看 | 亚洲 a v无 码免 费 成 人 a v | 一二三四在线观看免费视频 | 亚洲日韩精品欧美一区二区 | 亚洲乱码国产乱码精品精 | 欧洲vodafone精品性 | 性开放的女人aaa片 | 人人妻人人澡人人爽人人精品浪潮 | 亚洲无人区一区二区三区 | 国产精品人人爽人人做我的可爱 | 亚洲国产精品久久人人爱 | 日日干夜夜干 | 久久精品一区二区三区四区 | 亚洲综合精品香蕉久久网 | 人人爽人人澡人人人妻 | 2019nv天堂香蕉在线观看 | 亚洲熟妇色xxxxx欧美老妇 | 亚洲国产精品成人久久蜜臀 | 成人欧美一区二区三区黑人 | 亚洲日本一区二区三区在线 | 男女猛烈xx00免费视频试看 | 久久 国产 尿 小便 嘘嘘 | 任你躁国产自任一区二区三区 | 久久久久久久久888 | 在线观看国产午夜福利片 | www国产亚洲精品久久久日本 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 午夜时刻免费入口 | 亚洲一区二区三区含羞草 | 日韩亚洲欧美精品综合 | 亚洲成av人在线观看网址 | 国产精品99爱免费视频 | 国产精品多人p群无码 | 精品乱码久久久久久久 | 极品尤物被啪到呻吟喷水 | 亚洲国产av美女网站 | 国产精品香蕉在线观看 | 夜夜影院未满十八勿进 | yw尤物av无码国产在线观看 | 午夜精品一区二区三区在线观看 | 精品国产麻豆免费人成网站 | 丰满护士巨好爽好大乳 | а天堂中文在线官网 | 久久aⅴ免费观看 | 亚洲男女内射在线播放 | 国产色视频一区二区三区 | 国产av剧情md精品麻豆 | 乱码av麻豆丝袜熟女系列 | 中文精品无码中文字幕无码专区 | 无码人妻丰满熟妇区五十路百度 | 亚洲成a人片在线观看无码 | 成熟女人特级毛片www免费 | 色欲综合久久中文字幕网 | 久久99精品久久久久久动态图 | 99精品国产综合久久久久五月天 | 日本一本二本三区免费 | 在线精品国产一区二区三区 | 国产精品人人妻人人爽 | 思思久久99热只有频精品66 | 色偷偷人人澡人人爽人人模 | 欧洲vodafone精品性 | 亚洲精品www久久久 | 国产午夜亚洲精品不卡下载 | 国产精品办公室沙发 | 99久久无码一区人妻 | 帮老师解开蕾丝奶罩吸乳网站 | 爽爽影院免费观看 | 亚洲の无码国产の无码步美 | 久久久久人妻一区精品色欧美 | 午夜福利电影 | 人人澡人人透人人爽 | 国产人妻精品一区二区三区不卡 | 欧美三级不卡在线观看 | а天堂中文在线官网 | 亚洲日本va中文字幕 | 水蜜桃亚洲一二三四在线 | 国产在线无码精品电影网 | 老熟女重囗味hdxx69 | 色一情一乱一伦一区二区三欧美 | 激情内射亚州一区二区三区爱妻 | 偷窥日本少妇撒尿chinese | 小sao货水好多真紧h无码视频 | 无码精品人妻一区二区三区av | 国内少妇偷人精品视频免费 | 无人区乱码一区二区三区 | 亚洲国产精品无码久久久久高潮 | 人人超人人超碰超国产 | 国产suv精品一区二区五 | 国产成人精品三级麻豆 | 久久精品一区二区三区四区 | 暴力强奷在线播放无码 | 欧美人与动性行为视频 | 天堂一区人妻无码 | 精品成在人线av无码免费看 | av无码电影一区二区三区 | 强奷人妻日本中文字幕 | 国产精品欧美成人 | 人妻中文无码久热丝袜 | 中文字幕 人妻熟女 | 国产在线精品一区二区三区直播 | 日韩无码专区 | 中文亚洲成a人片在线观看 | 国产suv精品一区二区五 | 欧美日韩一区二区综合 | 丰满人妻精品国产99aⅴ | 国产激情无码一区二区 | 亚洲国产欧美日韩精品一区二区三区 | 日本丰满护士爆乳xxxx | 久久久精品人妻久久影视 | 清纯唯美经典一区二区 | 精品亚洲成av人在线观看 | 亚洲熟妇色xxxxx欧美老妇y | 老司机亚洲精品影院无码 | 国内精品久久毛片一区二区 | 国产国产精品人在线视 | 亚洲一区二区三区香蕉 | 秋霞成人午夜鲁丝一区二区三区 | 偷窥村妇洗澡毛毛多 | 性啪啪chinese东北女人 | 欧美日韩视频无码一区二区三 | 天天躁日日躁狠狠躁免费麻豆 | 国产精品人人妻人人爽 | 特黄特色大片免费播放器图片 | 欧美日韩人成综合在线播放 | 日本乱偷人妻中文字幕 | 精品午夜福利在线观看 | 久久人妻内射无码一区三区 | 国产精品无码mv在线观看 | 亚洲精品久久久久中文第一幕 | 青青草原综合久久大伊人精品 | 人人爽人人爽人人片av亚洲 | 亚洲娇小与黑人巨大交 | av在线亚洲欧洲日产一区二区 | 又粗又大又硬又长又爽 | 无套内谢的新婚少妇国语播放 | 亚洲日本va午夜在线电影 | 国产亚洲精品久久久久久久久动漫 | 国产精品第一国产精品 | 亚洲精品鲁一鲁一区二区三区 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 丁香啪啪综合成人亚洲 | 久久国产精品二国产精品 | 精品欧洲av无码一区二区三区 | 国产黑色丝袜在线播放 | 午夜福利电影 | 熟女俱乐部五十路六十路av | 在线播放亚洲第一字幕 | 性生交大片免费看女人按摩摩 | 国产亚洲精品久久久久久久 | 秋霞特色aa大片 | 日韩欧美中文字幕公布 | 午夜肉伦伦影院 | 18黄暴禁片在线观看 | 色噜噜亚洲男人的天堂 | 日本熟妇大屁股人妻 | 亚洲综合伊人久久大杳蕉 | 中文字幕无码人妻少妇免费 | 国产成人一区二区三区别 | 久久综合色之久久综合 | 国产人妻精品一区二区三区不卡 | 初尝人妻少妇中文字幕 | 国产美女精品一区二区三区 | 一本无码人妻在中文字幕免费 | 国产69精品久久久久app下载 | 精品国产青草久久久久福利 | 免费人成网站视频在线观看 | 亚洲精品欧美二区三区中文字幕 | 国产美女精品一区二区三区 | 国产真实夫妇视频 | 日日鲁鲁鲁夜夜爽爽狠狠 | 99久久久无码国产aaa精品 | 成人片黄网站色大片免费观看 | 爽爽影院免费观看 | 日日躁夜夜躁狠狠躁 | 亚洲大尺度无码无码专区 | 无码免费一区二区三区 | 亚洲va欧美va天堂v国产综合 | 少妇人妻偷人精品无码视频 | 久久久精品456亚洲影院 | 蜜桃av抽搐高潮一区二区 | 亚洲第一无码av无码专区 | 国产在热线精品视频 | 成人免费视频一区二区 | 76少妇精品导航 | 国产人妻久久精品二区三区老狼 | 国产亚洲精品久久久久久大师 | 国产猛烈高潮尖叫视频免费 | 国产在线精品一区二区高清不卡 | 婷婷六月久久综合丁香 | 少妇人妻偷人精品无码视频 | 少妇性l交大片欧洲热妇乱xxx | 老熟妇仑乱视频一区二区 | www一区二区www免费 | 扒开双腿疯狂进出爽爽爽视频 | 丝袜 中出 制服 人妻 美腿 | 久久99热只有频精品8 | 97精品人妻一区二区三区香蕉 | 国产精品美女久久久久av爽李琼 | 国产莉萝无码av在线播放 | 人妻少妇精品无码专区动漫 | 国内丰满熟女出轨videos | 欧美 亚洲 国产 另类 | 人妻无码αv中文字幕久久琪琪布 | 熟女少妇人妻中文字幕 | 人妻天天爽夜夜爽一区二区 | 国产成人av免费观看 | 亚洲人交乣女bbw | 日本免费一区二区三区最新 | 亚洲爆乳无码专区 | 亚洲自偷自偷在线制服 | 国产精品无码成人午夜电影 | 67194成是人免费无码 | 一本无码人妻在中文字幕免费 | 国产激情精品一区二区三区 | 日产精品高潮呻吟av久久 | 精品偷拍一区二区三区在线看 | 亚洲色欲色欲天天天www | 爽爽影院免费观看 | 亚洲熟妇色xxxxx欧美老妇y | 天堂无码人妻精品一区二区三区 | 精品夜夜澡人妻无码av蜜桃 | 国产精品无码mv在线观看 | 日本饥渴人妻欲求不满 | 麻豆国产人妻欲求不满谁演的 | 亚洲综合精品香蕉久久网 | av人摸人人人澡人人超碰下载 | 欧美人与动性行为视频 | 国内精品久久毛片一区二区 | 国产综合色产在线精品 | 波多野结衣高清一区二区三区 | 宝宝好涨水快流出来免费视频 | av人摸人人人澡人人超碰下载 | 美女极度色诱视频国产 | 中文字幕人成乱码熟女app | 亚洲一区二区三区偷拍女厕 | 国产精品怡红院永久免费 | 人妻互换免费中文字幕 | 久久精品国产99精品亚洲 | 性色av无码免费一区二区三区 | 久久午夜夜伦鲁鲁片无码免费 | 国产亚洲视频中文字幕97精品 | 日韩人妻系列无码专区 | 国产精品.xx视频.xxtv | 久久综合给久久狠狠97色 | 国产午夜福利100集发布 | 欧美一区二区三区视频在线观看 | 2020久久超碰国产精品最新 | 2019nv天堂香蕉在线观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 亚洲色在线无码国产精品不卡 | 2020最新国产自产精品 | 国产亚洲精品久久久久久国模美 | 国产精品a成v人在线播放 | 欧美人与物videos另类 | 久久www免费人成人片 | 欧美日本免费一区二区三区 | 天天拍夜夜添久久精品 | 国产乱码精品一品二品 | 国产午夜福利亚洲第一 | 狂野欧美激情性xxxx | 日日橹狠狠爱欧美视频 | 免费无码午夜福利片69 | 永久免费观看国产裸体美女 | 亚洲精品久久久久久久久久久 | 国产人妖乱国产精品人妖 | 日韩精品无码一本二本三本色 | 成人一在线视频日韩国产 | 精品一区二区三区无码免费视频 | 免费无码肉片在线观看 | 伊在人天堂亚洲香蕉精品区 | 狠狠综合久久久久综合网 | 午夜福利试看120秒体验区 | 国产亚洲美女精品久久久2020 | 欧美人妻一区二区三区 | 色综合久久久无码中文字幕 | 97久久超碰中文字幕 | 精品无码一区二区三区的天堂 | 日韩精品无码免费一区二区三区 | 久久久精品成人免费观看 | 日日麻批免费40分钟无码 | 高清不卡一区二区三区 | 欧美日韩久久久精品a片 | 日本大香伊一区二区三区 | 国产明星裸体无码xxxx视频 | 欧美黑人性暴力猛交喷水 | 中文字幕人妻无码一区二区三区 | 99久久无码一区人妻 | 国产明星裸体无码xxxx视频 | 国内少妇偷人精品视频 | 国产免费久久精品国产传媒 | 大色综合色综合网站 | 国产无套粉嫩白浆在线 | 99在线 | 亚洲 | 亚洲性无码av中文字幕 | 大地资源中文第3页 | 免费无码av一区二区 | 欧美日韩精品 | 18无码粉嫩小泬无套在线观看 | 国产精品18久久久久久麻辣 | 亚洲精品国产a久久久久久 | 中文字幕久久久久人妻 | 免费乱码人妻系列无码专区 | 欧美激情综合亚洲一二区 | 妺妺窝人体色www在线小说 | 久久亚洲精品成人无码 | 欧美野外疯狂做受xxxx高潮 | 国产女主播喷水视频在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 中文毛片无遮挡高清免费 | 精品国产一区二区三区四区在线看 | 无码av中文字幕免费放 | 最新国产乱人伦偷精品免费网站 | 亚无码乱人伦一区二区 | 国产一区二区三区四区五区加勒比 | 日韩av无码中文无码电影 | 日韩人妻少妇一区二区三区 | 国产精品18久久久久久麻辣 | 日日碰狠狠躁久久躁蜜桃 | 55夜色66夜色国产精品视频 | 国产无套内射久久久国产 | 内射白嫩少妇超碰 | 国产成人精品优优av | 久久人人爽人人爽人人片ⅴ | 又大又紧又粉嫩18p少妇 | 国产无遮挡又黄又爽免费视频 | 久久99国产综合精品 | 玩弄少妇高潮ⅹxxxyw | 少妇久久久久久人妻无码 | 乱人伦中文视频在线观看 | 免费无码一区二区三区蜜桃大 | 国产性生交xxxxx无码 | 亚洲精品久久久久中文第一幕 | 国产真实乱对白精彩久久 | 亚洲精品成人福利网站 | 蜜臀aⅴ国产精品久久久国产老师 | 青草视频在线播放 | 久久97精品久久久久久久不卡 | 亚洲色欲色欲天天天www | 成人免费视频一区二区 | 四虎4hu永久免费 | 亚洲精品成人福利网站 |