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

            char型字符串中得到漢字

            關于這個問題,,自己一直沒模糊的。。一直的做法是把字符串全部轉成寬字節。然后再去查找,但是想了下。。有時有可能。不能轉。。比如我需要得到一個char字符串中漢字的位置,,,如果轉成寬字節。。位置是不對的。。去網上查了一下相關的資料。  記錄下一段代碼,方便以后
            int   main(int   argc,   char*   argv[])  
              {  
              char   *str="abc一個問題def";  
              char   *p=str,*p1;  
              unsigned   short   ch;  
              while(strcmp(p,"")!=0)  
              {  
              p1=CharNextExA(936,p,0);  
              int   i=p1-p;  
              if(i==1)  
              {  
              ch=(unsigned   char)*p;  
              }else   if(i==2)  
              {  
              ch=(*p)*255+*(p+1);  
              }  
              p=p1;  
               
               
              }  
              return   0;  
              }  

            posted @ 2007-10-23 10:34 Randy 閱讀(1008) | 評論 (0)編輯 收藏

            毫秒級計時器

            今天繼續編寫,基于框架的效果編輯器,修正了部分BUG后。。就想把。渲染窗口掛到MFC的窗口上。。。做為整個編輯器的一個子窗口打開。。這次。。。也比較方便。。也便于以后修改。以前掛接渲染窗口時。是使用settime來進行定時刷新渲染窗口,原來就感覺到刷新比較慢。但是因為查看MSDN。。。上講。。SetTime是毫秒級。。。最低精確到1毫秒。。。1秒=1000毫秒。我為了保證窗口UI的正常使用。一般設置為20毫秒。。為什么不用線程咧。因為渲染窗口一般會與其它信息存在交互。。單純渲染線程。。在處理互斥時。。。效率會慢到無法用言語來表達。。。1000/20=50。。每秒50的fps。。足可以應付簡單的渲染需求了。但是在今天的測試中。。動態調整動畫的FPS時。。。確發現。當FPS超過每秒20的范圍后。。動畫就不再有任何變化了,郁悶。。。然后。。就輕易的推翻了自己寫的一切。。。使用線程。。渲染。。。。因為渲染紋理是從一個模板LIST中。。。獲得。。。立刻就開始徘徊在。。加鎖。。。。。巨慢。。。不加鎖。。。異常的圍城中。。。。在多方思索無果后。。。。忽然覺得SetTime不應該會如此慢的。。。。然后。。。放棄線程。。。去實際測試了一下。。。發現了問題:

            SetTime雖然MSDN上說可以最低設置到一毫秒,但實際上測試只能精確到53毫秒左右,然后google上查詢。。。有了答案。windows 以經限定了Settimer()的精度是55ms。。。就是所謂的1000/55==18.2 ..因為98系統是根據時間中斷反饋,而時間中段每秒最多18.2次,雖然2000的系統據說沒有此限制。。但在我XP的系統下測試。。。精度依舊。應該是為了保證系統兼容。。所以將SetTime精度設定在最高的范圍。。如果這樣換算。。。也就和我的問題基本吻合。。。。SetTime(1)的情況下。。實現是55毫秒觸發一次,也就是每秒18.2幀。。。。18的FPS。。。啥都玩不轉了。而且WM-TIME消息 在系統的優先級為極低。很容易被拋棄。。渲染窗口最少要保證在20毫秒觸發一次。。也就是FPS50的情況下。。才可以保證動畫等效果的連續性。。怎么辦。。。怎么辦。。。。繼續google。。。毫秒級記時器。。。。。終于被我找到了。。。。。好幾種解決的方法,對了。。。sleep的精度是30MS。。。以后要注意。。一下:

            一.GetTickCount()函數,該函數的返回值是  DWORD型,表示以ms為單位的計算機啟動后經歷的時間間隔。精度比WM_TIMER消息映射高,在較 短的定時中其計時誤差為15ms,在較長的定時中其計時誤差較低,如果定時時間太長,就好象死機一樣,CPU占用率非常高,只能用于要求不高的延時程序中.
            下列代碼可以實現50ms的精確定時:
                   DWORD dwStart = GetTickCount();
            DWORD dwEnd   = dwStart;
            do
            {
                          //為了在延遲時間不阻塞。可在此將消息傳出,但是會降低精度
            MSG   msg;
            GetMessage(&msg,NULL,0,0);
            TranslateMessage(&msg);
            DispatchMessage(&msg);
                          dwEnd = GetTickCount()-dwStart;
            }while(dwEnd <50);
            二,這就是我現在使用的方法,也決定以后都使用。。哈哈
             使用多媒體定時器timeSetEvent()函數,該函數定時精度為ms級(精度基本準確,由于掛接窗口一般是在工具中實現,內部人員使用,所以不需要控制機器配置)。
            MMRESULT timeSetEvent( UINT uDelay,
            UINT uResolution,
            LPTIMECALLBACK lpTimeProc,
            WORD dwUser,
            UINT fuEvent )
            該函數設置一個定時回調事件,此事件可以是一個一次性事件或周期性事件。事件一旦被激活,便調用指定的回調函數, 成功后返回事件的標識符代碼,否則返回NULL
            參數說明:
            uDelay:以毫秒指定事件的周期。
            Uresolution:以毫秒指定延時的精度,數值越小定時器事件分辨率越高。缺省值為1ms。
            LpTimeProc:指向一個回調函數。
            DwUser:存放用戶提供的回調數據。
            FuEvent:指定定時器事件類型:
            TIME_ONESHOT:uDelay毫秒后只產生一次事件
            TIME_PERIODIC :每隔uDelay毫秒周期性地產生事件。  
            需要注意的是,任務處理的時間不能大于周期間隔時間。另外,在定時器使用完畢后, 應及時調用timeKillEvent()將之釋放。 
            雖然還有更加精確的計時方法,不過對于我的需求這個以經夠用了
            我的實現代碼
            UINT   uTimerID;         //定義定時器句柄   
            void   CALLBACK   TimerCallProc(UINT   TimerID,   UINT   msg,DWORD   dwUser,   DWORD   dwa,DWORD   dwb)   
            {
             // TODO: 在此添加消息處理程序代碼和/或調用默認值

             Sleep(1);
            }
            //當前設置為1ms...
            uTimerID=timeSetEvent(1,1,&TimerCallProc,0,TIME_PERIODIC);
            //退出時
             timeKillEvent(uTimerID);                   //刪除定時器事件   
             timeEndPeriod(1);                          //清除定時器分辨率  



             

            posted @ 2007-10-17 17:38 Randy 閱讀(5490) | 評論 (1)編輯 收藏

            內存填充值的理解

            1、使用 new 或者 malloc 分配后的內存,其內容被填充為 0xCD,CRT 中稱處于這種狀態的內存區為 Clean Land,即干凈區,由此推測 0xCD 的含義可能為 Clean Data。在此數據的前后(不包含于此區域內),各有一個守衛用的 DWORD,其內容為 0xFDFDFDFD。
            2、使用 delete 或者 free 釋放后的內存,其內容被清空為 0xDD,CRT 中稱處于這種狀態的內存區為 Dead Land,即死區,由此推測 0xDD 的含義可能為 Dead Data。守衛用 DWORD 也同時被清除。
            3、使用 HeapAlloc 分配的內存,其內容被填充為 0xBAADF00D,我推測為 Bad Food 的變體,經過 HeadFree 釋放的內存,其大部分內容會被填充為 0xFEEE,但起始的兩個 DWORD 不是,在我的機器上這兩個 DWORD 的值均為 0x00140238,含義不詳。
             
            在簡單的測試中,delete/free 最終總會調用到 HeapFree,因而看到的釋放后的內存中是 0xFEEE,而 new/malloc 雖然調用了 HeapAlloc,但之后又填充了 0xCD,故而看到的是 0xCD。
             
            記憶中有過釋放之后看到 0xDD 的情況,而且 CRT 的代碼里也的確有并不立刻調用 HeapFree 來真正釋放內存的分支,但測試代碼并未達到。
             
            另外,0xCC 也是有的,好像是編譯器做的事情之一,用于填充棧上的自動變量。
             
            上述 CRT 的行為均為 Debug 版本的表現。
             
            上述的系統行為(即 HeapXXX 函數族的行為)均為在 Windows Xp SP2 上的表現。

            posted @ 2007-10-16 16:53 Randy 閱讀(836) | 評論 (8)編輯 收藏

            通過系統填充的數據判斷內存屬性

            Microsoft Visual C++ Runtime library

            C runtime library provides it own debug codes:
            0xCD, 0xCDCDCDCD - New objects. New objects are filled with 0xCD when they are allocated.
            0xFD, 0xFDFDFDFD - No-man's land memory. Extra bytes that belong to the internal block allocated, but not the block you requested. They are placed before and after requested blocks and used for data bound checking.
            0xDD, 0xDDDDDDDD - Freed blocks. The freed blocks kept unused in the debug heap's linked list when the _CRTDBG_DELAY_FREE_MEM_DF flag is set are currently filled with 0xDD. Although in some cases you won't see magic 0xDDDDDDDD value, as it will be overwritten by another debug function (e.g. 0xFEEEFEEE for HeapFree).

            These constants are defined in DbgHeap.c file as


            static unsigned char _bNoMansLandFill = 0xFD; /* fill no-man's land with this */
            static unsigned char _bDeadLandFill = 0xDD; /* fill free objects with this */
            static unsigned char _bCleanLandFill = 0xCD; /* fill new objects with this */



            Compiler initialisations

            0xCC, 0xCCCCCCCC - The /GX Microsoft Visual C++ compiler option initialises all local variables not explicitly initialised by the program. It fills all memory used by these variables with 0xCC, 0xCCCCCCCC.

            Windows NT memory codes

            0xABABABAB - Memory following a block allocated by LocalAlloc().
            0xBAADF00D - "Bad Food". This is memory allocated via LocalAlloc( LMEM_FIXED, ... ). It is memory that has been allocated but not yet written to.
            0xFEEEFEEE - OS fill heap memory, which was marked for usage, but wasn't allocated by HeapAlloc() or LocalAlloc(). Or that memory just has been freed by HeapFree().

            posted @ 2007-10-16 16:47 Randy 閱讀(350) | 評論 (0)編輯 收藏

            C/C++中的近指令、遠指針和巨指針

             今天Ben忽然問我。。。LPVOID中的L是什么意思,一下把我問住了。不可能是長的意思是。查了下。。竟然是遠指針的含義,都沒學過這個東東。學習了下。。以前都沒聽說指針還有遠、近、巨之分的,從沒聽說過什么近指針、遠指針和巨指針。

            char near *p; /*定義一個字符型“近”指針*/
            char far *p; /*定義一個字符型“遠”指針*/
            char huge *p; /*定義一個字符型“巨”指針*/

            首先要從8086處理器體系結構和匯編淵源學起。8086是一個16位處理器,它設定了四個段寄存器,專門用來保存段地址:CS(Code Segment):代碼段寄存器;DS(Data Segment):數據段寄存器;SS(Stack Segment):堆棧段寄存器;ES(Extra Segment):附加段寄存器。8086采用段式訪問,訪問本段(64K范圍內)的數據或指令時,不需要變更段地址(意味著段地址寄存器不需修改),而訪問本段范圍以外的數據或指令時,則需要變更段地址(意味著段地址寄存器需要修改)。
            因此,在16位處理器環境下,如果訪問本段內地址的值,用一個16位的指針(表示段內偏移)就可以訪問到;而要訪問本段以外地址的值,則需要用16位的段內偏移+16位的段地址,總共32位的指針。

            這樣,就可以知道遠、近指針的區別:

            近指針是只能訪問本段、只包含本段偏移的、位寬為16位的指針;
            遠指針是能訪問非本段、包含段偏移和段地址的、位寬為32位的指針。

            近指針只能對64k字節數據段內的地址進行存取,如:

            char near *p;
            p=(char near *)0xffff;

            遠指針是32位指針,它表示段地址:偏移地址,遠指針可以進行跨段尋址,可以訪問整個內存的地址。如定義遠程指針p指向0x1000段的0x2號地址,即1000:0002,則可寫作:
            char far *p;
            p=(char far *)0x10000002;

            除了遠指針和近指針外,還有一個巨指針的概念。
            和遠指針一樣,巨指針也是32位的指針,指針也表示為16位段:16位偏移,也可以尋址任何地址。它和遠指針的區別在于進行了規格化處理。遠指針沒有規格化,可能存在兩個遠指針實際指向同一個物理地址,但是它們的段地址和偏移地址不一樣,如23B0:0004和23A1:00F4都指向同一個物理地址23604!巨指針通過特定的例程保證:每次操作完成后其偏移量均小于10h,即只有最低4位有數值,其余數值都被進位到段地址上去了,這樣就可以避免Far指針在64K邊界時出乎意料的回繞的行為。當然,一次操作必須小于64K。下面的函數可以將遠指針轉換為巨指針:
            void normalize(void far ** p)
            {
              *p=(void far *)(((long)*p&0xffff000f)+(((long)*p&0x0000fff00<<12));
            }

            從上面的函數中 可以看到指針之指針的使用,這個函數要修改指針的值,因此必須傳給它的指針的指針作為參數。

            看到最后。。。。學習到了一點。。讓人很郁悶的事實。。。

            近指針、遠指針、巨指針是段尋址的16bit處理器的產物(如果處理器是16位的,但是不采用段尋址的話,也不存在近指針、遠指針、巨指針的概念),當前普通PC所使用的32bit處理器(80386以上)一般運行在保護模式下的,指針都是32位的,可平滑地址,已經不分遠、近指針了。但是在嵌入式系統領域下,8086的處理器仍然有比較廣泛的市場,如AMD公司的AM186ED、AM186ER等處理器,開發這些系統的程序時,我們還是有必要弄清楚指針的尋址范圍。

            一個多小的學習。。。。。。。白學了。。。。。。-_______________________________-

            posted @ 2007-10-16 15:00 Randy 閱讀(884) | 評論 (1)編輯 收藏

            感想

            想想自己也注冊很多天了。也不是沒時間寫。。只是忽然不覺得有什么系統的東西可以寫上來的。后來想想。也沒什么啦。哪有那么多系統的東西可以寫啊。所以。。就把每天code上遇到的一些問題。。以及自己學習的一些心得記下來吧。以便日后忘了的話。。可以看下,呵呵。。。以后要堅持啦。

            posted @ 2007-10-15 21:47 Randy 閱讀(114) | 評論 (0)編輯 收藏

            字節對齊

            今天下午權哥忽然發過來一道題,后來說明是網上流傳的一道關于字節對齊的題,很久沒做了。嘗試著想啊想啊做了下。也算做出來了
            #pragma pack(8)

              struct s1{
              short a;
              long b;
              };

              struct s2{
              char c;
              s1 d;
              long long e;
              };

              #pragma pack()

              問
              1.sizeof(s2) = ?
              2.s2的s1中的a后面空了幾個字節接著是b?
            回憶中的思路是:
            s1 short(2) long(4)
               0 1       2 3 4 5       6 7 8 9 10
               short     long                                   算錯了

            對齊的原則是取小 當前類型與pack(n)的字節數取小的那一個

            short占兩個字節后當前地址為2 long為四字節。可以被整除2 所以不用添字節
            所以  sizeof(s1) = 6                            算錯了


            這個地方算錯了。。非常對不起大家。。重寫的那天。。頭暈。。按1字節算了
            也多謝朋友的提醒,以后一定注意.

            重新修正為

            s1 short(2) long(4)
             0 1       2 3    4 5 6 7
            short      補          long

            對齊的原則是取小 當前類型與pack(n)的字節數取小的那一個
            short占兩個字節  long是占四個字節。所以需要當前地址可以被4整除  所以。。補兩個字節
            所以  sizeof(s1) =8



            然后來算s2
            char(1)  s1被拆分 (short(2) long(4)   結構體拆分后按最大字節對齊)  longlong(8)

             0        1 2 3          4567    8 9 10 11  12 13 14 15   16 17 18 19 20 21 22 23 
             char      補           short          long          補              longlong
            所以sizeof(s2)=24
            a后面空了2個字節接著是b

            應該是沒有問題的 還有一點。。如果最后位數不夠的話。。。是按packer和結構體兩個最小的字節數補齊

            posted @ 2007-10-15 21:43 Randy 閱讀(557) | 評論 (2)編輯 收藏

            僅列出標題
            共4頁: 1 2 3 4 
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            超级97碰碰碰碰久久久久最新| 久久国产精品成人影院| 久久e热在这里只有国产中文精品99| 久久精品www人人爽人人| 香港aa三级久久三级| 久久天天躁狠狠躁夜夜2020老熟妇 | 国内精品久久久人妻中文字幕| 久久精品国产亚洲77777| 久久99精品国产麻豆蜜芽| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 国产亚洲美女精品久久久久狼| 99久久免费只有精品国产| 日韩欧美亚洲综合久久| 国产999精品久久久久久| 亚洲精品无码久久久久去q | 久久久久无码精品国产app| 一本色道久久88精品综合| 久久香蕉一级毛片| 久久丫精品国产亚洲av| 人妻无码久久精品| a级毛片无码兔费真人久久| 久久亚洲精品成人AV| 中文字幕精品久久久久人妻| 国产99久久九九精品无码| 国产国产成人精品久久| 伊人久久久AV老熟妇色| 亚洲精品久久久www| 国产巨作麻豆欧美亚洲综合久久| 国内精品伊人久久久久| 久久精品国产久精国产思思| 久久无码高潮喷水| 97精品伊人久久大香线蕉| 一级a性色生活片久久无| 污污内射久久一区二区欧美日韩| 精品人妻伦九区久久AAA片69| 亚洲综合精品香蕉久久网97| 99久久精品午夜一区二区| 国产精品久久亚洲不卡动漫| 精品久久久久久中文字幕| 久久免费视频网站| 国内精品久久久久久久涩爱|