青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Beginning to 編程

VC++ 方面編程文章

 

2006年7月16日

Windows GDI CDC 使用問題

最近在學習Hoops?? 的引擎(http://www.hoops3d.com )

模擬它的MVO架構,不過沒有原代碼,所以很難a
設計了一個交互繪圖基本類,
但是還有錯誤,鼠標左鍵點擊兩下
?winGDI.cpp中出錯。
請大蝦指教一二。
我已經在這個問題上花了很多的心思。
其中最重要的就是Painter抽象類的設計
他的子類QBufferDC繼承CDC
而SGView包含Painter指針,方便在SGView ::drawEntity調用。



SGObject - 對象的抽象類,也就是幾何對象
SGModel- 負責對象管理,沒有實現所有的功能,準備用SceneTree來實現
SGView - 負責顯示SGModel中的數據,關鍵的函數
void SGView::drawEntity(SGObject* pObj)
{
???pObj->draw(m_pPainter,this)
}

Painter - 封裝CDC的功能,見代碼

在CSGView創建的時候創建Painter對象
很可能這里有問題!!!!!
void CSGView::OnCreate(..)
{
?????CDC*?pDC =?GetDC();
???Painter* painter = new QBufferDC(pDC);
???m_pSGView->setPainter(painter);
}


MFC 相關的Document/View架構
CSGDocument - 管理SGModel

CSGView - 和SGView建立聯系,并負責把windows的消息發送給SGView
見原代碼

SGActionManager - 負責工具的管理
SGBaseAction - 工具的抽象基類
SGActionDrawLine - 繪制直線的工具



源代碼連接:
http://www.shnenglu.com/Files/richardzeng/MVOTest.rar

posted @ 2006-07-16 03:06 Beginning to 編程 閱讀(1527) | 評論 (2)編輯 收藏

2006年5月27日

資源和資源管理類的設計問題


我要設計的應用程序其中的一個模塊就是封裝 windows GDI中的畫筆,畫刷等GDI object
把GDI object 再封裝成resource,以實現多種樣式多線條的畫筆及畫刷資源

畫筆,畫刷等資源繼承resource
為了避免發生資源泄露和resource的管理
設計ResourceManager類,負責資源的創建,加載和卸載以及刪除

兩個抽象類 Resource 和 ResourceManager
兩個具體類 ConcreateResource 和 ConcreateResourceManager
分別派生于上面的抽象類

以上設計是看了 OGRE 游戲引擎的資源管理部分,
對它的資源管理類ResourceManager不是很理解

resource 派生了pen,brush等類
pen類可以來自文件,也可以自己創建SubPen 添加到SubPenList中

ResourceManager 負責創建資源Resource
1. 如果我在抽象的 ResourceManager 聲明 createRes函數,并返回基類resource
勢必會要強制轉換,然后在用到具體的Resource時候又要轉換回來

2. 如果我在具體類 ConcreateResourceManager 聲明 createConcreateRes函數
那么就白費了我應用設計模式設計這么多類


// abstract class for resource
class Resource{
public:
?// standard constructor
? Resource(const string& name, const string& group)
?:mName(name),mGroup(group){}
? ~Resource(){}
protected:
?// prevent default construct
? Resource():mName(""),mGroup(""){}
? string mName;
? string mGroup;
? static unsigned long mHandle;
};

// subclass of resource
// concreateResource such as PEN
class Pen:
?public Resource{
?Pen(const string& name, const string& group)
??:Resource(name,group){}
??~Pen(){}

? void loadfromFile(string& filename);

// add?into vector
? void addSubPen(SubPen* sub){
???? mSubPenList.push_back(sub);
}
public:
typedef std::vector<SubPen> SubPenList;
SubPenList mSubPenList;

};
class
// abstract class for resource manager
class ResourceManager{
public:
? ResourceManager(){}
? ~ResourceManager(){}
public:
// here , I cannot understand OGRE degsin
? Resource* createRes(const string& name,const string& group);
?// resource map
 typedef std::map<string,Resource*> ResourceMap;
?? ResourceMap mResources;

};

// subclass ResourceManager
class ConcreateResourceManager
?:public ResourceManager
{
?ConcreateResourceManager(){}
?~ConcreateResourceManager(){}

????? // how can design here!!
?????? Pen* createPen(const string& name,const string& group){}
}

?

posted @ 2006-05-27 22:19 Beginning to 編程 閱讀(735) | 評論 (1)編輯 收藏

2006年5月15日

MFC 容器類對象的序列化問題

設計一個程序實現如何保存一系列的SPen(如下定義)對象到文件,或者稱為序列化SPen collection

SPenCollection::Load和 Save函數實現打開畫筆文件(文件的內容是一系列SPen對象)
// for example
?SPenCollection pc;
?pc.Load("C:\\1.pen");

我不知道如何序列化容器類對象,請大蝦指教。



// SPen object
class SPen : public CObject
{
?DECLARE_SERIAL(SPen)
public:
?SPen();
?virtual ~SPen();

public:
?int lineStyle;
?int lineWidth;
?COLORREF lineColor;
public:
?virtual void Serialize(CArchive& ar);
};


// SPen.cpp : 實現文件
//

#include "stdafx.h"
#include "ArchiveTest.h"
#include "SPen.h"


// SPen
IMPLEMENT_SERIAL(SPen,CObject,1)

SPen::SPen()
{
?lineStyle = PS_SOLID;
?lineWidth = 2;
?lineColor = RGB(255,0,0);
}

SPen::~SPen()
{
}


// SPen 成員函數

void SPen::Serialize(CArchive& ar)
{
?if (ar.IsStoring())
?{?// storing code
??ar<<lineStyle;
??ar<<lineWidth;
??ar<<lineColor;
?}
?else
?{?// loading code
??ar>>lineStyle;
??ar>>lineWidth;
??ar>>lineColor;
?}
}


///////////////////////////////////////
// 關鍵是要實現如何保存一系列的SPen對象
// load 和 save函數實現打開畫筆文件(文件的內容是一系列SPen對象)
// for example
/** SPenCollection pc;
???pc.Load("C:\\1.pen");
?**/

#pragma once

// SPenCollection 命令目標

#include "SPen.h"
#include <afxtempl.h>

class SPenCollection : public CObject
{
?DECLARE_SERIAL(SPenCollection)
public:
?SPenCollection();
?virtual ~SPenCollection();

?void AddPen(SPen* pen);

?void Load(CString strFileName);
?void Save(CString strFileName);

// CArray 不知道用得對不對,請大蝦指教
?CArray<SPen*,SPen*> pens;
};


?

posted @ 2006-05-15 22:14 Beginning to 編程 閱讀(1427) | 評論 (1)編輯 收藏

boost serialize 和 ostream 問題

下面是Boost serialization 中的demo例子
為何寫了serialize 函數還寫個ostream<<
阿,
我對ostream 不是很了解,
我的印象是iostream 是在控制臺里輸入輸出的
/////////////////////////////////////////////////////////////////////////////
class gps_position
{
??? friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
??? friend class boost::serialization::access;
??? int degrees;
??? int minutes;
??? float seconds;
??? template<class Archive>
??? void serialize(Archive & ar, const unsigned int /* file_version */){
??????? ar & degrees & minutes & seconds;
??? }
public:
??? // every serializable class needs a constructor
??? gps_position(){};
??? gps_position(int _d, int _m, float _s) :
??????? degrees(_d), minutes(_m), seconds(_s)
??? {}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
??? return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}

posted @ 2006-05-15 17:26 Beginning to 編程 閱讀(867) | 評論 (1)編輯 收藏

fatal error LNK1104: 無法打開文件“libboost_serialization-vc80-mt-gd-1_33_1.lib”

?最近想試試boost,下載了boost 1.33.1
我目前使用的是VC++2005,
首先編譯bjam, 不過用boost 1.33.1 \tools \jam-src 下的build.bat不用又從sf上下載了
最新的bjam,然后編譯bjam,倒是很簡單很快就好生成bjam.exe

然后把bjam的路徑設置到path 環境變量中
一切都運行正常。

我首先就編譯了boost -serialization

在命令行模式下
cd <boost-serialization 目錄>
運行bjam "-sTOOLS=vc-8_0"

編譯完成后在boost 目錄下生成了bin 目錄C:\boost_1_33_1\bin\
我編譯的serialization lib 文件在這里
C:\boost_1_33_1\bin\boost\libs\serialization\build\boost_serialization.dll\vc-8_0\debug\threading-multi,當然還有其它的lib,dll

首先設置vc++包含文件目錄C:\boost_1_33_1\
庫文件設置在C:\boost_1_33_1\bin\boost\libs\serialization\build\boost_serialization.dll\vc-8_0\debug\threading-multi,
(這個肯定不好,難道我需要一個lib文件就要在這里加一個路徑,因為編譯的lib文件太分散,沒有集中,不知道copy到一起是否可行)

然后我copy boost serialization 中demo代碼,
編譯demo.cpp,就提示 fatal error LNK1104: 無法打開文件“libboost_serialization-vc80-mt-gd-1_33_1.lib”

我想是不是lib文件的路徑不對阿,把要的libboost_serialization-vc80-mt-gd-1_33_1.lib 拷貝到C:\boost_1_33_1\libs
下還是不行,設置項目依賴文件也不行,
到底在vc++2005 中怎么設置boost的環境阿

posted @ 2006-05-15 10:54 Beginning to 編程 閱讀(10655) | 評論 (6)編輯 收藏

2006年5月10日

不能將“this”指針從“const Vector3D”轉換為“Vector3D &" 錯誤

我在VS2005中編譯Vector3D類出現
error C2662: “Vector3D::dotP”: 不能將“this”指針從“const Vector3D”轉換為“Vector3D &”

怎么樣改正呢,這個類也是看到別人這樣寫的,編譯也沒有錯誤。

#pragma once

#define M_PI 3.141
#include <math.h>

class Vector3D{
?Vector3D(){x=y=z=0.0;}
?Vector3D(double vx, double vy,double vz=0.0){
??x = vx;
??y = vy;
??z = vz;
?}
?
?double magnitude() const{
??return sqrt(x*x+y*y+z*z);
?}

?double dotP(const Vector3D& v1,const Vector3D& v2){
??return (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z);
?}

?// get the vector angle
?double angle() const{
??double ret = 0.0;
??double m = magnitude();

??if (m>1.0e-6) {

//?問題出在這里!!!!
// ==============================
???double dp = dotP(*this,Vector3D(1.0,0.0));
//==============================

???if (dp/m>=1.0) {
????ret = 0.0;
???}
???else if (dp/m<-1.0) {
????ret = M_PI;
???}
???else {
????ret = acos( dp / m);
???}
???if (y<0.0) {
????ret = 2*M_PI - ret;
???}
??}
??return ret;
?}


protected:
?double x;
?double y;
?double z;

};#pragma once

#define M_PI 3.141
#include <math.h>

class Vector3D{
?Vector3D(){x=y=z=0.0;}
?Vector3D(double vx, double vy,double vz=0.0){
??x = vx;
??y = vy;
??z = vz;
?}
?
?double magnitude() const{
??return sqrt(x*x+y*y+z*z);
?}

?double dotP(const Vector3D& v1,const Vector3D& v2){
??return (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z);
?}

?// get the vector angle
?double angle() const{
??double ret = 0.0;
??double m = magnitude();

??if (m>1.0e-6) {
???double dp = dotP(*this,Vector3D(1.0,0.0));

???if (dp/m>=1.0) {
????ret = 0.0;
???}
???else if (dp/m<-1.0) {
????ret = M_PI;
???}
???else {
????ret = acos( dp / m);
???}
???if (y<0.0) {
????ret = 2*M_PI - ret;
???}
??}
??return ret;
?}


protected:
?double x;
?double y;
?double z;

};

posted @ 2006-05-10 14:42 Beginning to 編程 閱讀(6474) | 評論 (2)編輯 收藏

2006年4月21日

C++中Singleton的實現[zhuan]


這些東西在網上都很多了,但是我覺得他們的使用都不符合我的要求,所以自己動手豐衣足食,寫一個自己能用的,夠用就好。
#include <iostream>
?
using namespace std;
?
//單件模板類
template<typename T> class Singleton
{
protected:
?
? static T* m_Instance;
?
? Singleton(){}
? virtual~Singleton(){}
?
public:
?
? //實例的獲得
? static T* Instance()
? {
??? if(m_Instance==0)
????? m_Instance=new T;
?
??? return m_Instance;
? }
?
? //單件類的釋放
? virtual void Release()
? {
??? if(m_Instance!=0)
??? {
????? delete m_Instance;
????? m_Instance=0;
??? }
? }
};
?
//單件模板測試類
class Test:public Singleton<Test>
{
? friend class Singleton<Test>; //聲明為友員,不然會出錯
protected:
? Test()
? {
??? a=b=c=0;
? }
? virtual ~Test(){}
?
public :
?
? int a;
? int b;
? int c;
};
?
//初始化靜態成員。。。
template<> Test*Singleton<Test>::m_Instance=0;
?
?
//以下為測試代碼
void main()
{
? Test*t=Test::Instance();
?
? t->a=5;
? t->b=25;
? t->c=35;
? cout<<"t: a="<<t->a<<" b="<<t->b<<" c="<<t->c<<endl;
?
? Test*t2;
? t2=Test::Instance();
? cout<<"t2 a="<<t2->a<<" b="<<t2->b<<" c="<<t2->c<<endl;
?
? t2->Release();
}

posted @ 2006-04-21 09:31 Beginning to 編程 閱讀(390) | 評論 (0)編輯 收藏

2006年3月24日

EffectiveC++2ed 關于函數返回對象,引用還是指針

我看到EffectiveC++2ed中函數返回對象中的說明感覺以后再也不想讓返回任何東西啦。比較怕。

但是有的時候不返回任何東西是不行的阿。

返回引用,返回指針,返回對象到底怎么寫?!

——————————————————————————————
下面是EC中的內容

條款23: 必須返回一個對象時不要試圖返回一個引用

據說愛因斯坦曾提出過這樣的建議:盡可能地讓事情簡單,但不要過于簡單。在c++語言中相似的說法應該是:盡可能地使程序高效,但不要過于高效。

一旦程序員抓住了“傳值”在效率上的把柄(參見條款22),他們會變得十分極端,恨不得挖出每一個隱藏在程序中的傳值操作。豈不知,在他們不懈地追求純粹的“傳引用”的過程中,他們會不可避免地犯另一個嚴重的錯誤:傳遞一個并不存在的對象的引用。這就不是好事了。

看一個表示有理數的類,其中包含一個友元函數,用于兩個有理數相乘:

class rational {
public:
? rational(int numerator = 0, int denominator = 1);

? ...

private:
? int n, d;????????????? // 分子和分母

friend
? const rational????????????????????? // 參見條款21:為什么
??? operator*(const rational& lhs,??? // 返回值是const
????????????? const rational& rhs)????
};

inline const rational operator*(const rational& lhs,
??????????????????????????????? const rational& rhs)
{
? return rational(lhs.n * rhs.n, lhs.d * rhs.d);
}

很明顯,這個版本的operator*是通過傳值返回對象結果,如果不去考慮對象構造和析構時的開銷,你就是在逃避作為一個程序員的責任。另外一件很明顯的事實是,除非確實有必要,否則誰都不愿意承擔這樣一個臨時對象的開銷。那么,問題就歸結于:確實有必要嗎?

答案是,如果能返回一個引用,當然就沒有必要。但請記住,引用只是一個名字,一個其它某個已經存在的對象的名字。無論何時看到一個引用的聲明,就要立即問自己:它的另一個名字是什么呢?因為它必然還有另外一個什么名字(見條款m1)。拿operator*來說,如果函數要返回一個引用,那它返回的必須是其它某個已經存在的rational對象的引用,這個對象包含了兩個對象相乘的結果。

但,期望在調用operator*之前有這樣一個對象存在是沒道理的。也就是說,如果有下面的代碼:

rational a(1, 2);??????????????? // a = 1/2
rational b(3, 5);??????????????? // b = 3/5
rational c = a * b;????????????? // c 為 3/10

期望已經存在一個值為3/10的有理數是不現實的。如果operator* 一定要返回這樣一個數的引用,就必須自己創建這個數的對象。

一個函數只能有兩種方法創建一個新對象:在堆棧里或在堆上。在堆棧里創建對象時伴隨著一個局部變量的定義,采用這種方法,就要這樣寫operator*:

// 寫此函數的第一個錯誤方法
inline const rational& operator*(const rational& lhs,
???????????????????????????????? const rational& rhs)
{
? rational result(lhs.n * rhs.n, lhs.d * rhs.d);
? return result;
}

這個方法應該被否決,因為我們的目標是避免構造函數被調用,但result必須要象其它對象一樣被構造。另外,這個函數還有另外一個更嚴重的問題,它返回的是一個局部對象的引用,關于這個錯誤,條款31進行了深入的討論。

那么,在堆上創建一個對象然后返回它的引用呢?基于堆的對象是通過使用new產生的,所以應該這樣寫operator*:

// 寫此函數的第二個錯誤方法
inline const rational& operator*(const rational& lhs,
???????????????????????????????? const rational& rhs)
{
? rational *result =
??? new rational(lhs.n * rhs.n, lhs.d * rhs.d);
? return *result;
}

首先,你還是得負擔構造函數調用的開銷,因為new分配的內存是通過調用一個適當的構造函數來初始化的(見條款5和m8)。另外,還有一個問題:誰將負責用delete來刪除掉new生成的對象呢?

實際上,這絕對是一個內存泄漏。即使可以說服operator*的調用者去取函數返回值地址,然后用delete去刪除它(絕對不可能——條款31展示了這樣的代碼會是什么樣的),但一些復雜的表達式會產生沒有名字的臨時值,程序員是不可能得到的。例如:

rational w, x, y, z;

w = x * y * z;

兩個對operator*的調用都產生了沒有名字的臨時值,程序員無法看到,因而無法刪除。(再次參見條款31)

也許,你會想你比一般的熊——或一般的程序員——要聰明;也許,你注意到在堆棧和堆上創建對象的方法避免不了對構造函數的調用;也許,你想起了我們最初的目標是為了避免這種對構造函數的調用;也許,你有個辦法可以只用一個構造函數來搞掂一切;也許,你的眼前出現了這樣一段代碼:operator*返回一個“在函數內部定義的靜態rational對象”的引用:

// 寫此函數的第三個錯誤方法
inline const rational& operator*(const rational& lhs,
???????????????????????????????? const rational& rhs)
{
? static rational result;????? // 將要作為引用返回的
?????????????????????????????? // 靜態對象

? lhs和rhs 相乘,結果放進result;

? return result;
}

這個方法看起來好象有戲,雖然在實際實現上面的偽代碼時你會發現,不調用一個rational構造函數是不可能給出result的正確值的,而避免這樣的調用正是我們要談論的主題。就算你實現了上面的偽代碼,但,你再聰明也不能最終挽救這個不幸的設計。

想知道為什么,看看下面這段寫得很合理的用戶代碼:

bool operator==(const rational& lhs,????? // rationals的operator==
??????????????? const rational& rhs);???? //

rational a, b, c, d;

...

if ((a * b) == (c * d)) {

? 處理相等的情況;

} else {

? 處理不相等的情況;

}

看出來了嗎?((a*b) == (c*d)) 會永遠為true,不管a,b,c和d是什么值!

用等價的函數形式重寫上面的相等判斷語句就很容易明白發生這一可惡行為的原因了:

if (operator==(operator*(a, b), operator*(c, d)))

注意當operator==被調用時,總有兩個operator*剛被調用,每個調用返回operator*內部的靜態rational對象的引用。于是,上面的語句實際上是請求operator==對“operator*內部的靜態rational對象的值”和“operator*內部的靜態rational對象的值”進行比較,這樣的比較不相等才怪呢!

幸運的話,我以上的說明應該足以說服你:想“在象operator*這樣的函數里返回一個引用”實際上是在浪費時間。但我沒幼稚到會相信幸運總會光臨自己。一些人——你們知道這些人是指誰——此刻會在想,“唔,上面那個方法,如果一個靜態變量不夠用,也許可以用一個靜態數組……”

請就此打住!我們難道還沒受夠嗎?

我不能讓自己寫一段示例代碼來太高這個設計,因為即使只抱有上面這種想法都足以令人感到羞愧。首先,你必須選擇一個n,指定數組的大小。如果n太小,就會沒地方儲存函數返回值,這和我們前面否定的那個“采用單個靜態變量的設計”相比沒有什么改進。如果n太大,就會降低程序的性能,因為函數第一次被調用時數組中每個對象都要被創建。這會帶來n個構造函數和n個析構函數的開銷,即使這個函數只被調用一次。如果說"optimization"(最優化)是指提高軟件的性能的過程, 那么現在這種做法簡直可以稱為"pessimization"(最差化)。最后,想想怎么把需要的值放到數組的對象中以及需要多大的開銷?在對象間傳值的最直接的方法是通過賦值,但賦值的開銷又有多大呢?一般來說,它相當于調用一個析構函數(摧毀舊值)再加上調用一個構造函數(拷貝新值)。但我們現在的目標正是為了避免構造和析構的開銷啊!面對現實吧:這個方法也絕對不能選用。

所以,寫一個必須返回一個新對象的函數的正確方法就是讓這個函數返回一個新對象。對于rational的operator*來說,這意味著要不就是下面的代碼(就是最初看到的那段代碼),要不就是本質上和它等價的代碼:

inline const rational operator*(const rational& lhs,
??????????????????????????????? const rational& rhs)
{
? return rational(lhs.n * rhs.n, lhs.d * rhs.d);
}

的確,這會導致“operator*的返回值構造和析構時帶來的開銷”,但歸根結底它只是用小的代價換來正確的程序運行行為而已。況且,你所擔心的開銷還有可能永遠不會出現:和所有程序設計語言一樣,c++允許編譯器的設計者采用一些優化措施來提高所生成的代碼的性能,所以,在有些場合,operator*的返回值會被安全地除去(見條款m20)。當編譯器采用了這種優化時(當前大部分編譯器這么做),程序和以前一樣繼續工作,只不過是運行速度比你預計的要快而已。

以上討論可以歸結為:當需要在返回引用和返回對象間做決定時,你的職責是選擇可以完成正確功能的那個。至于怎么讓這個選擇所產生的代價盡可能的小,那是編譯器的生產商去想的事。

posted @ 2006-03-24 15:51 Beginning to 編程 閱讀(2958) | 評論 (0)編輯 收藏

2006年3月23日

Doxygen 源代碼文檔自動生成器的使用筆記

     摘要: 在 google 上搜了很久的關于 Doxygen 使用方法的咚咚,只不過都是英文,而且都很多的規則。實際上大家只需要告訴基本的規則就可以。下面是我對 Doxygen 的摸索 ? 首先熟知 Do...  閱讀全文

posted @ 2006-03-23 22:32 Beginning to 編程 閱讀(18269) | 評論 (4)編輯 收藏

2006年3月20日

查錯:下面的程序編譯沒問題,為什么運行會出錯呢

最近在看吉林大學的C程序設計的課件,有一章講到這個函數動手寫了一下。

題目:
編寫一個Insert函數實現在字符串s中的第i個位置插入字符串s1;
在VC++2005中編譯這段程序沒有任何的Error和warning但是運行就會錯誤,不知道為什么阿,請高手指點一二。

#include "stdafx.h"

#include <iostream>
using namespace std;

void Insert(char *s, char *s1, int i)
{
?char *p,*q;
?p = s + strlen(s); // p?指向s的末尾+1
?q = p + strlen(s1);?//q 指向新構造的字符串的\0?
?*q = '\0';

?//?
?for(p--,q--;p>=s+i-1;)
?{
??*(p--) = *(q--);
?}

?//
?for(p=s+i-1;*s1;)
?{
??*(p++) = *(s1++);
?}
}


int _tmain(int argc, _TCHAR* argv[])
{

?char *s = "Student";
?char *s1 = "Teacher";

?Insert(s,s1,3);

// 期待的輸出是StuTeacherdent;
?cout<<s;


?return 0;
}


// 還有我如果把insert函數改成下面的應該也是可以的吧

void Insert2(char *s, char *s1, int i)
{
?char *p,*q;
?p = s + strlen(s); // p?指向s的末尾+1
?q = p + strlen(s1);?//q 指向新構造的字符串的\0?
?*q = '\0';

?//?
?for(p--,q--;p>=s+i-1;)
?{
??*p-- = *q--;
?}

?//
?for(p=s+i-1;*s1;)
?{
??*p++ = *s1++;
?}
}

posted @ 2006-03-20 21:32 Beginning to 編程 閱讀(1230) | 評論 (3)編輯 收藏

僅列出標題  下一頁

導航

統計

常用鏈接

留言簿(4)

隨筆分類

隨筆檔案

文章檔案

相冊

BlogDev

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久av网站| 亚洲国产精品一区制服丝袜| 久久深夜福利| 欧美日韩八区| 欧美成人一区二区三区| 国产精品乱码久久久久久| 欧美风情在线观看| 国产日韩欧美电影在线观看| 最新国产乱人伦偷精品免费网站| 国产精品自在在线| 一本色道久久综合亚洲精品小说| 亚洲高清不卡在线| 性欧美办公室18xxxxhd| 亚洲欧美日韩一区在线| 欧美日本亚洲| 美女国产一区| 国产资源精品在线观看| 在线视频精品| 亚洲视频999| 欧美日韩成人激情| 欧美xart系列高清| 在线欧美日韩精品| 久久aⅴ国产欧美74aaa| 久久久精品网| 国产综合色一区二区三区| 亚洲免费人成在线视频观看| 亚洲一区二区三区在线看| 欧美精品一区三区| 亚洲清纯自拍| 亚洲丝袜av一区| 欧美日韩国产经典色站一区二区三区| 欧美激情精品久久久久久黑人 | 久久久免费精品| 国产欧美综合一区二区三区| 亚洲在线视频观看| 欧美一区二粉嫩精品国产一线天| 国产精品女主播| 亚洲综合欧美日韩| 久久精品视频在线看| 国产亚洲福利| 久久人人97超碰国产公开结果| 久久另类ts人妖一区二区| 狠狠色噜噜狠狠狠狠色吗综合| 午夜一级久久| 免费看亚洲片| 日韩一级精品视频在线观看| 欧美三级视频| 午夜国产精品影院在线观看| 久久久国产精品一区二区中文 | 国产精品亚洲激情 | 亚洲一级高清| 久久gogo国模啪啪人体图| 激情视频一区二区三区| 久久尤物电影视频在线观看| 亚洲国产裸拍裸体视频在线观看乱了中文| 亚洲精品乱码久久久久久日本蜜臀| 欧美高清视频一区二区三区在线观看| 亚洲精品免费网站| 午夜伦理片一区| 在线免费观看一区二区三区| 欧美精品一区二区三区在线播放| 一区二区欧美日韩视频| 久久久亚洲综合| 99在线精品免费视频九九视| 国产精品日韩久久久久| 麻豆91精品91久久久的内涵| 这里只有精品丝袜| 免费人成精品欧美精品| 亚洲午夜电影网| 亚洲第一在线综合在线| 国产精品xxxxx| 久久在线精品| 亚洲已满18点击进入久久| 欧美国产高清| 久久成人精品无人区| 亚洲三级视频| 国产真实乱偷精品视频免| 欧美成人亚洲成人| 久久se精品一区精品二区| 亚洲日本免费| 免费久久99精品国产自| 欧美一级片一区| 日韩视频中文| 伊人久久综合97精品| 国产精品老牛| 欧美日本在线播放| 狼狼综合久久久久综合网| 午夜精品久久久久久99热| 亚洲九九爱视频| 欧美成人精品| 久久久综合激的五月天| 性色av一区二区三区在线观看| 亚洲精品偷拍| 尤物yw午夜国产精品视频明星| 国产精品乱码一区二区三区| 欧美精品在线一区| 欧美成人精品h版在线观看| 久久精品官网| 欧美一区二区视频97| 亚洲制服少妇| 亚洲午夜激情网页| aa日韩免费精品视频一| 亚洲国产欧美精品| 欧美激情一区三区| 欧美不卡福利| 欧美v亚洲v综合ⅴ国产v| 久久视频这里只有精品| 久久精品国产一区二区三区| 欧美伊久线香蕉线新在线| 亚洲一区制服诱惑| 亚洲综合第一| 午夜精品电影| 亚洲午夜久久久久久久久电影网| 9i看片成人免费高清| 亚洲裸体视频| 在线亚洲免费视频| 中文欧美字幕免费| 这里只有视频精品| 亚洲视频在线一区观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 日韩一级裸体免费视频| 亚洲视频国产视频| 亚洲字幕在线观看| 欧美在线|欧美| 久久亚洲综合色一区二区三区| 久久视频这里只有精品| 免费在线观看日韩欧美| 亚洲国产裸拍裸体视频在线观看乱了 | 日韩午夜av| 亚洲一区二区少妇| 欧美一级久久| 久久一区二区三区四区五区| 猛男gaygay欧美视频| 欧美麻豆久久久久久中文| 欧美午夜宅男影院| 国产午夜精品理论片a级探花| 国模精品一区二区三区| 亚洲黄色一区| 亚洲一区在线播放| 久久这里有精品视频| 欧美大片在线看免费观看| 亚洲九九九在线观看| 性高湖久久久久久久久| 蜜乳av另类精品一区二区| 欧美日韩一区在线观看| 国产午夜精品麻豆| 亚洲巨乳在线| 欧美呦呦网站| 亚洲国产精品99久久久久久久久| 一本一本久久a久久精品牛牛影视| 欧美一级淫片播放口| 欧美激情亚洲自拍| 国产欧美日韩综合| 亚洲精品影院| 久久福利毛片| 亚洲国产婷婷| 性色av一区二区三区红粉影视| 美女尤物久久精品| 国产精品综合视频| 亚洲精品一区二区三区四区高清 | 久久久99精品免费观看不卡| 欧美国产三区| 午夜亚洲福利在线老司机| 欧美成人一区在线| 国产亚洲视频在线观看| 一区二区三区高清| 免费观看久久久4p| 亚洲男女毛片无遮挡| 欧美韩日精品| 影音先锋亚洲视频| 午夜精品福利一区二区三区av | 亚洲国产精品久久人人爱蜜臀 | 欧美一区二区女人| 欧美日韩午夜在线| 亚洲第一精品影视| 久久精品日产第一区二区| 99亚洲精品| 欧美激情欧美激情在线五月| 狠狠色2019综合网| 欧美一区二区三区四区高清| 日韩图片一区| 欧美精品啪啪| 亚洲精品免费在线播放| 欧美福利视频在线| 久久久久一本一区二区青青蜜月| 国产精品视频免费观看www| 亚洲小说春色综合另类电影| 亚洲人成人99网站| 欧美激情亚洲自拍| 亚洲免费观看高清完整版在线观看熊 | 欧美一区=区| 国产欧美日韩不卡| 欧美一区二区三区成人| 亚洲一区三区电影在线观看| 欧美性猛交一区二区三区精品| 日韩亚洲欧美高清| 亚洲国产欧美一区二区三区久久 | 美女网站在线免费欧美精品| 亚洲欧美日韩成人| 欧美大胆人体视频|