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

            xiaoxiaoling

            C++博客 首頁 新隨筆 聯系 聚合 管理
              17 Posts :: 2 Stories :: 9 Comments :: 0 Trackbacks

            #

            1)打開資源文件,把LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US修改為
            LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
            2)關閉資源文件
            3)打開對話框,輸入漢字,并保存
            4)右擊資源文件屬性,選擇Resources->General->Culture,設置為:中文(中國) (0x804)
            5)編譯,測試
            posted @ 2008-12-11 17:53 clcl 閱讀(393) | 評論 (0)編輯 收藏

            前言  
              看到有些人對位運算還存在問題,于是決定寫這篇文章作個簡要說明。  
               
              什么是位(bit)?  
               
              很簡單,位(bit)就是單個的0或1,位是我們在計算機上所作一切的基礎。計算機上的所有數據都是用位來存儲的。一個字節(BYTE)由八個位組成,一個字(WORD)是二個字節或十六位,一個雙字(DWORD)是二個字(WORDS)或三十二位。如下所示:  
               
                  0   1   0   0   0   1   1   1   1   0   0   0   0   1   1   1   0   1   1   1   0   1   0   0   0   1   1   1   1   0   0   0  
              |   |                             |                               |                               |                             |   |  
              |   +-   bit   31             |                               |                               |               bit   0   -+   |  
              |                                 |                               |                               |                                 |  
              +--   BYTE   3   ----   -+----   BYTE   2   ---+----   BYTE   1   ---+---   BYTE   0   -----+  
              |                                                                 |                                                                 |  
              +------------   WORD   1   ------------+-----------   WORD   0   -------------+  
              |                                                                                                                                   |  
              +-----------------------------   DWORD   -----------------------------+  
               
              使用位運算的好處是可以將BYTE,   WORD   或   DWORD   作為小數組或結構使用。通過位運算可以檢查位的值或賦值,也可以對整組的位進行運算。  
               
              16進制數及其與位的關系  
              用0或1表示的數值就是二進制數,很難理解。因此用到16進制數。  
               
              16進制數用4個位表示0   -   15的值,4個位組成一個16進制數。也把4位成為半字節(nibble)。一個BYTE有二個nibble,因此可以用二個16進制數表示一個BYTE。如下所示:  
               
              NIBBLE       HEX   VALUE  
              ======       =========  
                0000                 0  
                0001                 1  
                0010                 2  
                0011                 3  
                0100                 4  
                0101                 5  
                0110                 6  
                0111                 7  
                1000                 8  
                1001                 9  
                1010                 A  
                1011                 B  
                1100                 C  
                1101                 D  
                1110                 E  
                1111                 F  
               
              如果用一個字節存放字母"r"(ASCII碼114),結果是:  
              0111   0010         二進制  
                  7         2           16進制  
               
              可以表達為:'0x72'  
               
              有6種位運算:  
                    &       與運算  
                    |       或運算  
                    ^       異或運算  
                    ~       非運算(求補)  
                  >>       右移運算  
                  <<       左移運算  
               
              與運算(&)  
              雙目運算。二個位都置位(等于1)時,結果等于1,其它的結果都等于0。  
                    1       &       1       ==       1  
                    1       &       0       ==       0  
                    0       &       1       ==       0  
                    0       &       0       ==       0  
               
              與運算的一個用途是檢查指定位是否置位(等于1)。例如一個BYTE里有標識位,要檢查第4位是否置位,代碼如下:  
               
              BYTE   b   =   50;  
              if   (   b   &   0x10   )  
                      cout   <<   "Bit   four   is   set"   <<   endl;  
              else  
                      cout   <<   "Bit   four   is   clear"   <<   endl;  
               
              上述代碼可表示為:  
               
                      00110010     -   b  
                  &   00010000     -   &   0x10  
                ----------------------------  
                      00010000     -   result  
               
              可以看到第4位是置位了。  
               
              或運算(   |   )  
              雙目運算。二個位只要有一個位置位,結果就等于1。二個位都為0時,結果為0。  
                    1       |       1       ==       1  
                    1       |       0       ==       1  
                    0       |       1       ==       1  
                    0       |       0       ==       0  
               
              與運算也可以用來檢查置位。例如要檢查某個值的第3位是否置位:  
               
              BYTE   b   =   50;  
              BYTE   c   =   b   |   0x04;  
              cout   <<   "c   =   "   <<   c   <<   endl;  
               
              可表達為:  
               
                      00110010     -   b  
                  |   00000100     -   |   0x04  
                  ----------  
                      00110110     -   result  
               
              異或運算(^)  
              雙目運算。二個位不相等時,結果為1,否則為0。  
               
                    1       ^       1       ==       0  
                    1       ^       0       ==       1  
                    0       ^       1       ==       1  
                    0       ^       0       ==       0  
               
              異或運算可用于位值翻轉。例如將第3位與第4位的值翻轉:  
               
              BYTE   b   =   50;  
              cout   <<   "b   =   "   <<   b   <<   endl;  
              b   =   b   ^   0x18;  
              cout   <<   "b   =   "   <<   b   <<   endl;  
              b   =   b   ^   0x18;  
              cout   <<   "b   =   "   <<   b   <<   endl;  
               
              可表達為:  
               
                      00110010     -   b  
                  ^   00011000     -   ^0x18  
                  ----------  
                      00101010     -   result  
               
                      00101010     -   b  
                  ^   00011000     -   ^0x18  
                  ----------  
                      00110010     -   result  
               
              非運算(~)  
              單目運算。位值取反,置0為1,或置1為0。非運算的用途是將指定位清0,其余位置1。非運算與數值大小無關。例如將第1位和第2位清0,其余位置1:  
               
              BYTE   b   =   ~0x03;  
              cout   <<   "b   =   "   <<   b   <<   endl;  
              WORD   w   =   ~0x03;  
              cout   <<   "w   =   "   <<   w   <<   endl;  
               
              可表達為:  
               
                      00000011     -   0x03  
                      11111100     -   ~0x03     b  
               
                      0000000000000011     -   0x03  
                      1111111111111100     -   ~0x03     w  
               
              非運算和與運算結合,可以確保將指定為清0。如將第4位清0:  
               
              BYTE   b   =   50;  
              cout   <<   "b   =   "   <<   b   <<   endl;  
              BYTE   c   =   b   &   ~0x10;  
              cout   <<   "c   =   "   <<   c   <<   endl;  
               
              可表達為:  
               
                      00110010     -   b  
                  &   11101111     -   ~0x10  
                  ----------  
                      00100010     -   result  
               
              移位運算(>>   與   <<)  
              將位值向一個方向移動指定的位數。右移   >>   算子從高位向低位移動,左移   <<   算子從低位向高位移動。往往用位移來對齊位的排列(如MAKEWPARAM,   HIWORD,   LOWORD   宏的功能)。  
               
              BYTE   b   =   12;  
              cout   <<   "b   =   "   <<   b   <<   endl;  
              BYTE   c   =   b   <<   2;  
              cout   <<   "c   =   "   <<   c   <<   endl;  
              c   =   b   >>   2;  
              cout   <<   "c   =   "   <<   c   <<   endl;  
               
              可表達為:  
                      00001100     -   b  
                      00110000     -   b   <<   2  
                      00000011     -   b   >>   2  
               
              譯注:以上示例都對,但舉例用法未必恰當。請閱文末鏈接的文章,解釋得較為清楚。  
               
              位域(Bit   Field)  
              位操作中的一件有意義的事是位域。利用位域可以用BYTE,   WORD或DWORD來創建最小化的數據結構。例如要保存日期數據,并盡可能減少內存占用,就可以聲明這樣的結構:  
               
              struct   date_struct   {  
                      BYTE       day       :   5,       //   1   to   31  
                                    month   :   4,       //   1   to   12  
                                    year     :   14;     //   0   to   9999  
                      }date;  
                       
              在結構中,日期數據占用最低5位,月份占用4位,年占用14位。這樣整個日期數據只需占用23位,即3個字節。忽略第24位。如果用整數來表達各個域,整個結構要占用12個字節。  
               
              |   0   0   0   0   0   0   0   0   |   0   0   0   0   0   0   0   0   |   0   0   0   0   0   0   0   0   |  
                    |                                                           |                   |                     |  
                    +-------------   year   --------------+   month+--   day   --+  
               
              現在分別看看在這個結構聲明中發生了什么  
               
              首先看一下位域結構使用的數據類型。這里用的是BYTE。1個BYTE有8個位,編譯器將分配1個BYTE的內存。如果結構內的數據超過8位,編譯器就再分配1個BYTE,直到滿足數據要求。如果用WORD或DWORD作結構的數據類型,編譯器就分配一個完整的32位內存給結構。  
               
              其次看一下域聲明。變量(day,   month,   year)名跟隨一個冒號,冒號后是變量占用的位數。位域之間用逗號分隔,用分號結束。  
               
              使用了位域結構,就可以方便地象處理普通結構數據那樣處理成員數據。盡管我們無法得到位域的地址,卻可以使用結構地址。例如:  
              date.day   =   12;  
              dateptr   =   &date;  
              dateptr->year   =   1852;
            posted @ 2008-11-11 22:21 clcl 閱讀(220) | 評論 (0)編輯 收藏

            CButtonT           CButton           CTrackBarCtrlT         CTrackBarCtrl
            CListBoxT          CListBox          CUpDownCtrlT           CUpDownCtrl
            CComboBoxT         CComboBox         CProgressBarCtrlT      CProgressBarCtrl
            CEditT             CEdit             CHotKeyCtrlT           CHotKeyCtrl
            CScrollBarT        CScrollBar        CAnimateCtrlT          CAnimateCtrl
            CToolTipCtrlT CToolTipCtrl      CRichEditCtrlT         CRichEditCtrl
            CHeaderCtrlT       CHeaderCtrl       CReBarCtrlT            CReBarCtrl
            CListViewCtrlT     CListViewCtrl     CMonthCalendarCtrlT    CMonthCalendarCtrl
            CTreeViewCtrlT     CTreeViewCtrl     CDateTimePickerCtrlT  CDateTimePickerCtrl
            CToolBarCtrlT CToolBarCtrl      CIPAddressCtrlT        CIPAddressCtrl
            CStatusBarCtrlT    CStatusBarCtrl    CPagerCtrlT            CPagerCtrl
            CTabCtrlT          CTabCtrl
            posted @ 2008-11-11 17:02 clcl 閱讀(1468) | 評論 (0)編輯 收藏

               char file[MAX_PATH];
               TCHAR Tchartmp[MAX_PATH];

            sprintf_s(file, "fileName%d", 134);

               CString strUnicode = file;

               wcscpy(Tchartmp,strUnicode);
            posted @ 2008-10-14 15:00 clcl 閱讀(924) | 評論 (1)編輯 收藏

            TCHAR tcScriptName[MAX_PATH];
            tcScriptName = "filename";
            size_t i;
              char tmp[MAX_PATH];
              mbstate_t       mbstate;

              // Reset to initial shift state
              ::memset((void*)&mbstate, 0, sizeof(mbstate));

              const wchar_t* wt = tcScriptName;
              wcsrtombs_s(&i, tmp, MAX_PATH, &wt, MAX_PATH,&mbstate);


            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


            char * input = null;
            wchar_t wc_input[MAX_USERNAME_LEN] = L"test";

              int nLen = WideCharToMultiByte( CP_ACP, 0, wc_input, -1, NULL, 0, NULL, NULL );
              int i = wcslen(wc_input)*sizeof(wchar_t);
              input = (char*)realloc(input,i+1);
              if (!input)
              {
               free(input);
               input = (char*)malloc(i + 1);
              }
              WideCharToMultiByte( CP_ACP, 0, wc_input, -1, input, nLen, NULL, NULL );


             

            posted @ 2008-10-14 14:26 clcl 閱讀(8047) | 評論 (4)編輯 收藏

            繼承是類與類的關系。
            重載是方法與方法之間的關系。

            繼承是一個類需要另一個類的屬性和方法,所以用到繼承,這是發生在兩個類之間的事情。
            重載是指一個方法與另一個方法的方法名相同而參數列表不相同,這樣的情況叫重載,屬于多態。這是發生在一個類中的事情。

            一個子類繼承另外一個類,可以對父類中的方法進行重寫,說到這里應該可以看出,繼承和重載沒什么關系了。而重寫卻與繼承有很大的關系。
            因為重寫一般都發生在有繼承的情況下,就是子類重寫父類的方法。


            重載和重寫有什么區別和聯系:

            先說聯系:
            都是發生在同名方法之間的事情。

            區別:
            重載是發生在一個類中,根據參數列表的不同來區分兩個同名的方法。
            重寫是發生在兩個又繼承關系的類中,根據方法體不同來區分兩個同名方法。



            memcpy
            開放分類: C語言函數

              原型:extern void *memcpy(void *dest, void *src, unsigned int count);
              用法:#include <string.h>
             
              功能:由src所指內存區域復制count個字節到dest所指內存區域。
             
              說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。
             
              舉例:
                  // memcpy.c
                 
                  #include <syslib.h>
                  #include <string.h>
                  main()
                  {
                    char *s="Golden Global View";
                    char d[20];
                   
                    clrscr();
                   
                    memcpy(d,s,strlen(s));
                    d[strlen(s)]=0;
                    printf("%s",d);
                    getchar();
                    return 0;
                  }
             

             

             

            strcat
             
             

              原型:extern char *strcat(char *dest,char *src);
                   
              用法:#include <string.h>
             
              功能:把src所指字符串添加到dest結尾處(覆蓋dest結尾處的'\0')并添加'\0'。
             
              說明:src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
                    返回指向dest的指針。
             
              舉例:


                  // strcat.c
                 
                  #include <syslib.h>
                  #include <string.h>

                  main()
                  {
                    char d[20]="Golden Global";
                    char *s=" View";
                   
                    clrscr();
                   
                    strcat(d,s);
                    printf("%s",d);

                    getchar();
                    return 0;
                  }

             

             

            memset
            在你申請了一塊內存之后,
            比如
            int *p=NULL;
            p=malloc(10*sizeof(int));//申請了10個int型內存
            memset(p,0,10*sizeof(int));//全部初始化為0

            memset的作用就是把你快連續的內存初始化為你給的值。
            Example
            /* MEMSET.C: This program uses memset to
            * set the first four bytes of buffer to "*".
            */

            #include <memory.h>
            #include <stdio.h>

            void main( void )
            {
            char buffer[] = "This is a test of the memset function";

            printf( "Before: %s\n", buffer );
            memset( buffer, '*', 4 );
            printf( "After: %s\n", buffer );
            }

            Output
            Before: This is a test of the memset function
            After: **** is a test of the memset function

             

             

             

             

             

            ftell
            開放分類: 計算機語言、計算機技術、編程、程序、函數

            函數名: ftell
            功  能: 返回當前文件指針
            用  法: long ftell(FILE *stream);
            程序例:

            #include <stdio.h>

            int main(void)
            {
               FILE *stream;

               stream = fopen("MYFILE.TXT", "w+");
               fprintf(stream, "This is a test");
               printf("The file pointer is at byte \
                      %ld\n", ftell(stream));
               fclose(stream);
               return 0;
            }

             

             

             


            fopen
            開放分類: 計算機語言、計算機技術、編程、程序、函數

            fopen(打開文件)
            相關函數  open,fclose
            表頭文件  #include<stdio.h>
            定義函數  FILE * fopen(const char * path,const char * mode);
            函數說明  參數path字符串包含欲打開的文件路徑及文件名,參數mode字符串則代表著流形態。
            mode有下列幾種形態字符串:
            r 打開只讀文件,該文件必須存在。
            r+ 打開可讀寫的文件,該文件必須存在。
            w 打開只寫文件,若文件存在則文件長度清為0,即該文件內容會消失。若文件不存在則建立該文件。
            w+ 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內容會消失。若文件不存在則建立該文件。
            a 以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。
            a+ 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾后,即文件原先的內容會被保留。
            上述的形態字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b 字符用來告訴函數庫打開的文件為二進制文件,而非純文字文件。不過在POSIX系統,包含Linux都會忽略該字符。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權限,此文件權限也會參考umask 值。
            返回值
            文件順利打開后,指向該流的文件指針就會被返回。若果文件打開失敗則返回NULL,并把錯誤代碼存在errno 中。
            附加說明
            一般而言,開文件后會作一些文件讀取或寫入的動作,若開文件失敗,接下來的讀寫動作也無法順利進行,所以在fopen()后請作錯誤判斷及處理。

            【例程】
            #include <stdlib.h>
            #include <stdio.h>
            #include <dir.h>

            int main(void)
            {
                char *s;
                char drive[MAXDRIVE];
                char dir[MAXDIR];
                char file[MAXFILE];
                char ext[MAXEXT];
                int flags;

                s=getenv("COMSPEC"); /* get the comspec environment parameter */
                flags=fnsplit(s,drive,dir,file,ext);

                printf("Command processor info:\n");
                if(flags & DRIVE)
                   printf("\tdrive: %s\n",drive);
                if(flags & DIRECTORY)
                   printf("\tdirectory: %s\n",dir);
                if(flags & FILENAME)
                   printf("\tfile: %s\n",file);
                if(flags & EXTENSION)
                   printf("\textension: %s\n",ext);

                return 0;
            }
             

             

             

            fseek
            開放分類: 計算機語言、計算機技術、編程、程序、函數

            函數名: fseek
            功  能: 重定位流上的文件指針
            用  法: int fseek(FILE *stream, long offset, int fromwhere);
            程序例:

            #include <stdio.h>

            long filesize(FILE *stream);

            int main(void)
            {
               FILE *stream;

               stream = fopen("MYFILE.TXT", "w+");
               fprintf(stream, "This is a test");
               printf("Filesize of MYFILE.TXT is %ld bytes\n", filesize(stream));
               fclose(stream);
               return 0;
            }

            long filesize(FILE *stream)
            {
               long curpos, length;

               curpos = ftell(stream);
               fseek(stream, 0L, SEEK_END);
               length = ftell(stream);
               fseek(stream, curpos, SEEK_SET);
               return length;
            }


            int fseek( FILE *stream, long offset, int origin );
            第一個參數stream為文件指針,offset為偏移,比如你要從文件的第10000個字節開始讀取的話,offset就應該為10000,origin 為標志是從文件開始還是末尾。
            origin 的取值:
            SEEK_CUR Current position of file pointer
            SEEK_END End of file
            SEEK_SET Beginning of file
            那么fseek(fp,-size,1)中-size和1是否應理解為,從文件倒說第一個文件開始讀取
            fseek最后一個參數最好不要直接指定一個數值,比如1,
            要使用SEEK_CUR,SEEK_END,SEEK_SET
            第二個參數表示相對于第三個參數的偏移,整數表示正向偏移,負數表示負向偏移,比如
            fseek(fp,-size,SEEK_CUR);
            從當前位置向文件后方(比如文件有123三個數字,那么2在三的后方,3在2的前方)
            fseek(fp,size,SEEK_SET);
            從文件開始位置向前移動size


            這里默認size是正數
             

             

             

             

            fwrite
            開放分類: 計算機語言、計算機技術、編程、程序、函數

            函數名: fwrite
            功  能: 寫內容到流中
            用  法:fwrite(buffer,size,count,fp);
              (1)buffer:是一個指針,對fwrite來說,是要輸出數據的地址。
              (2)size:要讀寫的字節數;
              (3)count:要進行讀寫多少個size字節的數據項;
              (4)fp:文件型指針。
            程序例:

            #include <stdio.h>

            struct mystruct
            {
              int i;
              char ch;
            };

            int main(void)
            {
               FILE *stream;
               struct mystruct s;

               if ((stream = fopen("TEST.$$$", "wb")) == NULL) /* open file TEST.$$$ */
               {
                  fprintf(stderr, "Cannot open output file.\n");
                  return 1;
               }
               s.i = 0;
               s.ch = 'A';
               fwrite(&s, sizeof(s), 1, stream); /* write struct s to file */
               fclose(stream); /* close file */
               return 0;
            }
             

             

             

             


            fread
            開放分類: 計算機語言、計算機技術、編程、程序、函數

            函數名: fread
            功  能: 從一個流中讀數據
            用  法: int fread(void *ptr, int size, int nitems, FILE *stream);
            參  數:用于接收數據的地址(字符型指針)(ptr)
                    單個元素的大小(size)
                    元素個數(nitems)
                    提供數據的文件指針(stream)
            返回值:成功讀取的元素個數


            程序例:

            #include <string.h>
            #include <stdio.h>

            int main(void)
            {
               FILE *stream;
               char msg[] = "this is a test";
               char buf[20];

               if ((stream = fopen("DUMMY.FIL", "w+"))
                   == NULL)
               {
                  fprintf(stderr,
                          "Cannot open output file.\n");
                  return 1;
               }

               /* write some data to the file */
               fwrite(msg, strlen(msg)+1, 1, stream);

               /* seek to the beginning of the file */
               fseek(stream, SEEK_SET, 0);

               /* read the data and display it */
               fread(buf, 1, strlen(msg)+1, stream);
               printf("%s\n", buf);

               fclose(stream);
               return 0;
            }

             

             

             

             

             

            FindFirstFile

            void CFindFilesDlg::OnBnClickedButton1()
            {
             // TODO: 在此添加控件通知處理程序代碼
             CString c1;
             CString stredit;
             CString strtemp;
             HANDLE hFile;
             WIN32_FIND_DATA fileinfo;
             DWORD errorcode = 0;
             m_Edit1.GetWindowText(c1);   //要熟悉控件的基本使用
             if(!c1.IsEmpty())
             {
                   hFile=FindFirstFile("f:\\*.*",&fileinfo);
                while(hFile!=INVALID_HANDLE_VALUE&&errorcode!=ERROR_NO_MORE_FILES)
                {
                 //
               strtemp=fileinfo.cFileName;
               stredit=stredit+"\r\n";
               stredit=stredit+strtemp;
               FindNextFile(hFile,&fileinfo);
               errorcode=GetLastError();
                }
                if(errorcode==ERROR_NO_MORE_FILES)
                {
                 m_cedit1.SetWindowText(stredit);
                 MessageBox("檢索結束");
                }
                CloseHandle(hFile);
             }
            }


            在上述代碼中

            FindFirstFile第一個個參數需要一個路徑,但要寫*.*,表示從所有文件中找到的第一個.但寫f:或者f:雙斜杠都返回無效句柄.

            如果f:\\1.txt 則對特定文件進行搜索,返回找到的第一個

            找到的文件的文件結構被記錄在WIN32_FIND_DATA結構體里

            FindNextFile第一個參數是FindFirstFile的返回值,可以接著上次結果繼續尋找

            但注意!!!!

            但一個目錄的文件被搜索一遍后,FindNextFile返回的WIN32_FIND_DATA結構體將重復找到最后一個找到的文件,而不會終止.

            讓循環結束的方法就是找上一次的報錯碼,然后看有沒有ERROR_NO_MORE_FILES信息發生.

            hFile的有效與否個人覺得還是取決于第一次的FindFirstFile結果,本程序后半段的運行主要還是errorcode!=ERROR_NO_MORE_FILES在控制.

             

             

             


             


             一、 內聯匯編的一般原則:

            1、 自由使用通用寄存器;(EAX,EBX,ECX和EDX)
            2、 其它寄存器利用堆棧保留,使用,最后恢復;
            一般的像下面這樣:

            __asm{
             push ebp
             push esp
             ……….//使用EBP和ESP
             pop esp
             pop ebp
            }

             二、 內聯匯編__asm可以單獨使用:
            例如:__asm mov eax,anyval1
            __asm mov ebx,anyval2

             三、 函數返回值可以直接放到eax中,可以不理會警告
            例如: int anyfun(……/*anyparm*/)
            {
             int irtn; //函數返回值
             ……        //函數語句
             __asm mov eax,irtn    //代替return irtn;但編譯器會發出警告,可以不理它
            }

             四、 內聯匯編不區分大小寫,語法同普通匯編

            例如:__asm{
             mov eax,ebx
             MOV EAX,EBX  //同上一句
            }

            注意:C++的變量還是區分大小寫的

             五、 內聯匯編盡量使用__asm或_asm關鍵字,而不用標準C++的asm關鍵字(這個是微軟說的)
            以上只是一些關于內聯匯編的補充,我將出一系列圍繞內聯匯編的文章,下面接著上一次的話題詳細一點地講一下MMX指令的調用

            1、 MMX指令集簡介:

            [數據傳輸指令]
            movq //傳輸64位整數
            movd //傳輸32位整數

            [數據打包轉換指令]
            PACKSSWB //Pack words into bytes with signed saturation.
            PACKSSDW //Pack doublewords into words with signed saturation.
            PACKUSWB //Pack words into bytes with unsigned saturation.
            PUNPCKHBW //Unpack high-order bytes.
            PUNPCKHWD //Unpack high-order words.
            PUNPCKHDQ //Unpack high-order doublewords.
            PUNPCKLBW //Unpack low-order bytes.
            PUNPCKLWD //Unpack low-order words.
            PUNPCKLDQ //Unpack low-order doublewords.
            注:這一組指令我沒有具體用過,不知道是干什么的,請高手賜教!小弟先謝了!

            [ 算術指令]
            PADDB
            PADDW
            PADDD
            PADDSB
            PADDSW
            PADDUSB
            PADDUSW
            PSUBB
            PSUBW
            PSUBD
            PSUBSB
            PSUBSW
            PSUBUSB
            PSUBUSW
            PMULHW
            PMULLW
            PMADDWD

            [ 比較指令]
            PCMPEQB Compare packed bytes for equal.
            PCMPEQW Compare packed words for equal.
            PCMPEQD Compare packed doublewords for equal.
            PCMPGTB Compare packed signed byte integers for greater than.
            PCMPGTW Compare packed signed word integers for greater than.
            PCMPGTD Compare packed signed doubleword integers for greater than.
            這組指令用于成組比較數據

            [ 位邏輯指令]
            PAND Bitwise logical AND.
            PANDN Bitwise logical AND NOT.
            POR Bitwise logical OR.
            PXOR Bitwise logical exclusive OR.
            這組指令與AND,XOR基本相同,都是按位進行邏輯運算。

            [ 移位和循環移位指令]
            PSLLW //Shift packed words left logical.
            PSLLD //Shift packed doublewords left logical.
            PSLLQ //Shift packed quadword left logical.
            PSRLW //Shift packed words right logical.
            PSRLD //Shift packed doublewords right logical.
            PSRLQ //Shift packed quadword right logical.
            PSRAW //Shift packed words right arithmetic.
            PSRAD //Shift packed doublewords right arithmetic.

            [ 狀態管理指令]
            EMMS //Empty MMX state.
            在VC中要求所有的MMX指令調用完畢后都要調用這個指令清空
            例如:__asm{
             …..MMX 語句
             EMMS   //清空狀態
            }

            以上是所有的MMX指令,你可以測試使用其中的指令,他的工作原理就是單指令,多數據
            2、 使用MMX指令集的注意事項

            由于在CPU內部,FPU寄存器和MMX寄存器是同一組寄存器,所以在同時引用上面寄存器時要注意正確的狀態轉換,具體做法以后在探討。你只要先記住不能簡單的混合以上兩種指令集即可。
            每次調用之前要先檢測cpu是否支持MMX指令集,以免發生異常。具體做法看下列示例:


            mov EAX, 1 ; request for feature flags
            CPUID ; 0Fh, 0A2h CPUID instruction
            test EDX, 00800000h ; Is IA MMX technology bit (Bit 23 of EDX)
            ; in feature flags set?
            jnz MMX_Technology_Found

            這段代碼來自Intel的參考手冊,所以你可以放心的使用。

            3、 下面用一段示例代碼來說明一下怎樣用MMX指令 __int8 i8_a[2][16];  //字節操作數,兩組,每組16個
             __int16 i16_a[8];   //字操作數
             __int32 i32_a[4];
             __int64 i64_a[2];

             i64_a[0]=0;
             i64_a[1]=0;

             i32_a[0]=1000;
             i32_a[1]=1000;
             i32_a[2]=3;
             i32_a[3]=4;

             i16_a[0]=10;
             i16_a[1]=20;
             i16_a[2]=30;
             i16_a[3]=40;
             i16_a[4]=50;
             i16_a[5]=60;
             i16_a[6]=70;
             i16_a[7]=80;
             
             i8_a[0][0]=1;
             i8_a[0][1]=1;
             i8_a[0][2]=1;
             i8_a[0][3]=1;
             i8_a[0][4]=1;
             i8_a[0][5]=1;
             i8_a[0][6]=1;
             i8_a[0][7]=1;
             i8_a[0][8]=1;
             i8_a[0][9]=1;
             i8_a[0][10]=1;
             i8_a[0][11]=1;
             i8_a[0][12]=1;
             i8_a[0][13]=1;
             i8_a[0][14]=1;
             i8_a[0][15]=1;

             i8_a[1][0]=2;
             i8_a[1][1]=2;
             i8_a[1][2]=2;
             i8_a[1][3]=2;
             i8_a[1][4]=2;
             i8_a[1][5]=2;
             i8_a[1][6]=2;
             i8_a[1][7]=2;
             i8_a[1][8]=2;
             i8_a[1][9]=2;
             i8_a[1][10]=2;
             i8_a[1][11]=2;
             i8_a[1][12]=2;
             i8_a[1][13]=2;
             i8_a[1][14]=2;
             i8_a[1][15]=2;

             __asm{
              movq mm1,[i64_a]
              movq mm2,[i64_a]
              
              movq mm2, [i32_a+8]
              psubd mm2, [i32_a]
              movq [i32_a],mm2
              
              movq mm1,[i16_a]
              paddsw mm1,[i16_a+8]
              movq [i16_a],mm1

              movq mm1,[i8_a]
              movq mm2,[i8_a+8]
              paddb mm1,[i8_a+16]
              paddb mm2,[i8_a+24]
              movq [i8_a],mm1
              movq [i8_a+8],mm2
              
              emms   //最后清除MMX狀態寄存器,正確返回給系統
             }


            你可以通過設置斷點,和watch的方法來觀察寄存器以及變量的變化情況,這里只是引用了一部分的指令,那么最引人注意的是對i16_a、i8_a、以及i32_a數組的操作,我是隨便對他們進行了算術運算,大家可以看到我加兩組字節數組數據時只用了兩條加指令,這是普通的指令集望塵莫及的。這就是單指令,多數據的魅力。同時你也可以看到對64位整數的操作也簡單多了。但是要注意的是,MMX指令集里好像沒有提供除法操作。所以你需借助算法來實現。另外要補充的是MMX寄存器是從MM0-MM7命名的一組64位寄存器。



            sscanf
            開放分類: c函數

            名稱:
            sscanf() - 從一個字符串中讀進與指定格式相符的數據.
            函數原型:
            Int  sscanf( string str, string fmt, mixed var1, mixed var2 ... );
            int  scanf( const char *format [,argument]... );
            說明:
            sscanf與scanf類似,都是用于輸入的,只是后者以屏幕(stdin)為輸入源,前者以固定字符串為輸入源。
            其中的format可以是一個或多個 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符號}
            注:
            1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星號 (*) 表示跳過此數據不讀入. (也就是不把此數據讀入參數中)
            2、{a|b|c}表示a,b,c中選一,[d],表示可以有d也可以沒有d。
            3、width表示讀取寬度。
            4、{h | l | I64 | L}:參數的size,通常h表示單字節size,I表示2字節 size,L表示4字節size(double例外),l64表示8字節size。
            5、type :這就很多了,就是%s,%d之類。
            6、特別的:%*[width] [{h | l | I64 | L}]type 表示滿足該條件的被過濾掉,不會向目標參數中寫入值
              
            支持集合操作:

                 %[a-z] 表示匹配a到z中任意字符,貪婪性(盡可能多的匹配)

                 %[aB'] 匹配a、B、'中一員,貪婪性

                 %[^a] 匹配非a的任意字符,貪婪性

            例子:
            1. 常見用法。
                char buf[512] = ;
                sscanf("123456 ", "%s", buf);
            printf("%s\n", buf);

            結果為:123456

            2. 取指定長度的字符串。如在下例中,取最大長度為4字節的字符串。
                sscanf("123456 ", "%4s", buf);
            printf("%s\n", buf);

            結果為:1234

            3. 取到指定字符為止的字符串。如在下例中,取遇到空格為止字符串。
                sscanf("123456 abcdedf", "%[^ ]", buf);
            printf("%s\n", buf);

            結果為:123456

            4.  取僅包含指定字符集的字符串。如在下例中,取僅包含1到9和小寫字母的字符串。
                sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
            printf("%s\n", buf);

            結果為:123456abcdedf

            5.  取到指定字符集為止的字符串。如在下例中,取遇到大寫字母為止的字符串。
                sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
            printf("%s\n", buf);

            結果為:123456abcdedf
              
            6、給定一個字符串iios/12DDWDFF@122,獲取 / 和 @ 之間的字符串,先將 "iios/"過濾掉,再將非'@'的一串內容送到buf中
            sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
            printf("%s\n", buf);

            結果為:12DDWDFF

            7、給定一個字符串““hello, world”,僅保留world。(注意:“,”之后有一空格)
            sscanf(“hello, world”,  "%*s%s",  buf);   
            printf("%s\n", buf);

            結果為:world

            %*s表示第一個匹配到的%s被過濾掉,即hello被過濾了

            如果沒有空格則結果為NULL。

            sscanf的功能很類似于正則表達式, 但卻沒有正則表達式強大,所以如果對于比較復雜的字符串處理,建議使用正則表達式.
            //-------------------------------------------------------
            sscanf,表示從字符串中格式化輸入
            上面表示從str中,輸入數字給x,就是32700
            久以前,我以為c沒有自己的split string函數,后來我發現了sscanf;一直以來,我以為sscanf只能以空格來界定字符串,現在我發現我錯了。
            sscanf是一個運行時函數,原形很簡單:
            int sscanf(
            const char *buffer,
            const char *format [,
            argument ] ...
            );
            它強大的功能體現在對format的支持上。
            我以前用它來分隔類似這樣的字符串2006:03:18:
            int a, b, c;
            sscanf("2006:03:18", "%d:%d:%d", a, b, c);
            以及2006:03:18 - 2006:04:18:
            char sztime1[16] = "", sztime2[16] = "";
            sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2);
            但是后來,我需要處理2006:03:18-2006:04:18
            僅僅是取消了‘-’兩邊的空格,卻打破了%s對字符串的界定。
            我需要重新設計一個函數來處理這樣的情況?這并不復雜,但是,為了使所有的代碼都有統一的風格,我需要改動很多地方,把已有的sscanf替換成我自己的分割函數。我以為我肯定需要這樣做,并伴隨著對sscanf的強烈不滿而入睡;一覺醒來,發現其實不必。
            format-type中有%[]這樣的type field。如果讀取的字符串,不是以空格來分隔的話,就可以使用%[]。
            %[]類似于一個正則表達式。[a-z]表示讀取a-z的所有字符,[^a-z]表示讀取除a-z以外的所有字符。
            所以那個問題也就迎刃而解了:
            sscanf("2006:03:18 - 2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2);
            在softmse (Jake) 的問題貼http://community.csdn.net/Expert/topic/4843/4843294.xml?temp=.4321558中 ,周星星給出了一個很cool的sscanf用例,而后通過學習,發現sscanf真棒,現做一總結。
            原問題:
            iios/12DDWDFF@122
            獲取/和@之間的字符串怎么做
            C程序里面有什么函數嗎?
            周星星的代碼:
            #include <stdio.h>
            int main()
            {
            const char* s = "iios/12DDWDFF@122";
            char buf[20];
            sscanf( s, "%*[^/]/%[^@]", buf );
            printf( "%s\n", buf );
            return 0;
            }
            結果為:12DDWDFF
            sscanf與scanf類似,都是用于輸入的,只是后者以屏幕(stdin)為輸入源,前者以固定字符串為輸入源。
            函數原型:
            int scanf( const char *format [,argument]... );
            其中的format可以是一個或多個 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符號},
            注:{a|b|c}表示a,b,c中選一,[d],表示可以有d也可以沒有d。

            width:寬度,一般可以忽略,用法如:
            const char sourceStr[] = "hello, world";
            char buf[10] = ;
            sscanf(sourceStr, "%5s", buf); //%5s,只取5個字符
            cout << buf<< endl;
            結果為:hello
            {h | l | I64 | L}:參數的size,通常h表示單字節size,I表示2字節 size,L表示4字節size(double例外),l64表示8字節size。
            type :這就很多了,就是%s,%d之類。

            特別的:
            %*[width] [{h | l | I64 | L}]type 表示滿足該條件的被過濾掉,不會向目標參數中寫入值。如:
            const char sourceStr[] = "hello, world";
            char buf[10] = ;
            sscanf(sourceStr, "%*s%s", buf); //%*s表示第一個匹配到的%s被過濾掉,即hello被過濾了
            cout << buf<< endl;
            結果為:world
            支持集合操作:
            %[a-z] 表示匹配a到z中任意字符,貪婪性(盡可能多的匹配)
            %[aB'] 匹配a、B、'中一員,貪婪性
            %[^a] 匹配非a的任意字符,貪婪性
            是不是感覺眼熟了啊,不錯,這和正則表達式很相似,而且仍然支持過濾,即可以有%*[a-z].如:
            星星大哥例子回顧:
            const char* s = "iios/12DDWDFF@122";
            char buf[20];
            sscanf( s, "%*[^/]/%[^@]", buf );
            printf( "%s\n", buf );
            先將 "iios/"過濾掉,再將非'@'的一串內容送到buf中,cool.得到結果。
            PS: 向星星大哥和softmse (Jake) 致謝了,有了你們才有它啊

             

            posted @ 2008-08-19 09:14 clcl 閱讀(405) | 評論 (0)編輯 收藏








               第一篇文章不知道寫什么,就當是對我入行幾個月的一個save吧,第一個項目,2D的地圖編輯器,3個人一起做的(主程有先搭個框架),我負責的是用OGRE在視圖中顯示地形和物件管理還有阻擋等,后來還做了機器人的尋路,資源暫時用的是魔獸(覺得美工做的地形的圖沒有魔獸的美 =  = |||)。
               OGRE確實是好東西,不過可能是不夠熟悉的原因吧,經常被小問題還有沒有考慮到的因素絆了好久,又是上網搜又是群里問才解決。
               額· · · 實在不知道說什么,先這樣吧,以后慢慢補充·   ·  ·

            PS:關于兩個房子是透明的是因為我在調試OGRE的材質里的PASS 中設置ALPHA通道的幾個參數
            posted @ 2008-08-18 22:36 clcl 閱讀(400) | 評論 (2)編輯 收藏

            僅列出標題
            共2頁: 1 2 
            久久精品麻豆日日躁夜夜躁| 久久久久18| 久久发布国产伦子伦精品 | 久久久久亚洲AV片无码下载蜜桃| 亚洲AV无码一区东京热久久| 久久久91精品国产一区二区三区| 久久av高潮av无码av喷吹| 97精品依人久久久大香线蕉97 | 国产精品视频久久| 国产综合免费精品久久久| 亚洲AV日韩AV永久无码久久| 91精品国产高清久久久久久91| 久久精品国产AV一区二区三区| 青青青青久久精品国产| 亚洲精品乱码久久久久久蜜桃图片| 国内精品久久久久久中文字幕| 久久久婷婷五月亚洲97号色| 久久99这里只有精品国产| 久久婷婷久久一区二区三区| 久久综合香蕉国产蜜臀AV| 久久久久久久91精品免费观看| 国内精品久久久久影院网站| 国内精品久久久久影院免费| 久久国产热精品波多野结衣AV| 久久婷婷色香五月综合激情| 看全色黄大色大片免费久久久| 中文字幕亚洲综合久久2| 久久人爽人人爽人人片AV| 青青草原综合久久大伊人| 久久精品无码一区二区三区免费| 久久综合久久综合久久| 久久精品亚洲精品国产色婷| 日韩精品久久无码人妻中文字幕| 国内精品久久久久影院亚洲| 亚洲?V乱码久久精品蜜桃| 久久亚洲视频| 日本精品一区二区久久久| 久久久久亚洲av成人无码电影| 久久久精品国产亚洲成人满18免费网站 | 亚洲欧美久久久久9999| 久久青青草视频|