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

            若我的小家

            -編程,讀書,感悟,旅游,設(shè)計(jì)
            posts - 21, comments - 0, trackbacks - 0, articles - 0

            2008年12月14日

            灰度增強(qiáng)是一種在空域進(jìn)行的圖像增強(qiáng)方法。它是指將一定范圍的像素(l,h)線性映射到一個(gè)新的范圍(nl,nh)的操作。如果原來某個(gè)位置(x,y)的像素p(x,y)在(l,h)的范圍內(nèi)。那么,變換后的像素
            f(p(x,y))=(p(x,y)-l)*(nh-nl)/(h-l);

            使用gdi+對應(yīng)的處理代碼如下:

            void EnhanceImage_Linear(Bitmap *bmp, int oldLow,int oldHigh, int newLow,int newHigh)
            {
                ASSERT(bmp!=NULL);
                ASSERT(oldLow>=0
                    &&oldLow<=255);
                ASSERT(oldHigh>=0
                    &&oldHigh<=255);
                ASSERT(newLow>=0
                    &&newLow<=255);
                ASSERT(newHigh>=0
                    &&newHigh<=255);
                ASSERT(oldLow<oldHigh);
                ASSERT(newLow<newHigh);

                long width=bmp->GetWidth();
                long height=bmp->GetHeight();
               
                BitmapData bmpData;
                bmp->LockBits(&Rect(0,0,width,height), ImageLockModeRead|ImageLockModeWrite,PixelFormat24bppRGB ,&bmpData);
                unsigned char *pStart=(unsigned char *)(bmpData.Scan0);
                REAL oldDiff=oldHigh-oldLow;
                REAL newDiff=newHigh-newLow;
                REAL ratio=newDiff/oldDiff;
                for(int j=0;j<height;j++)
                {
                    for(int i=0;i<width;i++)
                    {
                        pStart+=j*bmpData.Stride+3*i;
                        for(int k=0;k<3;k++)
                        {
                            if(pStart[k]>=oldLow
                                &&pStart[k]<=oldHigh)
                            {
                                int data=((pStart[k]-oldLow)*ratio);
                                if(data>255)
                                {
                                    data=255;
                                }
                                pStart[k]=(unsigned char)data;
                            }
                        }
                    }
                }

                bmp->UnlockBits(&bmpData);
            }

            posted @ 2008-12-14 14:55 若我 閱讀(1386) | 評論 (0)編輯 收藏

            圖像增強(qiáng)技術(shù)是將圖像的部分信息按照一定的要求加以強(qiáng)化,使得其更適合于某種應(yīng)用要求。比如,我們可能覺得圖像的對比度太差,那么就可以將圖像的頻域中高頻信息加以強(qiáng)化,使得圖像的對比度更好;或者覺得圖像太過銳利了,那么可以增強(qiáng)圖像的低頻部分使得圖像得以平滑。
            圖像增強(qiáng)可以在頻域或者空域進(jìn)行。前者是只將圖像的空間一定位置的像素值pixel(x,y)按照一定的要求映射到另一個(gè)像素值f(pixel(x,y),這里的f就是我們的變換函數(shù)。后者(頻域增強(qiáng))是指對圖像進(jìn)行傅立葉變換等變換而獲取其像素變化的頻率信息,然后按照一定的要求將這些頻率信息處理以使之符合要求,然后將圖像變換回空間像素陣列。


            posted @ 2008-12-14 14:51 若我 閱讀(1768) | 評論 (0)編輯 收藏

            2008年10月27日

            第一階段
            此階段主要是能熟練地使用某種語言。這就相當(dāng)于練武中的套路和架式這些表面的東西。
            第二階段
            此階段能精通基于某種平臺的接口(例如我們現(xiàn)在常用的Win 32的API函數(shù))以及所對應(yīng)語言的自身的庫函數(shù)。到達(dá)這個(gè)階段后,也就相當(dāng)于可以進(jìn)行真實(shí)散打?qū)毩耍梢哉嬲卦趯?shí)踐中做些應(yīng)用。
            第三階段
            此階段能深入地了解某個(gè)平臺系統(tǒng)的底層,已經(jīng)具有了初級的內(nèi)功的能力,也就是“手中有劍,心中無劍”。
            第四階級
            此階段能直接在平臺上進(jìn)行比較深層次的開發(fā)。基本上,能達(dá)到這個(gè)層次就可以說是進(jìn)入了高層次。這時(shí)進(jìn)入了高級內(nèi)功的修煉。比如能進(jìn)行VxD或操作系統(tǒng)的內(nèi)核的修改。
            這時(shí)已經(jīng)不再有語言的束縛,語言只是一種工具,即使要用自己不會的語言進(jìn)行開發(fā),也只是簡單地熟悉一下,就手到擒來,完全不像是第一階段的時(shí)候?qū)W習(xí)語言的那種情況。一般來說,從第三階段過渡到第四階段是比較困難的。為什么會難呢?這就是因?yàn)楹芏嗳说乃枷胱儾贿^來。
            第五階級
            此階段就已經(jīng)不再局限于簡單的技術(shù)上的問題了,而是能從全局上把握和設(shè)計(jì)一個(gè)比較大的系統(tǒng)體系結(jié)構(gòu),從內(nèi)核到外層界面。可以說是“手中無劍,心中有劍”。到了這個(gè)階段以后,能對市面上的任何軟件進(jìn)行剖析,并能按自己的要求進(jìn)行設(shè)計(jì),就算是MS Word這樣的大型軟件,只要有充足的時(shí)間,也一定會設(shè)計(jì)出來。
            第六階級
            此階段也是最高的境界,達(dá)到“無招勝有招”。這時(shí)候,任何問題就純粹變成了一個(gè)思路的問題,不是用什么代碼就能表示的。也就是“手中無劍,心中也無劍”。
            此時(shí),對于練功的人來說,他已不用再去學(xué)什么少林拳,只是在旁看一下少林拳的對戰(zhàn),就能把此拳拿來就用。這就是真正的大師級的人物。這時(shí),Win 32或Linux在你眼里是沒有什么差別的。
            每一個(gè)階段再向上發(fā)展時(shí)都要按一定的方法。第一、第二個(gè)階段通過自學(xué)就可以完成,只要多用心去研究,耐心地去學(xué)習(xí)。
            要想從第二個(gè)階段過渡到第三個(gè)階段,就要有一個(gè)好的學(xué)習(xí)環(huán)境。例如有一個(gè)高手帶領(lǐng)或公司里有一個(gè)好的練手環(huán)境。經(jīng)過二、三年的積累就能達(dá)到第三個(gè)階段。但是,有些人到達(dá)第三個(gè)階段后,常常就很難有境界上的突破了。他們這時(shí)會產(chǎn)生一種觀念,認(rèn)為軟件無非如此,認(rèn)為自己已無所不能。其實(shí),這時(shí)如果遇到大的或難些的軟件,他們往往還是無從下手。
            現(xiàn)在我們國家大部分程序員都是在第二、三級之間。他們大多都是通過自學(xué)成才的,不過這樣的程序員一般在軟件公司也能獨(dú)當(dāng)一面,完成一些軟件的模塊。
            但是,也還有一

            posted @ 2008-10-27 13:29 若我 閱讀(898) | 評論 (0)編輯 收藏

            java方面的:
            it人資訊交流網(wǎng)
            http://www.it315.org
            這個(gè)網(wǎng)站是我最近才發(fā)現(xiàn)的,雖然內(nèi)容不多,但是提供的相關(guān)java工具挺齊全。還有就是里面提供了java教學(xué)視頻錄象的免費(fèi)下載,好像一兩周更換一段。個(gè)人覺得挺適合初學(xué)者的,尤其是那個(gè)classpath的設(shè)置,講的很透徹,大家有空可以看一看。

            java官方站點(diǎn)(英文)
            http://java.sun.com
            要想了解最新的java動態(tài),下載最新的java相關(guān),比如j2se、j2ee、j2se的最新jdk版本就來這里吧。

            java中文站
            http://www.java-cn.com
            這個(gè)可能大家都知道,不用說了,他提供的java資源是最豐富的。注冊論壇是免費(fèi)的,還送積分,用積分可以下載軟件和電子書等,如果積分用完了,就需要自己發(fā)表一些文章來賺新的積分。

            中文java網(wǎng)站
            http://www.cn-java.com
            跟上面站點(diǎn)類似的一個(gè)站,宗旨就是:為java愛好者服務(wù)。值得一看!

            鋒網(wǎng)
            http://www.ijsp.net/tech/book/index.jsp
            綜合性的java網(wǎng)站,內(nèi)含“下載中心”、“教程教學(xué)”等欄目。

            java動力
            http://eww.cn
            網(wǎng)站的內(nèi)容可以,但是最為出色的是它所運(yùn)用的flash技術(shù),我就不在這里多說了,大家去看看就知道了,一個(gè)字“酷”!!!

            vc方面的:
            vc知識庫
            http://www.vckbase.com
            這個(gè)網(wǎng)站就不用多說了,學(xué)習(xí)vc必去之地。網(wǎng)站專門提供了免費(fèi)的ftp下載,好東東巨多!

            vc之路
            http://www.vcroad.com
            綜合軟件開發(fā)網(wǎng)站,以vc為主。“資源中心”有許多值得下載的東東。

            visual c++/mfc開發(fā)指南
            http://www.vchelp.net
            以講述windows開發(fā)為主的站點(diǎn),提供了最新的源代碼,開發(fā)工具,開發(fā)資料,開發(fā)教程和對好的開發(fā)站點(diǎn),開發(fā)工具,圖書做介紹,同時(shí)為從事開發(fā)的朋友提供發(fā)布自己開發(fā)的軟件,代碼和工具場所。

            c維視點(diǎn)
            http://www.c-view.org/root/index.htm
            最近發(fā)現(xiàn)的vc好站,書籍、軟件、代碼下載一應(yīng)具全!!!


            游戲開發(fā):
            風(fēng)云工作室
            http://member.netease.com/~cloudwu/2000/index.html

            標(biāo)點(diǎn)游戲制作
            http://makegame.myetang.com/

            未來開發(fā)者
            http://www.fdev.net/


            綜合的:
            中國軟件網(wǎng)
            http://www.csdn.net
            中國最大的開發(fā)者網(wǎng)絡(luò),他之所以著名就是因?yàn)樗恼搲蠹矣锌湛梢匀タ纯矗芟碌胶芏嗖诲e(cuò)的東東,另外也是交流學(xué)習(xí)的好地方。

            電子書籍的:
            http://www.itebook.net

            最后公布一個(gè)巨好的,狂多的電子書下載
            http://www.pdown.net
            還有巨好的
            http://www.codestudy.net/default.asp

            我會不斷完善這個(gè)帖子,要是斑竹允許,請置頂

            posted @ 2008-10-27 13:28 若我 閱讀(490) | 評論 (0)編輯 收藏

            (一)深入淺出理解索引結(jié)構(gòu)

            實(shí)際上,您可以把索引理解為一種特殊的目錄。微軟的SQL SERVER提供了兩種索引:聚集索引(clustered index,也稱聚類索引、簇集索引)和非聚集索引(nonclustered index,也稱非聚類索引、非簇集索引)。下面,我們舉例來說明一下聚集索引和非聚集索引的區(qū)別:

            其實(shí),我們的漢語字典的正文本身就是一個(gè)聚集索引。比如,我們要查“安”字,就會很自然地翻開字典的前幾頁,因?yàn)?#8220;安”的拼音是“an”,而按照拼音排序漢字的字典是以英文字母“a”開頭并以“z”結(jié)尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”開頭的部分仍然找不到這個(gè)字,那么就說明您的字典中沒有這個(gè)字;同樣的,如果查“張”字,那您也會將您的字典翻到最后部分,因?yàn)?#8220;張”的拼音是“zhang”。也就是說,字典的正文部分本身就是一個(gè)目錄,您不需要再去查其他目錄來找到您需要找的內(nèi)容。

            我們把這種正文內(nèi)容本身就是一種按照一定規(guī)則排列的目錄稱為“聚集索引”。

            如果您認(rèn)識某個(gè)字,您可以快速地從自動中查到這個(gè)字。但您也可能會遇到您不認(rèn)識的字,不知道它的發(fā)音,這時(shí)候,您就不能按照剛才的方法找到您要查的字,而需要去根據(jù)“偏旁部首”查到您要找的字,然后根據(jù)這個(gè)字后的頁碼直接翻到某頁來找到您要找的字。但您結(jié)合“部首目錄”和“檢字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“張”字,我們可以看到在查部首之后的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“馳”字,但頁碼卻是63頁,“張”的下面是“弩”字,頁面是390頁。很顯然,這些字并不是真正的分別位于“張”字的上下方,現(xiàn)在您看到的連續(xù)的“馳、張、弩”三字實(shí)際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個(gè)過程,先找到目錄中的結(jié)果,然后再翻到您所需要的頁碼。

            我們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱為“非聚集索引”。

            通過以上例子,我們可以理解到什么是“聚集索引”和“非聚集索引”。

            進(jìn)一步引申一下,我們可以很容易的理解:每個(gè)表只能有一個(gè)聚集索引,因?yàn)槟夸浿荒馨凑找环N方法進(jìn)行排序。

            (二)何時(shí)使用聚集索引或非聚集索引

            下面的表總結(jié)了何時(shí)使用聚集索引或非聚集索引(很重要)。

            動作描述
            使用聚集索引
            使用非聚集索引

            列經(jīng)常被分組排序
            應(yīng)
            應(yīng)

            返回某范圍內(nèi)的數(shù)據(jù)
            應(yīng)
            不應(yīng)

            一個(gè)或極少不同值
            不應(yīng)
            不應(yīng)

            小數(shù)目的不同值
            應(yīng)
            不應(yīng)

            大數(shù)目的不同值
            不應(yīng)
            應(yīng)

            頻繁更新的列
            不應(yīng)
            應(yīng)

            外鍵列
            應(yīng)
            應(yīng)

            主鍵列
            應(yīng)
            應(yīng)

            頻繁修改索引列
            不應(yīng)
            應(yīng)


            事實(shí)上,我們可以通過前面聚集索引和非聚集索引的定義的例子來理解上表。如:返回某范圍內(nèi)的數(shù)據(jù)一項(xiàng)。比如您的某個(gè)表有一個(gè)時(shí)間列,恰好您把聚合索引建立在了該列,這時(shí)您查詢2004年1月1日至2004年10月1日之間的全部數(shù)據(jù)時(shí),這個(gè)速度就將是很快的,因?yàn)槟倪@本字典正文是按日期進(jìn)行排序的,聚類索引只需要找到要檢索的所有數(shù)據(jù)中的開頭和結(jié)尾數(shù)據(jù)即可;而不像非聚集索引,必須先查到目錄中查到每一項(xiàng)數(shù)據(jù)對應(yīng)的頁碼,然后再根據(jù)頁碼查到具體內(nèi)容。

            (三)結(jié)合實(shí)際,談索引使用的誤區(qū)

            理論的目的是應(yīng)用。雖然我們剛才列出了何時(shí)應(yīng)使用聚集索引或非聚集索引,但在實(shí)踐中以上規(guī)則卻很容易被忽視或不能根據(jù)實(shí)際情況進(jìn)行綜合分析。下面我們將根據(jù)在實(shí)踐中遇到的實(shí)際問題來談一下索引使用的誤區(qū),以便于大家掌握索引建立的方法。

            1、主鍵就是聚集索引

            這種想法筆者認(rèn)為是極端錯(cuò)誤的,是對聚集索引的一種浪費(fèi)。雖然SQL SERVER默認(rèn)是在主鍵上建立聚集索引的。

            通常,我們會在每個(gè)表中都建立一個(gè)ID列,以區(qū)分每條數(shù)據(jù),并且這個(gè)ID列是自動增大的,步長一般為1。我們的這個(gè)辦公自動化的實(shí)例中的列Gid就是如此。此時(shí),如果我們將這個(gè)列設(shè)為主鍵,SQL SERVER會將此列默認(rèn)為聚集索引。這樣做有好處,就是可以讓您的數(shù)據(jù)在數(shù)據(jù)庫中按照ID進(jìn)行物理排序,但筆者認(rèn)為這樣做意義不大。

            顯而易見,聚集索引的優(yōu)勢是很明顯的,而每個(gè)表中只能有一個(gè)聚集索引的規(guī)則,這使得聚集索引變得更加珍貴。

            從我們前面談到的聚集索引的定義我們可以看出,使用聚集索引的最大好處就是能夠根據(jù)查詢要求,迅速縮小查詢范圍,避免全表掃描。在實(shí)際應(yīng)用中,因?yàn)镮D號是自動生成的,我們并不知道每條記錄的ID號,所以我們很難在實(shí)踐中用ID號來進(jìn)行查詢。這就使讓ID號這個(gè)主鍵作為聚集索引成為一種資源浪費(fèi)。其次,讓每個(gè)ID號都不同的字段作為聚集索引也不符合“大數(shù)目的不同值情況下不應(yīng)建立聚合索引”規(guī)則;當(dāng)然,這種情況只是針對用戶經(jīng)常修改記錄內(nèi)容,特別是索引項(xiàng)的時(shí)候會負(fù)作用,但對于查詢速度并沒有影響。

            在辦公自動化系統(tǒng)中,無論是系統(tǒng)首頁顯示的需要用戶簽收的文件、會議還是用戶進(jìn)行文件查詢等任何情況下進(jìn)行數(shù)據(jù)查詢都離不開字段的是“日期”還有用戶本身的“用戶名”。

            通常,辦公自動化的首頁會顯示每個(gè)用戶尚未簽收的文件或會議。雖然我們的where語句可以僅僅限制當(dāng)前用戶尚未簽收的情況,但如果您的系統(tǒng)已建立了很長時(shí)間,并且數(shù)據(jù)量很大,那么,每次每個(gè)用戶打開首頁的時(shí)候都進(jìn)行一次全表掃描,這樣做意義是不大的,絕大多數(shù)的用戶1個(gè)月前的文件都已經(jīng)瀏覽過了,這樣做只能徒增數(shù)據(jù)庫的開銷而已。事實(shí)上,我們完全可以讓用戶打開系統(tǒng)首頁時(shí),數(shù)據(jù)庫僅僅查詢這個(gè)用戶近3個(gè)月來未閱覽的文件,通過“日期”這個(gè)字段來限制表掃描,提高查詢速度。如果您的辦公自動化系統(tǒng)已經(jīng)建立的2年,那么您的首頁顯示速度理論上將是原來速度8倍,甚至更快。

            在這里之所以提到“理論上”三字,是因?yàn)槿绻木奂饕€是盲目地建在ID這個(gè)主鍵上時(shí),您的查詢速度是沒有這么高的,即使您在“日期”這個(gè)字段上建立的索引(非聚合索引)。下面我們就來看一下在1000萬條數(shù)據(jù)量的情況下各種查詢的速度表現(xiàn)(3個(gè)月內(nèi)的數(shù)據(jù)為25萬條):

            (1)僅在主鍵上建立聚集索引,并且不劃分時(shí)間段:

            Select gid,fariqi,neibuyonghu,title from tgongwen

            用時(shí):128470毫秒(即:128秒)

            (2)在主鍵上建立聚集索引,在fariq上建立非聚集索引:

            select gid,fariqi,neibuyonghu,title from Tgongwen

            where fariqi> dateadd(day,-90,getdate())

            用時(shí):53763毫秒(54秒)

            (3)將聚合索引建立在日期列(fariqi)上:

            select gid,fariqi,neibuyonghu,title from Tgongwen

            where fariqi> dateadd(day,-90,getdate())

            用時(shí):2423毫秒(2秒)

            雖然每條語句提取出來的都是25萬條數(shù)據(jù),各種情況的差異卻是巨大的,特別是將聚集索引建立在日期列時(shí)的差異。事實(shí)上,如果您的數(shù)據(jù)庫真的有1000萬容量的話,把主鍵建立在ID列上,就像以上的第1、2種情況,在網(wǎng)頁上的表現(xiàn)就是超時(shí),根本就無法顯示。這也是我摒棄ID列作為聚集索引的一個(gè)最重要的因素。

            得出以上速度的方法是:在各個(gè)select語句前加:declare @d datetime

            set @d=getdate()

            并在select語句后加:

            select [語句執(zhí)行花費(fèi)時(shí)間(毫秒)]=datediff(ms,@d,getdate())

            2、只要建立索引就能顯著提高查詢速度

            事實(shí)上,我們可以發(fā)現(xiàn)上面的例子中,第2、3條語句完全相同,且建立索引的字段也相同;不同的僅是前者在fariqi字段上建立的是非聚合索引,后者在此字段上建立的是聚合索引,但查詢速度卻有著天壤之別。所以,并非是在任何字段上簡單地建立索引就能提高查詢速度。

            從建表的語句中,我們可以看到這個(gè)有著1000萬數(shù)據(jù)的表中fariqi字段有5003個(gè)不同記錄。在此字段上建立聚合索引是再合適不過了。在現(xiàn)實(shí)中,我們每天都會發(fā)幾個(gè)文件,這幾個(gè)文件的發(fā)文日期就相同,這完全符合建立聚集索引要求的:“既不能絕大多數(shù)都相同,又不能只有極少數(shù)相同”的規(guī)則。由此看來,我們建立“適當(dāng)”的聚合索引對于我們提高查詢速度是非常重要的。

            3、把所有需要提高查詢速度的字段都加進(jìn)聚集索引,以提高查詢速度

            上面已經(jīng)談到:在進(jìn)行數(shù)據(jù)查詢時(shí)都離不開字段的是“日期”還有用戶本身的“用戶名”。既然這兩個(gè)字段都是如此的重要,我們可以把他們合并起來,建立一個(gè)復(fù)合索引(compound index)。

            很多人認(rèn)為只要把任何字段加進(jìn)聚集索引,就能提高查詢速度,也有人感到迷惑:如果把復(fù)合的聚集索引字段分開查詢,那么查詢速度會減慢嗎?帶著這個(gè)問題,我們來看一下以下的查詢速度(結(jié)果集都是25萬條數(shù)據(jù)):(日期列fariqi首先排在復(fù)合聚集索引的起始列,用戶名neibuyonghu排在后列)

            (1)select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>'2004-5-5'

            查詢速度:2513毫秒

            (2)select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>'2004-5-5' and neibuyonghu='辦公室'

            查詢速度:2516毫秒

            (3)select gid,fariqi,neibuyonghu,title from Tgongwen where neibuyonghu='辦公室'

            查詢速度:60280毫秒

            從以上試驗(yàn)中,我們可以看到如果僅用聚集索引的起始列作為查詢條件和同時(shí)用到復(fù)合聚集索引的全部列的查詢速度是幾乎一樣的,甚至比用

            posted @ 2008-10-27 13:25 若我 閱讀(568) | 評論 (0)編輯 收藏

            2008年10月21日

            __cdecl和__stdcall都是函數(shù)調(diào)用規(guī)范(還有一個(gè)__fastcall),規(guī)定了參數(shù)出入棧的順序和方法,如果只用VC編程的話可以不用關(guān)心,但是要在C++和Pascal等其他語言通信的時(shí)候就要注意了,只有用相同的方法才能夠調(diào)用成功.另外,像printf這樣接受可變個(gè)數(shù)參數(shù)的函數(shù)只有用cdecl才能夠?qū)崿F(xiàn).  
              __declspec主要是用于說明DLL的引出函數(shù)的,在某些情況下用__declspec(dllexport)在DLL中生命引出函數(shù),比用傳統(tǒng)的DEF文件方便一些.在普通程序中也可以用__declspec(dllimport)說明函數(shù)是位于另一個(gè)DLL中的導(dǎo)出函數(shù). 

            int   WINAPI   MessageBoxA(HWND,LPCSTR,LPSTR,UINT);  
              而WINAPI實(shí)際上就是__stdcall.  
              大多數(shù)API都采用__stdcall調(diào)用規(guī)范,這是因?yàn)閹缀跛械恼Z言都支持__stdcall調(diào)用.相比之下,__cdecl只有在C語言中才能用.但是__cdecl調(diào)用有一個(gè)特點(diǎn),就是能夠?qū)崿F(xiàn)可變參數(shù)的函數(shù)調(diào)用,比如printf,這用__stdcall調(diào)用是不可能的.  
              __fastcall這種調(diào)用規(guī)范比較少見,但是在Borland   C++   Builder中比較多的采用了這種調(diào)用方式.  
              如果有共享代碼的需要,比如寫DLL,推薦的方法是用__stdcall調(diào)用,因?yàn)檫@樣適用范圍最廣.如果是C++語言寫的代碼供Delphi這樣的語言調(diào)用就必須聲明為__stdcall,因?yàn)镻ascal不支持cdecl調(diào)用(或許Delphi的最新版本能夠支持也說不定,這個(gè)我不太清楚).在其他一些地方,比如寫COM組件,幾乎都用的是stdcall調(diào)用.在VC或Delphi或C++Builder里面都可以從項(xiàng)目設(shè)置中更改默認(rèn)的函數(shù)調(diào)用規(guī)范,當(dāng)然你也可以在函數(shù)聲明的時(shí)候加入__stdcall,__cdecl,__fastcall關(guān)鍵字來明確的指示本函數(shù)用哪種調(diào)用規(guī)范.  
              __declspec一般都是用來聲明DLL中的導(dǎo)出函數(shù).這個(gè)關(guān)鍵字也有一些其他的用法,不過非常罕見.

            posted @ 2008-10-21 17:46 若我 閱讀(1688) | 評論 (0)編輯 收藏

            2008年9月28日

            #ifndef _ALV_TREE_H
            #define _ALV_TREE_H
            #define Max(a,b) (((a)>(b))?(a):(b))
            #include <iostream>

            template<class T>
            class AVLTree
            {
             struct _TreeNode;
             typedef struct _TreeNode TreeNode;
             struct _TreeNode
             {
              T data;
              int height;
              TreeNode* left;
              TreeNode* right;
             };

            private:
             TreeNode *root;
            public:
             AVLTree()
             {
              this->root=NULL;
             }

             ~AVLTree()
             {
              this->MakeEmpty(this->root);
             }

             int GeiHeight()
             {
              return this->GetHeightUtil(this->root);
             }

             void Insert(T data)
             {
              this->root=this->InsertUtil(this->root,data);
             }
             
             void Delete(T data)
             {
              this->root=this->DeleteUtil(this->root,data);
             }

             void Print()
             {
              /*if(root!=NULL)
              {
               std::cout<<"The root node is: "<<root->data<<std::endl;
              }*/
              for(int level=0;;level++)
              {
               if(this->PrintUtil(this->root,level)==0)
               {
                break;
               }
               std::cout<<std::endl;
              }
             }

            private:
             TreeNode *InsertUtil(TreeNode *_root,T data)
             {
              if(_root==NULL)
              {
               _root=new TreeNode();
               _root->data=data;
               _root->left=0;
               _root->right=0;
               _root->height=0;
              }
              if(data>_root->data)
              {
               _root->right=this->InsertUtil(_root->right,data);
               if(GetHeightUtil(_root->right)-GetHeightUtil(_root->left)==2)
               {
                if(data>_root->right->data)
                {
                 _root=this->SingleRotateWithRight(_root);
                }
                else
                {
                 _root=this->DoubleRotateWithRight(_root);
                }
               }
              }
              else if(data<_root->data)
              {
               _root->left=this->InsertUtil(_root->left,data);
               if(GetHeightUtil(_root->left)-GetHeightUtil(_root->right)==2)
               {
                if(data<_root->left->data)
                {
                 _root=this->SingleRotateWithLeft(_root);
                }
                else
                {
                 _root=this->DoubleRotateWithLeft(_root);
                }
               }
              }
              _root->height=Max(GetHeightUtil(_root->left),GetHeightUtil(_root->right))+1;
              return _root;
             }

             TreeNode *DeleteUtil(TreeNode *_root,T data)
             {
              if(_root==NULL)
              {
               return _root;
              }
              else if(_root->data==data
               &&_root->left==NULL
               &&_root->right==NULL)
              {
               delete _root;
               return NULL;
              }
              else if(_root->data==data
               &&_root->left!=NULL
               &&_root->right==NULL)
              {
               TreeNode* tmpNode=_root->left;
               delete _root;
               tmpNode->height=this->RecalculateHeight(tmpNode);
               return tmpNode;
              }
              else if(_root->data==data
               &&_root->left==NULL
               &&_root->right!=NULL)
              {
               TreeNode *tmpNode=_root->right;
               delete _root;
               tmpNode->height=this->RecalculateHeight(tmpNode);
               return tmpNode;
              }
              else
              {
               if(data==_root->data)
               {
                TreeNode *tmpNode,*parentNode;
                tmpNode=_root->right->right;
                parentNode=_root->right;
                if(tmpNode!=NULL)
                {
                 while(tmpNode->right!=NULL)
                 {
                  parentNode->height-=1;
                  parentNode=tmpNode;
                  tmpNode=tmpNode->right;
                 }
                 parentNode->right=NULL;
                 _root->data=tmpNode->data;
                 delete tmpNode;
                }
                else
                {
                 _root=parentNode;
                }
                _root->height=this->RecalculateHeight(_root);
                //TreeNode *tmpNode=this->FindMax(_root->right);
                //_root->data=tmpNode->data;
                if(GetHeightUtil(_root->left)-GetHeightUtil(_root->right)==2)
                {
                 if(_root->left->left!=NULL)
                 {
                  _root=this->SingleRotateWithLeft(_root);
                 }
                 else if(_root->left->right!=NULL)
                 {
                  _root=this->DoubleRotateWithLeft(_root);
                 }
                }
               }
               else
               if(data>_root->data)
               {
                _root->right=this->DeleteUtil(_root->right,data);
                _root->height=this->RecalculateHeight(_root);
                if(GetHeightUtil(_root->left)-GetHeightUtil(_root->right)==2)
                {
                 if(_root->left->left!=NULL)
                 {
                  _root=this->SingleRotateWithLeft(_root);
                 }
                 else if(_root->left->right!=NULL)
                 {
                  _root=this->DoubleRotateWithLeft(_root);
                 }
                }
               }
               else
               {
                _root->left=this->DeleteUtil(_root->left,data);
                _root->height=this->RecalculateHeight(_root);
                if(GetHeightUtil(_root->right)-GetHeightUtil(_root->left)==2)
                {
                 if(_root->right->right!=NULL)
                 {
                  _root=this->SingleRotateWithRight(_root);
                 }
                 else if(_root->right->left!=NULL)
                 {
                  _root=this->DoubleRotateWithRight(_root);
                 }
                }
               }
              }
              //_root->height=this->RecalculateHeight(_root);
              return _root;
             }

             void MakeEmpty(TreeNode *_root)
             {
              if(_root==NULL)
              {
               return;
              }
              else
              {
               MakeEmpty(_root->left);
               MakeEmpty(_root->right);
               delete _root;
              }
             }

             int GetHeightUtil(TreeNode *_root)
             {
              /*if(_root==NULL|| (_root->left==NULL && _root->right==NULL))
              {
               return 0;
              }
              else
              {
               return 1+GetHeightUtil(_root->left)+GetHeightUtil(_root->right);
              }*/
              if(_root==NULL)
              {
               return -1;
              }
              else
              {
               return _root->height;
              }
             }

             int PrintUtil(TreeNode *node, int level)
             {
              if(node==NULL||level<0)
              {
               return 0;
              }
              else
              {
               if(level==0)
               {
                std::cout<<node->data<<" ";
                return 1;
               }
               return PrintUtil(node->left,level-1)+PrintUtil(node->right,level-1);
              }
             }

             TreeNode *SingleRotateWithLeft(TreeNode *node)
             {
              TreeNode *tmpNode=node->left;
              node->left=tmpNode->right;
              tmpNode->right=node;
              node->height=Max(GetHeightUtil(node->left),GetHeightUtil(node->right))+1;
              tmpNode->height=Max(GetHeightUtil(tmpNode->left),GetHeightUtil(tmpNode->right))+1;
              return tmpNode;
             }

             TreeNode*SingleRotateWithRight(TreeNode *node)
             {
              TreeNode *tmpNode=node->right;
              node->right=tmpNode->left;
              tmpNode->left=node;
              node->height=Max(GetHeightUtil(node->left),GetHeightUtil(node->right))+1;
              tmpNode->height=Max(GetHeightUtil(tmpNode->left),GetHeightUtil(tmpNode->right))+1;
              return tmpNode;
             }

             TreeNode* DoubleRotateWithLeft(TreeNode *node)
             {
              node->left=this->SingleRotateWithRight(node->left);
              return this->SingleRotateWithLeft(node);
             }

             TreeNode* DoubleRotateWithRight(TreeNode *node)
             {
              node->right=this->SingleRotateWithLeft(node->right);
              return this->SingleRotateWithRight(node);
             }

             TreeNode* FindMax(TreeNode *node)
             {
              //T maxData;
              while(node!=NULL&&node->right!=NULL)
              {
               node=node->right;
              }
              //maxData=node->data;
              return node;
             }

             int RecalculateHeight(TreeNode *node)
             {
              if(node==NULL)
              {
               return -1;
              }
              else
              {
               node->height=Max(RecalculateHeight(node->left),RecalculateHeight(node->right))+1;
               return node->height;
              }
             }
            };

            #endif

            posted @ 2008-09-28 17:30 若我 閱讀(797) | 評論 (0)編輯 收藏

            首先打開菜單 項(xiàng)目->項(xiàng)目屬性頁

            1。選擇配置屬性->鏈接器->調(diào)試->生成調(diào)試信息 改為 是

            2。選擇 配置屬性->C/C++ ->常規(guī)->調(diào)試信息格式 改為 用于“編輯并繼續(xù)”的程序數(shù)據(jù)庫(/ZI)

            3。選擇 配置屬性->C/C++ ->優(yōu)化->優(yōu)化 改為 自定義

            重新編譯,運(yùn)行

            posted @ 2008-09-28 16:56 若我 閱讀(1356) | 評論 (0)編輯 收藏

            2008年9月23日

            文本編輯器是所有計(jì)算機(jī)系統(tǒng)中最常用的一種工具。UNIX下的編輯器有ex,sed和vi等,其中,使用最為廣泛的是vi,而vi命令繁多,論壇里好像這方面的總結(jié)不多,以下稍做總結(jié),以資共享!渴望更正和補(bǔ)充! 

            進(jìn)入vi的命令
            vi filename :打開或新建文件,并將光標(biāo)置于第一行首
            vi +n filename :打開文件,并將光標(biāo)置于第n行首
            vi + filename :打開文件,并將光標(biāo)置于最后一行首
            vi +/pattern filename:打開文件,并將光標(biāo)置于第一個(gè)與pattern匹配的串處
            vi -r filename :在上次正用vi編輯時(shí)發(fā)生系統(tǒng)崩潰,恢復(fù)filename
            vi filename....filename :打開多個(gè)文件,依次進(jìn)行編輯

            移動光標(biāo)類命令
            h :光標(biāo)左移一個(gè)字符
            l :光標(biāo)右移一個(gè)字符
            space:光標(biāo)右移一個(gè)字符
            Backspace:光標(biāo)左移一個(gè)字符
            k或Ctrl+p:光標(biāo)上移一行
            j或Ctrl+n :光標(biāo)下移一行
            Enter :光標(biāo)下移一行
            w或W :光標(biāo)右移一個(gè)字至字首
            b或B :光標(biāo)左移一個(gè)字至字首
            e或E :光標(biāo)右移一個(gè)字至字尾
            ) :光標(biāo)移至句尾
            ( :光標(biāo)移至句首
            }:光標(biāo)移至段落開頭
            {:光標(biāo)移至段落結(jié)尾
            nG:光標(biāo)移至第n行首
            n+:光標(biāo)下移n行
            n-:光標(biāo)上移n行
            n$:光標(biāo)移至第n行尾
            H :光標(biāo)移至屏幕頂行
            M :光標(biāo)移至屏幕中間行
            L :光標(biāo)移至屏幕最后行
            0:(注意是數(shù)字零)光標(biāo)移至當(dāng)前行首
            $:光標(biāo)移至當(dāng)前行尾

            屏幕翻滾類命令
            Ctrl+u:向文件首翻半屏
            Ctrl+d:向文件尾翻半屏
            Ctrl+f:向文件尾翻一屏
            Ctrl+b;向文件首翻一屏
            nz:將第n行滾至屏幕頂部,不指定n時(shí)將當(dāng)前行滾至屏幕頂部。

            插入文本類命令
            i :在光標(biāo)前
            I :在當(dāng)前行首
            a:光標(biāo)后
            A:在當(dāng)前行尾
            o:在當(dāng)前行之下新開一行
            O:在當(dāng)前行之上新開一行
            r:替換當(dāng)前字符
            R:替換當(dāng)前字符及其后的字符,直至按ESC鍵
            s:從當(dāng)前光標(biāo)位置處開始,以輸入的文本替代指定數(shù)目的字符
            S:刪除指定數(shù)目的行,并以所輸入文本代替之
            ncw或nCW:修改指定數(shù)目的字
            nCC:修改指定數(shù)目的行

            刪除命令
            ndw或ndW:刪除光標(biāo)處開始及其后的n-1個(gè)字
            do:刪至行首
            d$:刪至行尾
            ndd:刪除當(dāng)前行及其后n-1行
            x或X:刪除一個(gè)字符,x刪除光標(biāo)后的,而X刪除光標(biāo)前的
            Ctrl+u:刪除輸入方式下所輸入的文本

            搜索及替換命令
            /pattern:從光標(biāo)開始處向文件尾搜索pattern
            ?pattern:從光標(biāo)開始處向文件首搜索pattern
            n:在同一方向重復(fù)上一次搜索命令
            N:在反方向上重復(fù)上一次搜索命令
            :s/p1/p2/g:將當(dāng)前行中所有p1均用p2替代
            :n1,n2s/p1/p2/g:將第n1至n2行中所有p1均用p2替代
            :g/p1/s//p2/g:將文件中所有p1均用p2替換

            選項(xiàng)設(shè)置
            all:列出所有選項(xiàng)設(shè)置情況
            term:設(shè)置終端類型
            ignorance:在搜索中忽略大小寫
            list:顯示制表位(Ctrl+I)和行尾標(biāo)志($)
            number:顯示行號
            report:顯示由面向行的命令修改過的數(shù)目
            terse:顯示簡短的警告信息
            warn:在轉(zhuǎn)到別的文件時(shí)若沒保存當(dāng)前文件則顯示NO write信息
            nomagic:允許在搜索模式中,使用前面不帶“\”的特殊字符
            nowrapscan:禁止vi在搜索到達(dá)文件兩端時(shí),又從另一端開始
            mesg:允許vi顯示其他用戶用write寫到自己終端上的信息

            最后行方式命令
            :n1,n2 co n3:將n1行到n2行之間的內(nèi)容拷貝到第n3行下
            :n1,n2 m n3:將n1行到n2行之間的內(nèi)容移至到第n3行下
            :n1,n2 d :將n1行到n2行之間的內(nèi)容刪除
            :w :保存當(dāng)前文件
            :e filename:打開文件filename進(jìn)行編輯
            :x:保存當(dāng)前文件并退出
            :q:退出vi
            :q!:不保存文件并退出vi
            :!command:執(zhí)行shell命令command
            :n1,n2 w!command:將文件中n1行至n2行的內(nèi)容作為command的輸入并執(zhí)行之,若不指定n1,n2,則表示將整個(gè)文件內(nèi)容作為command的輸入
            :r!command:將命令command的輸出結(jié)果放到當(dāng)前行

            寄存器操作
            "?nyy:將當(dāng)前行及其下n行的內(nèi)容保存到寄存器?中,其中?為一個(gè)字母,n為一個(gè)數(shù)字
            "?nyw:將當(dāng)前行及其下n個(gè)字保存到寄存器?中,其中?為一個(gè)字母,n為一個(gè)數(shù)字
            "?nyl:將當(dāng)前行及其下n個(gè)字符保存到寄存器?中,其中?為一個(gè)字母,n為一個(gè)數(shù)字
            "?p:取出寄存器?中的內(nèi)容并將其放到光標(biāo)位置處。這里?可以是一個(gè)字母,也可以是一個(gè)數(shù)字
            ndd:將當(dāng)前行及其下共n行文本刪除,并將所刪內(nèi)容放到1號刪除寄存器中。

            posted @ 2008-09-23 14:57 若我 閱讀(419) | 評論 (0)編輯 收藏

            代碼:
            #include <iostream>
            #include <windows.h>
            using namespace std;

            int main()
            {
             SECURITY_ATTRIBUTES secStru;
             secStru.bInheritHandle=0;
             secStru.lpSecurityDescriptor=0;
             secStru.nLength=0; 
             HANDLE hDevice=CreateFile("\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

             if(hDevice==INVALID_HANDLE_VALUE)
             {
              return -1;
             }

             //DWORD outBuff[1000];
             GET_LENGTH_INFORMATION infoStruct;

             memset(&infoStruct,0,sizeof(infoStruct));
             DWORD bytesReturned;
             if(DeviceIoControl(hDevice,IOCTL_DISK_GET_LENGTH_INFO,NULL,0,&infoStruct,sizeof(infoStruct),&bytesReturned,NULL)==0)
             {
              cout<<"Failed to get disk information."<<endl;
              DWORD error;
              error=GetLastError();
              HRESULT hRe=HRESULT_FROM_WIN32(error);
              char errorData[10];
              sprintf(errorData,"%x",hRe);
              cout<<"Error code:"<</*hRe*/errorData<<endl;
              CloseHandle(hDevice);
              return -1;
             }

             DISK_GEOMETRY_EX geoStruct;
             memset(&geoStruct,0,sizeof(geoStruct));
             if(DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY_EX ,NULL,0,&geoStruct,sizeof(geoStruct),&bytesReturned,NULL)==0)
             {
              cout<<"Failed to get disk information."<<endl;
              DWORD error;
              error=GetLastError();
              HRESULT hRe=HRESULT_FROM_WIN32(error);
              char errorData[10];
              sprintf(errorData,"%x",hRe);
              cout<<"Error code:"<</*hRe*/errorData<<endl;
              CloseHandle(hDevice);
              return -1;
             }

             cout<<"The disk's size is:"<<infoStruct.Length.QuadPart/1024/1024/1024<<" G Bytes."<<endl;
             cout<<"The disk's cylinder number:"<<geoStruct.Geometry.Cylinders.QuadPart<<endl;
             cout<<"The disk's media type:"<<geoStruct.Geometry.MediaType<<endl;
             cout<<"Number of tracks per cylinder:"<<geoStruct.Geometry.TracksPerCylinder<<endl;
             cout<<"Number of sectors per track:"<<geoStruct.Geometry.SectorsPerTrack<<endl;
             cout<<"Number of bytes per sector:"<<geoStruct.Geometry.BytesPerSector<<endl;

             PDISK_PARTITION_INFO  partitionInfo=DiskGeometryGetPartition(&geoStruct);

             DRIVE_LAYOUT_INFORMATION_EX layOutInfo[20];

             memset(&layOutInfo,0,sizeof(DRIVE_LAYOUT_INFORMATION_EX)*20);

             //layOutInfo.PartitionEntry=*(new PARTITION_INFORMATION_EX[10]);

             if(DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_LAYOUT_EX,NULL,0,&layOutInfo,sizeof(DRIVE_LAYOUT_INFORMATION_EX)*20,&bytesReturned,NULL)==0)
             {
              cout<<"Failed to get disk information."<<endl;
              DWORD error;
              error=GetLastError();
              HRESULT hRe=HRESULT_FROM_WIN32(error);
              char errorData[10];
              sprintf(errorData,"%x",hRe);
              cout<<"Error code:"<</*hRe*/errorData<<endl;
              CloseHandle(hDevice);
              return -1;
             }

             int partitionCount=layOutInfo[0].PartitionCount;
             cout<<"Number of partitions:"<<layOutInfo[0].PartitionCount<<endl;
             cout<<"Partitions' information:"<<endl;
             for(int i=0;i<partitionCount;i++)
             {
              //PDISK_PARTITION_INFO pParInfo=partitionInfo+i*sizeof(DISK_PARTITION_INFO);
              if(layOutInfo[i].PartitionEntry[0].PartitionNumber!=0)
              {
               cout<<"Partition "<<layOutInfo[i].PartitionEntry[0].PartitionNumber<<",  partition size is "<<layOutInfo[i].PartitionEntry[0].PartitionLength.QuadPart/1024/1024/1024<<" G Bytes, partition style is "<<layOutInfo[i].PartitionEntry[0].PartitionStyle<<endl;
              }
             }

             //cout<<"The type of partition:"<<((partitionInfo.PartitionStyle==PARTITION_STYLE_MBR) ?"MBR":((partitionInfo.PartitionStyle==PARTITION_STYLE_GPT )?"GPT":((partitionInfo.PartitionStyle==PARTITION_STYLE_RAW)?"RAW":"")))<<endl;

             CloseHandle(hDevice);

             return 0;
            }

            posted @ 2008-09-23 13:19 若我 閱讀(4772) | 評論 (0)編輯 收藏

            蜜臀av性久久久久蜜臀aⅴ麻豆| 99久久精品无码一区二区毛片| 色婷婷综合久久久久中文字幕| 午夜精品久久久久9999高清| 亚洲欧美精品一区久久中文字幕| 一本久久知道综合久久| 久久精品一区二区三区不卡| 日韩欧美亚洲综合久久影院Ds| 亚洲狠狠婷婷综合久久蜜芽| 国产精品一区二区久久精品| 久久综合久久性久99毛片| 久久精品毛片免费观看| 激情五月综合综合久久69| 婷婷久久香蕉五月综合加勒比| 国产亚洲成人久久| 久久99精品国产自在现线小黄鸭| 日批日出水久久亚洲精品tv| 亚洲狠狠综合久久| 亚洲AV日韩精品久久久久| 亚洲国产综合久久天堂| 久久精品国产免费一区| 少妇内射兰兰久久| 亚洲性久久久影院| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 国产叼嘿久久精品久久| 天堂久久天堂AV色综合| 99久久精品免费看国产一区二区三区 | 亚洲午夜久久久久久噜噜噜| 久久精品三级视频| 91精品国产91久久久久久蜜臀| 亚洲乱码中文字幕久久孕妇黑人| 亚洲性久久久影院| 国产精品久久久久久久久软件 | 91视频国产91久久久| 国内精品久久久久久久久电影网| 久久亚洲国产精品123区| 国产香蕉97碰碰久久人人| 日本精品久久久久中文字幕| 久久精品国产91久久综合麻豆自制| 2021久久国自产拍精品| 99re这里只有精品热久久|