• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

               C++ 技術中心

               :: 首頁 :: 聯系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發表的原創文章,作者保留一切權利。必須經過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            關鍵字:
              and break do else elseif end false for function if in local nil not or repeat return then true until while
            使用變量不需要聲明,總是全局變量,除非加"local"。local的作用域是在最里層的end和其配對的關鍵字之間。全局變量的作用域是整個程序。大小寫相關。定義一個變量的方法就是賦值"="操作。變量類型,可以用type()函數來檢查:
              Nil  空值,所有沒有使用過的變量都是nil。nil既是值又是類型。變量清除直接給變量賦以nil值。
              Boolean  布爾值true 和 false。只有false和nil才被計算為false,而所有任何其它類型的值,都是true。比如0,空串等等,都是true。
              Number  數值,相當于C語言的double實數如:4 0.4 4.57e-3 0.3e12 5e+20
              Userdata  可以是宿主的任意數據類型,常用的有Struct和指針。
              Thread 線程類型,在Lua中沒有真正的線程,將一個函數分成幾部份運行。
              String  字符串,可以包含'/0'字符,可以定義很長的字符串。用雙引號或單引號引用單行,"[["和"]]"引用多行字符串。新版支持"[==["和"]==]"多層標記,=號個數為層數。嚴格按層數匹配。支持一些轉義字符:
            /a鈴/b退格/f換頁/n換行/r回車/t制表符/v垂直制表//反斜杠/"雙引號/'單引號/[左中括號/]右中括號
              Table  關系表類型,功能強大。可以用除了nil任意類型的值來作數組的索引和內容。
              Table的定義:T1 = {}  T1[1]=10  T1["John"]={Age=27, Gender="Male"}
                這一句相當于T1["John"]["Gender"]="Male"
                索引是字符串時可以簡寫成:T1.John.Gender="Male"或T1.John={Age=27, Gender="Male"}
                第一,所有元素之間,總是用逗號","隔開;
                第二,所有索引值都需要用"["和"]"括起來;如果是字符串,還可以去掉引號和中括號;
                第三,如果不寫索引,則索引就會被認為是數字,并按順序自動從1往后編;
                T1=
                {
                  10,  -- 相當于 [1] = 10
                  [100] = 40,
                  John=  -- 如果你原意,你還可以寫成:["John"] =
                  {
                    Age=27,   -- 如果你原意,你還可以寫成:["Age"] =27
                    Gender=Male   -- 如果你原意,你還可以寫成:["Gender"] ="Male"
                  },
                  20  -- 相當于 [2] = 20
                }
              Function  函數也是一種類型,也就是說所有的函數本身就是一個變量。
            函數的定義:function add(a,b) return a+b end 相當于add = function (a,b) return a+b end
            如果函數只有一個參數,可以省略括號。
            return語言一定要寫在end之前。在中間放上return,寫成:do return end。
            函數可以接受可變參數個數,用"..."來定義function sum (a,b,...)
            如 果想取得...所代表的參數,5.0版本可以在函數中訪問arg局部變量(表類型)得到。如 sum(1,2,3,4)則,a = 1, b = 2, arg = {3, 4},在5.1版本多了一個...變量(實際就是參數列表),區別只在于arg和...共同存在的情況,...會使arg變nil。
            可以同時返回多個結果,比如:function s() return 1,2,3,4 end
                a,b,c,d = s()  -- 此時,a = 1, b = 2, c = 3, d = 4
            使用面向對象編程:
                t = { Age = 27, add = function(self, n) self.Age = self.Age+n end }
                print(t.Age)  -- 27
                t.add(t, 10) 可以簡寫成:t:add(10)
                print(t.Age)  -- 37

            單行注釋"--"。只要--后面第一個字符不是多行字符串引用符[[,即為多行注釋。
            語句之間可以用分號";"隔開,也可以用空白隔開。
            條件控制:if 條件 then … elseif 條件 then … else … end
            While循環:while 條件 do … end
            Repeat循環:repeat … until 條件
            For循環:for 變量 = 初值,終點值,步進 do … end
            可以省略步進值,這時候,for循環會使用1作為步進值。
            For循環:for 變量1,變量2,… ,變量N in表或枚舉函數 do … end
            語句塊用do 和 end 括起來的。可以在函數中和語句塊中定局部變量。
            賦值語句可以同時給多個變量賦值。例如:a,b,c,d=1,2,3,4甚至是:a,b=b,a 方便的交換變量功能
            默認變量總是全局的。定義局部變量,則在第一次賦值的時候用local說明。比如:
              local a,b,c = 1,2,3  -- a,b,c都是局部變量
            數值運算支持 +, -, *, /,^,#,%。^表示指數乘方。比如2^3 結果為8。5.1版加了#長度運算符。字符串的長度單位為字節,表的長度為nil前的整數索引個數,也就是數組的個數,如果有名為n的索引,它的值就是長度。5.1版引進%模運算。
            用".."連接兩個字符串。如:"This a " .. "string." -- 等于 "this a string"
            比較運算< > <= >= == ~=分別表示 小于,大于,不大于,不小于,相等,不相等。總是返回true或false。對于Table,Function和Userdata類型的數據,只有 == 和 ~=可以用。相等表示兩個變量引用的是同一個數據。比如: a={1,2}    b=a    print(a==b, a~=b)  -- true, false
                a={1,2}    b={1,2}    print(a==b, a~=b)  -- false, true
            邏輯運算and, or, not只有false和nil才計算為false,其它任何數據都計算為true,0也是true!
                and 和 or的運算結果不是true和false,而是和它的兩個操作數相關。
                a and b:如果a為false,則返回a;否則返回b
                a or b:如果 a 為true,則返回a;否則返回b
            運算符優先級,從高到低順序如下:
                ^
                not - (一元運算)#
                 * / %
                 + -
                 ..(字符串連接)
                 < > <= >= ~= ==
                 and
                 or
                 =
            常用標準庫函數:
            print (···)把所有參數打印出來,利用tostring (e)轉換非字符。奇怪的是nil不能做..操作。
            table.insert (table, [pos,] value)在pos位置插入一個值,默認是末尾。
            table.remove (table [, pos])在pos位置刪除一個值,默認是末尾。
            table.concat (table [, sep [, i [, j]]])用sep來連接數組里從i到j字符串或數字并返回一個長字符串,默認用空串從1到末尾。如果j大于i,返回空串。
            table.maxn (table)返回最大正數索引或0。
            table.sort (table [, comp])對數組排序,排序函數默認是<。
            string.byte (s [, i [, j]])返回s串從i到j的數值。舊版只支持2個參數
            string.char (···)和byte函數功能相反,返回0或多個數字對應的字符串。
            string.find (s, pattern [, init [, plain]])從s串中從init位置開始找到第一個匹配模式的子串位置,并返回起點和終點。plain如果為true,忽略模式。如果使用了捕獲,則增加返回捕獲的部分。
            string.gmatch (s, pattern)這是一個迭代函數,每次返回一個匹配的串。舊版叫gfind。如果使用了捕獲,則返回捕獲的部分。
            string.gsub (s, pattern, repl [, n])用rep1替換。n限制替換個數。%1-9表示被捕獲的值。如果第3個參數是個函數并返回假,替換字符將保持原配而不是舊版的空串。
            string.sub (s, i [, j])返回s從位置i到j的子串。負值表示從末尾往前數的位置。默認從1到末尾。
            string.match (s, pattern [, init])從init匹配或捕獲值返回。舊版沒有這個函數。
            string.format (formatstring, ···)格式化輸出。%q可以輸出安全字符串。
            string.rep (s, n)把s復制n份
            string.reverse (s)把s倒轉。舊版沒有這個函數。
            string.len (s)計算字符串長度。
            string.lower (s)小寫化。string.upper (s)大寫化。
            io.read (···)"*n"讀一個數字,支持各種格式;"*a"讀整個文件;"*l":讀一行,默認;"n"讀n個字符
            io.write (···)寫字符或者數字
            io.lines ([filename])迭代返回文件中的一行。
            pairs (t)迭代返回表中的鍵值對
            ipairs (t)迭代返回數組中的索引和值
            module (name [, ···])創建一個模塊。require (modname)加載一個模塊
            模式表:
            .任意字符%w字母和數字%a字母%d數字%p標點字符%s空白符%大寫字母表示相應集合的補集
            %u大寫字母%l小寫字母%x十六進制數字%z代表0的字符%c控制字符
            %是轉義標識 []集合 ^補集
            ()表示捕獲 %1-9是捕獲值 %bxy是以xy為標識的對稱結構
            ?匹配前一字符0次或1次 +匹配前一字符1次或多次
            *最長匹配前一字符0次或多次 -最短匹配前一字符0次或多次
            以^開頭的模式只匹配目標串的開始部分,相似的,以$結尾的模式只匹配目標串的結尾部分。
            c調用lua函數一般的過程是:
            1. load一個lua的文件,形成一個閉包并執行它
            2. 在棧中壓入函數的名稱
            3. 依次在棧中壓入函數的實參
            4. 使用lua_pcall調用lua函數。 形式是: lua_pcall(L, 參數個數,結果個數, 錯誤處理函數在棧中的索引)
                此時此函數相關的棧已經被清空。執行lua完畢后,如果成功,結果依次將壓入棧中, 如果不成功,錯誤信息將 壓入棧中
            5. 從棧中讀取返回結果或者錯誤信息。
            lua調用c函數(寫成庫的例子)
            lua調用庫在windows下是dll文件,在unix/linux下面是so文件
            vs的過程如下:
            1. 新建一個dll的工程
            2. 定義一個def文件,定義dll的導出,mylib.def定義如下:
            LIBRARY  mylib.dll
            DESCRIPTION "first dll for lua"
            EXPORTS
            luaopen_mylib
            3. 編寫庫,新建一個cpp文件.
            4. 定義庫函數,這里以pil的lsin函數,輸出傳入參數的sin()值
            5. 定義luaL_reg數組,這個是注冊一系列公開給lua調用的函數數組. 數組最后一個元素必須是 {NULL, NULL} 的luaL_reg結構用來做結束標識.
            6. 用luaL_openlib聲明主函數
            5.1版本和5.0版本的區別:
            新模塊系統,增量垃圾收集,varargs新機制,多行字符串或引用的新語法,#和%新操作符, metatable支持所有類型,使用luaconf.h來配置lua暫時避免版本沖突,完善的reentrant parser。Pil第二版包括了5.1的新內容,增加了新例子,對新模塊系統,多狀態和垃圾收集的詳細闡述。
            語法:
            函數傳遞可變參數用...來代替局部arg表。不使用...時,arg用法和舊版本一樣;但使用...后(無論先后),局部arg都會變成nil。
            在repeat.until里,局部變量的生命周期覆蓋到until條件后面;
            多行字符串或引用的新語法使用多層匹配代替以前的嵌套;
            #和%新操作符。
            庫函數:
            string.gfind改為string.gmatch;
            如果調用string.gsub的第3個參數是個函數,如果函數返回假,替換字符將保持原配而不是舊版的空串;
            table.setn廢棄,table.getn改為使用#;
            loadlib改為package.loadlib;
            math.mod改為math.fmod;
            table.foreach和table.foreachi作廢。可用for循環pairs或ipairs代替;
            require從package.path而不是LUA_PATH得到path值;
            collectgarbage (opt [, arg])參數從[limit]改為更多選擇,gcinfo廢棄改為collectgarbage("count");
            string.byte (s [, i [, j]])返回s串從i到j的數值。舊版只支持2個參數
            string.match (s, pattern [, init])從init匹配或捕獲值返回。舊版沒有這個函數。
            string.reverse (s)把s倒轉。舊版沒有這個函數。
            module (name [, ···])創建一個模塊。舊版沒有這個函數。
            C API:
            5.1版本增加了以luaL_開頭的輔助庫Auxiliary Library;
            luaL_getn改為lua_objlen,luaL_setn廢棄;
            luaL_openlib改為luaL_register;
            luaL_checkudata改為拋出異常而不是返回NULL。
            luaopen_* functions不能直接調用,改為像調用其它普通c函數一樣的過程;
            lua_open改為lua_newstate,可以設置內存分配方法。luaL_newstate默認使用realloc分配方法;
            5.0的調用方法:
             lua_State *L = lua_open();
             luaopen_base(L);
             luaopen_string(L);
             luaopen_math(L);
            5.1的調用方法:
             lua_State *L = luaL_newstate();
             lua_cpcall(L, luaopen_base, 0);
             lua_cpcall(L, luaopen_io, 0);
             lua_cpcall(L, luaopen_math, 0);
             lua_cpcall(L, luaopen_string, 0);
            lua_pushcfunction(L, luaopen_*);lua_call();等價于lua_cpcall(L, luaopen_*, 0);
             
            其他經驗:
            lua的擴展庫luasocket, luasql, luacom, kepler...
            程序可以存成cpp也可以存成c, 如果以.c為擴展名就不需要加extern "C"
            c和lua交互的時候,棧的編號是從1-n,也可以取負值,-1表示末尾
            設置環境變量LUA_PATH="E:/LuaEdit/myproject/?.lua",然后使用require "lua包/文件名"。然后就可以直接使用lua文件里的函數而不需要dofile(路徑)了。在windows下的路徑如果是/必須寫成//,或者/。
            lua5.1win32的解析器下載來后可以直接使用。luasocketwin32擴展包下載后,需要正確設置LUA_PATH=< LDIR>/?.lua;?.lua和LUA_CPATH=<CDIR>/?.dll;?.dll。然后運行lua解析器, require相應的socket包就可以了。
            在VC++6下編譯帶lua的.dll文件的時候,在工程設置里必須指明LIBC.lib Libcmtd.lib的加載順序。選擇VC菜單Project->Settings->Link->Catagory然后在 Object/library  Modules的Edit欄中填入LIBC.lib Libcmtd.lib。否則會出現:
            Linking...
            LIBC.lib(crt0dat.obj) : error LNK2005: __cinit already defined in LIBCMTD.lib(crt0dat.obj)
             
            新版本下表迭帶需要加pairs(t),舊版本以下代碼結果是正確的:
            Lua 5.1.2  Copyright (C) 1994-2007 Lua.org, PUC-Rio
            > function print_contents(t)
            >> for k,v in t do
            >> print(k .. "=" .. v)
            >> end
            >> end
            > print_contents{x=10, y=20}
            stdin:2: attempt to call a table value
            stack traceback:
                    stdin:2: in function 'print_contents'
                    stdin:1: in main chunk
                    [C]: ?
             
            新版本中的...和arg不能同時出現,無論先后,...的出現都會使arg為nil:
            print(#arg)
            function test(...)
            --print(...)
            print(type(arg),#arg)
            --print(...)
            end
            test(1,2,3,4)
            print(#arg)
            運行結果:
            E:/lua5_1_2_Win32_bin>lua5.1 e....lua 1 2 3
            3
            table   4
            3
            結果說明arg在新版本中還是可以使用的,但跟...沖突,跟全局表arg不沖突。但本地arg會覆蓋全局的arg,如果兩者都要調用該如何處理?使用...后,編譯器仍然把函數里的arg看成是局部變量。因此變通的方法是:
            print(#arg)
            t=arg
            function test(...)
            print(...)
            arg=t
            print(type(arg),#arg)
            --print(...)
            end
            test(1,2,3,4)
            print(#arg)
            這和舊版本是一樣的。看來引入...的用意不是為了區分全局和局部的arg。那究竟是為了什么呢??
             
            lua安裝:
            Windows:  
            把etc目錄下的luavs.bat 拷到lua的解壓根目錄下直接運行, 生成的.h .dll .lib .exe文件都在src下。
            Linux:
            $make linux && make install 標準的linux安裝

            在Windows XP SP2下使用Visual C++ 6. 編譯lua的過程分為3步:
            1,建立靜態庫工程,編譯庫文件
                 Lua庫由標準庫和核心庫組成,我用的是5.1版本,所有代碼都放在src目錄中。把src目錄中除lua.c,luac.c文件外所有的*.c文件添加到項目中,設置一下輸出路徑,F7編譯就可以了。
            2,建立Win32控制臺工程 編譯lua.exe Lua解釋器
               把lua.c添加到工程中,link選項中包含進剛才編譯好的lib文件,F7編譯
            3.再建立Win32控制臺工程, 編譯luac.exe  Lua編譯器
               同上步一樣,編譯成功后生成luac.exe, 最好把這兩個文件放在新建的bin文件下,在添加進系統的環境變量。 
             
            tolua++在cygwin下不用SCons編譯:
            詳見http://lua-users.org/wiki/CompilingToluappWithoutScons
            src/lib下:
            gcc -shared -o tolua++.dll *.c /usr/local/lib/lua51.dll -I../../include -I/usr/local/include
            gcc -c *.c  -I../../include -I/usr/local/include
            ar rcsv libtolua++.a *.o
            src/bin下:
            gcc tolua.c toluabind.c -I../../include -I/usr/local/include -L /usr/local/lib -llua -L../lib/ -ltolua++
            然后把所得到的文件復制到系統相應目錄中。
            使用tolua用.pkg生成.cpp的時候,在生成的.cpp最前面設置#define TOLUA_API extern "C" __declspec(dllexport)可以使.dll文件導出時不改變文件名。貌似還要加
            #ifndef __cplusplus#define __cplusplus#endif
            使用cygwin產生的.dll文件不能被lua使用。用同一源文件在vc下生成的.dll文件是可以被lua用的。
            使用VC編譯tolua時,把除了tolua.c和xxx.defalt以外的.c和.h都包含進去,然后在tolua++.h里設置 #define TOLUA_API extern "C" __declspec,不斷得修改#include "tolua++.h"在各個文件中的位置,使得用dumpbin看到65個導出函數為止。貌似VC6版本太低不能成功設置預編譯處理選項,因此這樣麻煩 點。編譯成功后就有.lib和.dll文件供接下來的.dll工程使用。

            extern "C" _declspec(dillexport)
            extern "C" void DLL_EXPORT __stdcall
             
            ============
            實際應用場景練習
            ============
            一、利用Lua的Table實現類的多繼承:
                1、假設基類為B1、B2
                2、繼承的類為A
                3、使用的時候類似于:
                        Instance1 = A:new()
                        Instance1:Method1(arg1, arg2)
                這個不難,但是務必要掌握table的應用
            答案:見OO.lua。在lua解析器下運行:dofile "OO.lua"
             
            二、利用lua的擴展包luasocket實現http的一個應用:
                1、構造http協議,訪問www.qq.com,具體的訪問方式網上有例子。
                2、在返回來的http包中,取出騰訊公司的客服電話號碼 -- 需要使用到lua的字符串查找和模式匹配函數。
            答案:
            下載lua5.1win32的解析器和luasocketwin32擴展包,正確設置LUA_PATH=< LDIR>/?.lua;?.lua和LUA_CPATH=<CDIR>/?.dll;?.dll,<CDIR>指向 luasocket-2.0.1-lua5.1-win32/lib,<LDIR>指向luasocket-2.0.1-lua5.1- win32/lua。lua程序見Phone.lua。在lua解析器下運行:dofile "Phone.lua"
            ----------------------------
            http = require("socket.http")
            qqweb = http.request("http://www.qq.com")
            tel=string.match(qqweb,"騰訊客服電話:(%d+%-%d+)")
            print("您要的電話號碼是:"..tel)
            -------------------------------

            三、在Windows下,利用C++實現一個基本的Socket類庫來給Lua使用:
                1、結合tolua++進行編譯,生成Lua可以調用的dll文件,請參考網上的資料來熟悉tolua++的使用
                2、假設dll文件名為MySocket.dll,類為CMySocket,則調用的時候類似于:
                    require("MySocket")
                    Instance1 = CMySocket:new()
                    Instance2 = CMySocket:new()
                    Instance1:Listen(9701)
                    Instance2:Connect("127.0.0.1",9701)
            答案:
            windows下編譯lua:
            把etc目錄下的luavs.bat 拷到lua的解壓根目錄下直接運行, 生成的.h .dll .lib .exe文件都在src下。
            把相應的.h文件和lua51.lib文件拷貝到VC相應目錄下。lua.exe和lua51.dll為lua解析器。
            在cygwin下編譯安裝方法:$make linux && make install
            用cygwin編譯安裝tolua++,且不用SCons編譯:
            src/lib下:
            動態鏈接文件:
            gcc -shared -o tolua++.dll *.c /usr/local/lib/lua51.dll -I../../include -I/usr/local/include
            靜態連接文件:
            gcc -c *.c  -I../../include -I/usr/local/include
            ar rcsv libtolua++.a *.o
            src/bin下:
            執行文件,改名為tolua++.exe:
            gcc tolua.c toluabind.c -I../../include -I/usr/local/include -L /usr/local/lib -llua -L../lib/ -ltolua++
            然后把所得到的文件復制到系統相應目錄中。
            根據mysocket.h設計mysocket類模式,寫成.pkg文件。
            產生binding文件mypkg.cpp備用,此時要用到mysocket.h:tolua++ -o mypkg.cpp mysocket.pkg
            適當修改一下生成的mypkg.cpp文件,使以后導出的.dll文件函數名不變。
            #define TOLUA_API extern "C" __declspec
            用以下方法在cygwin下編譯的.dll文件不能被lua使用,加載包會失敗。
            g++ -shared -o MySocket.dll *.cpp  /usr/local/lib/lua51.dll -I/usr/local/include -I.. -L /usr/local/lib -ltolua++
            改用VC來編譯。先編譯tolua++。
            把src下除了tolua.c和toluabind_default.x以外的.c和.h都包 含進去。工程設置里要包含LIBC.lib Libcmtd.lib tolua.lib lua5.1.lib,include和lib路徑也要包含lua的。然后設置#define TOLUA_API extern "C" __declspec編譯成功后就有tolua.lib和tolua.dll文件供接下來的.dll工程使用。
            把bingding文件mypkg.cpp和寫好的mysocket.cpp,mysocket.h一起在VC下編譯生成.dll文件。工程設 置里要包含LIBC.lib Libcmtd.lib tolua.lib lua51.lib,include和lib路徑也要包含lua或tolua的。前面兩個文件順序一定不要寫錯,否則產生如下錯誤:
            Linking...
            LIBC.lib(crt0dat.obj) : error LNK2005: __cinit already defined in LIBCMTD.lib(crt0dat.obj)
            編譯產生的MySocket.dll文件就可以被lua調用了。
            運行一個lua解析器程序實例,執行:
            require("MySocket")
            Instance1 = CMySocket:new()
            Instance1:Listen(9701)
            再運行另一個lua解析器程序實例,執行:
            require("MySocket")
            Instance2 = CMySocket:new()
            Instance2:Connect("127.0.0.1",9701)
            posted on 2014-06-25 16:32 C++技術中心 閱讀(3031) 評論(0)  編輯 收藏 引用 所屬分類: 其他編程
            久久只有这精品99| 国产一区二区精品久久岳| 精品伊人久久大线蕉色首页| 久久亚洲精品国产亚洲老地址| 7777精品久久久大香线蕉| 精品国际久久久久999波多野| 国产成人久久精品二区三区| 无码人妻久久一区二区三区蜜桃| 浪潮AV色综合久久天堂| 国产亚州精品女人久久久久久| 三级三级久久三级久久| 欧美综合天天夜夜久久| 久久精品国产亚洲AV香蕉| 久久91这里精品国产2020| 色综合久久无码中文字幕| 亚洲性久久久影院| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 99久久免费国产精品| 亚洲AV日韩精品久久久久久久| 成人a毛片久久免费播放| 久久99精品国产麻豆| 亚洲成av人片不卡无码久久| 久久精品成人免费网站| 久久99久久99精品免视看动漫| 久久无码高潮喷水| 性做久久久久久久久久久| 99久久综合国产精品二区| 久久线看观看精品香蕉国产| 人妻丰满AV无码久久不卡| 久久精品卫校国产小美女| 欧美成人免费观看久久| 中文字幕精品久久久久人妻| 久久九九久精品国产免费直播| 久久本道综合久久伊人| 久久99精品国产麻豆不卡| 亚洲国产成人久久精品影视| 久久亚洲精品人成综合网| 久久国产高潮流白浆免费观看| 国产亚洲综合久久系列| 国产美女久久久| 国产精品综合久久第一页|