• <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>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            玩轉setjmp與longjmp

            Posted on 2009-05-19 11:30 Prayer 閱讀(301) 評論(0)  編輯 收藏 引用 所屬分類: C/C++LINUX/UNIX/AIX
            不要忘記,前面我們得出過結論,C語言中提供的這種異常處理機制,與C++中的異常處理模型很相似。例如,可以定義出類似的try block(受到監(jiān)控的代碼);catch block(異常錯誤的處理模塊);以及可以隨時拋出的異常(throw語句)。所以說,我們可以通過一種非常有技巧的封裝,來達到對setjmp和longjmp的使用方法(或者說語法規(guī)則),基本與C++中的語法一致。很有誘惑吧!

            首先展示阿愚封裝的在C語言環(huán)境中異常處理框架

              1、首先是接口的頭文件,主要采用“宏”技術!代碼如下:

            /*************************************************
            * author: 王勝祥 *
            * email: <mantx@21cn.com> *
            * date: 2005-03-07 *
            * version: *
            * filename: ceh.h *
            *************************************************/


            /********************************************************************

            This file is part of CEH(Exception Handling in C Language).

            CEH is free software; you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation; either version 2 of the License, or
            (at your option) any later version.

            CEH is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
            GNU General Public License for more details.

              注意:這個異常處理框架不支持線程安全,不能在多線程的程序環(huán)境下使用。
            如果您想在多線程的程序中使用它,您可以自己試著來繼續(xù)完善這個
            框架模型。
            *********************************************************************/

            #include <stdio.h>
            #include <signal.h>
            #include <setjmp.h>
            #include <stdlib.h>
            #include <float.h>
            #include <math.h>
            #include <string.h>


            ////////////////////////////////////////////////////
            /* 與異常有關的結構體定義 */
            typedef struct _CEH_EXCEPTION {
            int err_type; /* 異常類型 */
            int err_code; /* 錯誤代碼 */
            char err_msg[80]; /* 錯誤信息 */
            }CEH_EXCEPTION; /* 異常對象 */

            typedef struct _CEH_ELEMENT {
            jmp_buf exec_status;
            CEH_EXCEPTION ex_info;

            struct _CEH_ELEMENT* next;
            } CEH_ELEMENT; /* 存儲異常對象的鏈表元素 */
            ////////////////////////////////////////////////////


            ////////////////////////////////////////////////////
            /* 內部接口定義,操縱維護鏈表數(shù)據(jù)結構 */
            extern void CEH_push(CEH_ELEMENT* ceh_element);
            extern CEH_ELEMENT* CEH_pop();
            extern CEH_ELEMENT* CEH_top();
            extern int CEH_isEmpty();
            ////////////////////////////////////////////////////


            /* 以下是外部接口的定義 */
            ////////////////////////////////////////////////////
            /* 拋出異常 */
            extern void thrower(CEH_EXCEPTION* e);

            /* 拋出異常 (throw)
            a表示err_type
            b表示err_code
            c表示err_msg
            */
            #define throw(a, b, c)
            {
            CEH_EXCEPTION ex;
            memset(&ex, 0, sizeof(ex));
            ex.err_type = a;
            ex.err_code = b;
            strncpy(ex.err_msg, c, sizeof(c));
            thrower(&ex);
            }

            /* 重新拋出原來的異常 (rethrow)*/
            #define rethrow thrower(ceh_ex_info)
            ////////////////////////////////////////////////////


            ////////////////////////////////////////////////////
            /* 定義try block(受到監(jiān)控的代碼)*/
            #define try
            {
            int ___ceh_b_catch_found, ___ceh_b_occur_exception;
            CEH_ELEMENT ___ceh_element;
            CEH_EXCEPTION* ceh_ex_info;
            memset(&___ceh_element, 0, sizeof(___ceh_element));
            CEH_push(&___ceh_element);
            ceh_ex_info = &___ceh_element.ex_info;
            ___ceh_b_catch_found = 0;
            if (!(___ceh_b_occur_exception=setjmp(___ceh_element.exec_status)))
            {


            /* 定義catch block(異常錯誤的處理模塊)
            catch表示捕獲所有類型的異常
            */
            #define catch
            }
            else
            {
            CEH_pop();
            ___ceh_b_catch_found = 1;


            /* end_try表示前面定義的try block和catch block結束 */
            #define end_try
            }
            {
            /* 沒有執(zhí)行到任何的catch塊中 */
            if(!___ceh_b_catch_found)
            {
            CEH_pop();
            /* 出現(xiàn)了異常,但沒有捕獲到任何異常 */
            if(___ceh_b_occur_exception) thrower(ceh_ex_info);
            }
            }
            }


            /* 定義catch block(異常錯誤的處理模塊)
            catch_part表示捕獲一定范圍內的異常
            */
            #define catch_part(i, j)
            }
            else if(ceh_ex_info->err_type>=i && ceh_ex_info->err_type<=j)
            {
            CEH_pop();
            ___ceh_b_catch_found = 1;


            /* 定義catch block(異常錯誤的處理模塊)
            catch_one表示只捕獲一種類型的異常
            */
            #define catch_one(i)
            }
            else if(ceh_ex_info->err_type==i)
            {
            CEH_pop();
            ___ceh_b_catch_found = 1;
            ////////////////////////////////////////////////////


            ////////////////////////////////////////////////////
            /* 其它可選的接口定義 */
            extern void CEH_init();
            ////////////////////////////////////////////////////


            2、另外還有一個簡單的實現(xiàn)文件,主要實現(xiàn)功能封裝。代碼如下:

            /*************************************************
            * author: 王勝祥 *
            * email: <mantx@21cn.com> *
            * date: 2005-03-07 *
            * version: *
            * filename: ceh.c *
            *************************************************/


            /********************************************************************

            This file is part of CEH(Exception Handling in C Language).

            CEH is free software; you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation; either version 2 of the License, or
            (at your option) any later version.

            CEH is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
            GNU General Public License for more details.

            注意:這個異常處理框架不支持線程安全,不能在多線程的程序環(huán)境下使用。
            如果您想在多線程的程序中使用它,您可以自己試著來繼續(xù)完善這個
            框架模型。
            *********************************************************************/

            #include "ceh.h"

            ////////////////////////////////////////////////////
            static CEH_ELEMENT* head = 0;

            /* 把一個異常插入到鏈表頭中 */
            void CEH_push(CEH_ELEMENT* ceh_element)
            {
            if(head) ceh_element->next = head;
            head = ceh_element;
            }


            /* 從鏈表頭中,刪除并返回一個異常 */
            CEH_ELEMENT* CEH_pop()
            {
            CEH_ELEMENT* ret = 0;

            ret = head;
            head = head->next;

            return ret;
            }


            /* 從鏈表頭中,返回一個異常 */
            CEH_ELEMENT* CEH_top()
            {
            return head;
            }


            /* 鏈表中是否有任何異常 */
            int CEH_isEmpty()
            {
            return head==0;
            }
            ////////////////////////////////////////////////////


            ////////////////////////////////////////////////////
            /* 缺省的異常處理模塊 */
            static void CEH_uncaught_exception_handler(CEH_EXCEPTION *ceh_ex_info)
            {
            printf("捕獲到一個未處理的異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            fprintf(stderr, "程序終止! ");
            fflush(stderr);
            exit(EXIT_FAILURE);
            }
            ////////////////////////////////////////////////////


            ////////////////////////////////////////////////////
            /* 拋出異常 */
            void thrower(CEH_EXCEPTION* e)
            {
            CEH_ELEMENT *se;

            if (CEH_isEmpty()) CEH_uncaught_exception_handler(e);

            se = CEH_top();
            se->ex_info.err_type = e->err_type;
            se->ex_info.err_code = e->err_code;
            strncpy(se->ex_info.err_msg, e->err_msg, sizeof(se->ex_info.err_msg));

            longjmp(se->exec_status, 1);
            }
            ////////////////////////////////////////////////////


            ////////////////////////////////////////////////////
            static void fphandler( int sig, int num )
            {
            _fpreset();

            switch( num )
            {
            case _FPE_INVALID:
            throw(-1, num, "Invalid number" );
            case _FPE_OVERFLOW:
            throw(-1, num, "Overflow" );
            case _FPE_UNDERFLOW:
            throw(-1, num, "Underflow" );
            case _FPE_ZERODIVIDE:
            throw(-1, num, "Divide by zero" );
            default:
            throw(-1, num, "Other floating point error" );
            }
            }

            void CEH_init()
            {
            _control87( 0, _MCW_EM );

            if( signal( SIGFPE, fphandler ) == SIG_ERR )
            {
            fprintf( stderr, "Couldn't set SIGFPE " );
            abort();
            }
            }
            ////////////////////////////////////////////////////
              體驗上面設計出的異常處理框架
            請花點時間仔細揣摩一下上面設計出的異常處理框架。呵呵!程序員朋友們,大家是不是發(fā)現(xiàn)它與C++提供的異常處理模型非常相似。例如,它提供的基本接口有 try、catch、以及throw等三條語句。還是先看個具體例子吧!以便驗證一下這個C語言環(huán)境中異常處理框架是否真的比較好用。代碼如下:

            #include "ceh.h"

            int main(void)
            {
            //定義try block塊
            try
            {
            int i,j;
            printf("異常出現(xiàn)前 ");

            // 拋出一個異常
            // 其中第一個參數(shù),表示異常類型;第二個參數(shù)表示錯誤代碼
            // 第三個參數(shù)表示錯誤信息
            throw(9, 15, "出現(xiàn)某某異常");

            printf("異常出現(xiàn)后 ");
            }
            //定義catch block塊
            catch
            {
            printf("catch塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            // 這里稍有不同,需要定義一個表示當前的try block結束語句
            // 它主要是清除相應的資源
            end_try
            }

              注意,上面的測試程序可是C語言環(huán)境下的程序(文件的擴展名請使用.c結尾),雖然它看上去很像C++程序。請編譯運行一下,發(fā)現(xiàn)它是不是運行結果如下:
            異常出現(xiàn)前

            catch塊,被執(zhí)行到

              捕獲到一個異常,錯誤原因是:出現(xiàn)某某異常! err_type:9 err_code:15

              呵呵!程序的確是在按照我們預想的流程在執(zhí)行。再次提醒,這可是C程序,但是它的異常處理卻非常類似于C++中的風格,要知道,做到這一點其實非常地不容易。當然,上面異常對象的傳遞只是在一個函數(shù)的內部,同樣,它也適用于多個嵌套函數(shù)間的異常傳遞,還是用代碼驗證一下吧!在上面的代碼基礎下,小小修改一點,代碼如下:

            #include "ceh.h"

            void test1()
            {
            throw(0, 20, "hahaha");
            }

            void test()
            {
            test1();
            }

            int main(void)
            {
            try
            {
            int i,j;
            printf("異常出現(xiàn)前 ");

            // 注意,這個函數(shù)的內部會拋出一個異常。
            test();

            throw(9, 15, "出現(xiàn)某某異常");

            printf("異常出現(xiàn)后 ");
            }
            catch
            {
            printf("catch塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try
            }

              同樣,在上面程序中,test1()函數(shù)內拋出的異常,可以被上層main()函數(shù)中的catch block中捕獲到。運行結果就不再給出了,大家可以自己編譯運行一把,看看運行結果。
            另外這個異常處理框架,與C++中的異常處理模型類似,它也支持try catch塊的多層嵌套。很厲害吧!還是看演示代碼吧!,如下:

            #include "ceh.h"

            int main(void)
            {
            // 外層的try catch塊
            try
            {
            // 內層的try catch塊
            try
            {
            throw(1, 15, "嵌套在try塊中");
            }
            catch
            {
            printf("內層的catch塊被執(zhí)行 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);

            printf("外層的catch塊被執(zhí)行 ");
            }
            end_try

            throw(2, 30, "再拋一個異常");
            }
            catch
            {
            printf("外層的catch塊被執(zhí)行 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try
            }

              請編譯運行一下,程序的運行結果如下:
              內層的catch塊被執(zhí)行
              捕獲到一個異常,錯誤原因是:嵌套在try塊中! err_type:1 err_code:15
              外層的catch塊被執(zhí)行
              捕獲到一個異常,錯誤原因是:再拋一個異常! err_type:2 err_code:30

              還有,這個異常處理框架也支持對異常的分類處理。這一點,也完全是模仿C++中的異常處理模型。不過,由于C語言中,不支持函數(shù)名重載,所以語法上略有不同,還是看演示代碼吧!,如下:

            #include "ceh.h"

            int main(void)
            {
            try
            {
            int i,j;
            printf("異常出現(xiàn)前 ");

            throw(9, 15, "出現(xiàn)某某異常");

            printf("異常出現(xiàn)后 ");
            }
            // 這里表示捕獲異常類型從4到6的異常
            catch_part(4, 6)
            {
            printf("catch_part(4, 6)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            // 這里表示捕獲異常類型從9到10的異常
            catch_part(9, 10)
            {
            printf("catch_part(9, 10)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            // 這里表示只捕獲異常類型為1的異常
            catch_one(1)
            {
            printf("catch_one(1)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            // 這里表示捕獲所有類型的異常
            catch
            {
            printf("catch塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try
            }

              請編譯運行一下,程序的運行結果如下:
              異常出現(xiàn)前

            catch_part(9, 10)塊,被執(zhí)行到
              捕獲到一個異常,錯誤原因是:出現(xiàn)某某異常! err_type:9 err_code:15

              與C++中的異常處理模型相似,它這里的對異常的分類處理不僅支持一維線性的;同樣,它也支持分層的,也即在當前的try catch塊中找不到相應的catch block,那么它將會到上一層的try catch塊中繼續(xù)尋找。演示代碼如下:

            #include "ceh.h"

            int main(void)
            {
            try
            {
            try
            {
            throw(1, 15, "嵌套在try塊中");
            }
            catch_part(4, 6)
            {
            printf("catch_part(4, 6)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try

            printf("這里將不會被執(zhí)行到 ");
            }
            catch_part(2, 3)
            {
            printf("catch_part(2, 3)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            // 找到了對應的catch block
            catch_one(1)
            {
            printf("catch_one(1)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            catch
            {
            printf("catch塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try

            }

              到目前為止,大家是不是已經(jīng)覺得,這個主人公阿愚封裝的在C語言環(huán)境中異常處理框架,已經(jīng)與C++中的異常處理模型95%相似。無論是它的語法結構;還是所完成的功能;以及它使用上的靈活性等。下面我們來看一個各種情況綜合的例子吧!代碼如下:

            #include "ceh.h"

            void test1()
            {
            throw(0, 20, "hahaha");
            }

            void test()
            {
            test1();
            }

            int main(void)
            {
            try
            {
            test();
            }
            catch
            {
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try

            try
            {
            try
            {
            throw(1, 15, "嵌套在try塊中");
            }
            catch
            {
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try

            throw(2, 30, "再拋一個異常");
            }
            catch
            {
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);

            try
            {
            throw(0, 20, "嵌套在catch塊中");
            }
            catch
            {
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            end_try
            }
            end_try
            }

              請編譯運行一下,程序的運行結果如下:
              捕獲到一個異常,錯誤原因是:hahaha! err_type:0 err_code:20
              捕獲到一個異常,錯誤原因是:嵌套在try塊中! err_type:1 err_code:15
              捕獲到一個異常,錯誤原因是:再拋一個異常! err_type:2 err_code:30
              捕獲到一個異常,錯誤原因是:嵌套在catch塊中! err_type:0 err_code:20

              最后,為了體會到這個異常處理框架,更進一步與C++中的異常處理模型相似。那就是它還支持異常的重新拋出,以及系統(tǒng)中能捕獲并處理程序中沒有catch到的異常。看代碼吧!如下:

            #include "ceh.h"

            void test1()
            {
            throw(0, 20, "hahaha");
            }

            void test()
            {
            test1();
            }

            int main(void)
            {
            // 這里表示程序中將捕獲浮點數(shù)計算異常
            CEH_init();

            try
            {
            try
            {
            try
            {
            double i,j;
            j = 0;
            // 這里出現(xiàn)浮點數(shù)計算異常
            i = 1/j ;

            test();

            throw(9, 15, "出現(xiàn)某某異常");
            }
            end_try
            }
            catch_part(4, 6)
            {
            printf("catch_part(4, 6)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            catch_part(2, 3)
            {
            printf("catch_part(2, 3)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
            }
            // 捕獲到上面的異常
            catch
            {
            printf("內層的catch塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);

            // 這里再次把上面的異常重新拋出
            rethrow;

            printf("這里將不會被執(zhí)行到 ");
            }
            end_try
            }
            catch_part(7, 9)
            {
            printf("catch_part(7, 9)塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);

            throw(2, 15, "出現(xiàn)某某異常");
            }
            // 再次捕獲到上面的異常
            catch
            {
            printf("外層的catch塊,被執(zhí)行到 ");
            printf("捕獲到一個異常,錯誤原因是:%s! err_type:%d err_code:%d ",
            ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);

            // 最后又拋出了一個異常,
            // 但是這個異常沒有對應的catch block處理,所以系統(tǒng)中處理了
            throw(2, 15, "出現(xiàn)某某異常");
            }
            end_try
            }

              請編譯運行一下,程序的運行結果如下:
              內層的catch塊,被執(zhí)行到
              捕獲到一個異常,錯誤原因是:Divide by zero! err_type:-1 err_code:131
              外層的catch塊,被執(zhí)行到
              捕獲到一個異常,錯誤原因是:Divide by zero! err_type:-1 err_code:131
              捕獲到一個未處理的異常,錯誤原因是:出現(xiàn)某某異常! err_type:2 err_code:15
              程序終止!
            狠狠色丁香婷婷久久综合不卡| 久久人人妻人人爽人人爽| 国产99久久久久久免费看| www亚洲欲色成人久久精品| 国产免费久久精品丫丫| 久久综合九色综合网站| www久久久天天com| 久久九九免费高清视频| 亚洲AV无码久久| 久久精品国产精品亚洲| 日产精品久久久久久久性色| 国产精品日韩深夜福利久久| 久久精品国产2020| 国产成人99久久亚洲综合精品| 日韩十八禁一区二区久久| a高清免费毛片久久| 久久综合久久综合亚洲| 伊人久久综合热线大杳蕉下载| 久久久久久国产a免费观看黄色大片| 97精品久久天干天天天按摩| 久久天天躁夜夜躁狠狠| 国产三级观看久久| 韩国免费A级毛片久久| 一本久久知道综合久久| 久久亚洲欧洲国产综合| 中文字幕成人精品久久不卡| 久久午夜羞羞影院免费观看| 国产成人综合久久精品红| 久久综合伊人77777麻豆| 99久久亚洲综合精品成人| 国产成年无码久久久久毛片| 伊人久久大香线蕉综合Av| 一本色道久久HEZYO无码| 精品久久久无码人妻中文字幕豆芽| 日本三级久久网| 久久99久久99小草精品免视看| 99久久精品国产一区二区| 77777亚洲午夜久久多喷| 久久久久精品国产亚洲AV无码| 中文字幕久久亚洲一区| 色综合久久夜色精品国产|