• <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>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

                 摘要: 原文:http://ideapad.zol.com.cn/56/160_557421.html本樓層 是虛擬機(jī)設(shè)置貼子一樓是 Mac安裝帖子二樓是 工具下載位置,希望童鞋不要和我搶沙發(fā)神舟A560P i7-D2(Windows 7 X64環(huán)境下,VMware 8.0正式版)虛擬機(jī)首嘗MAC OS X 10.7 Lion系統(tǒng)成功,特將此好消息分享。2年了,終于我也裝上了Mac,我也成功的嘗...  閱讀全文

            posted @ 2012-04-07 07:30 RTY 閱讀(1466) | 評(píng)論 (0)編輯 收藏

            今天偶然寫了下面的程序(原來(lái)我寫的程序不一樣,下面的只是為了把問(wèn)題簡(jiǎn)化)

             

            1. void foo()  
            2. {  
            3.     int p = 0;  
            4.     if ( p == 0 )  
            5.         int i = 0;  
            6.     int a;  
            7. }  
            8.   
            9. int main()  
            10. {  
            11.     foo();  
            12. }  
              本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/fancylea/archive/2009/06/10/4256793.aspx 

             

             

            不幸的是偶然將這個(gè)文件保存成了test.c,然后編譯的時(shí)候出現(xiàn)了

             

            error, error C2143: syntax error : missing ';' before 'type'

             

            感覺(jué)很奇怪,細(xì)細(xì)看來(lái)所有的語(yǔ)法都似乎都是對(duì)的,更奇怪的是把文件改成cpp或者cc能正常編譯,把int a;和if調(diào)換下也能正常編譯。這樣的錯(cuò)誤可能發(fā)生在當(dāng)變量的聲明放在可執(zhí)行代碼之后。而這個(gè)是在K&R C中規(guī)定的,但在ANSI C中廢除。

            MSDN (http://support.microsoft.com/kb/58559)給出的解釋如下:

             


             

            In Microsoft C, compiler errors C2143 and C2144 are defined as follows:

                C2143: syntax error : missing 'token1' before 'token2'
                C2144: syntax error : missing 'token' before type 'type'

             

            You may receive this error message if your program places executable code before a data declaration, an acceptable practice in Kernighan-and-Ritchie C. This practice has been outlawed in later versions of the ANSI drafts. 

            This error message will normally occur if a required closing curly brace (}), right parenthesis [)], or semicolon (;) is missing.


             

            注: The C Programming Language的作者簡(jiǎn)稱K&R,也是C語(yǔ)言之父, 經(jīng)常用K&R C來(lái)和ANSI C做對(duì)比。這本書的第二版已經(jīng)用ANSI.

            我用的編譯器是VS2008, 看來(lái)微軟向來(lái)無(wú)視標(biāo)準(zhǔn)。

             

            總結(jié):

            在 ANSI C或者C++中,在可執(zhí)行代碼中隨時(shí)定義變量是允許的,但是在K&R C中是不允許的,VS2008實(shí)現(xiàn)的C竟然是K&R C。注意這樣的錯(cuò)誤也體現(xiàn)在VS中要是用for (int i = 0; i++; i<10)同時(shí)你的文件名是.c的也會(huì)出現(xiàn)這樣的錯(cuò)誤。

             

            Code complete中討論過(guò)變量名的最遲綁定有利于增加代碼的可讀性等。所以在VS中寫c要注意了。

            posted @ 2012-04-05 19:53 RTY 閱讀(1875) | 評(píng)論 (0)編輯 收藏

            請(qǐng)說(shuō)出const與#define 相比,有何優(yōu)點(diǎn)?
            答案:
            1) const 常量有數(shù)據(jù)類型,而宏常量沒(méi)有數(shù)據(jù)類型。編譯器可以對(duì)前者進(jìn)行類型安全檢查。而對(duì)后者只進(jìn)行字符替換,沒(méi)有類型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意料不到的錯(cuò)誤。
                  2) 有些集成化的調(diào)試工具可以對(duì)const 常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試。

            在8086 匯編下,邏輯地址和物理地址是怎樣轉(zhuǎn)換的?(Intel)
            答案:通用寄存器給出的地址,是段內(nèi)偏移地址,相應(yīng)段寄存器地址*10H+通用寄存器內(nèi)地址,就得到了真正要訪問(wèn)的地址。

            當(dāng)一個(gè)類A 中沒(méi)有生命任何成員變量與成員函數(shù),這時(shí)sizeof(A)的值是多少,如果不是零,請(qǐng)解釋一下編譯器為什么沒(méi)有讓它為零。(Autodesk)
            答案:肯定不是零。舉個(gè)反例,如果是零的話,聲明一個(gè)class A[10]對(duì)象數(shù)組,而每一個(gè)對(duì)象占用的空間是零,這時(shí)就沒(méi)辦法區(qū)分A[0],A[1]…了。

             描述內(nèi)存分配方式以及它們的區(qū)別?
            1) 從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static 變量
            2) 在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集。
            3) 從堆上分配亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc 或new 申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free 或delete 釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活,但問(wèn)題也最多。

             main 函數(shù)執(zhí)行以前,還會(huì)執(zhí)行什么代碼?
            答案:全局對(duì)象的構(gòu)造函數(shù)會(huì)在main 函數(shù)之前執(zhí)行。

             C++是不是類型安全的?
            答案:不是。兩個(gè)不同類型的指針之間可以強(qiáng)制轉(zhuǎn)換(用reinterpret cast)。C#是類型安全的。

             

            有哪幾種情況只能用intialization list 而不能用assignment?

             

            答案:當(dāng)類中含有const、reference 成員變量;基類的構(gòu)造函數(shù)都需要初始化表。

            define DOUBLE(x) x+x ,i = 5*DOUBLE(5); i 是多少?
            答案:i 為30

            New delete 與malloc free 的聯(lián)系與區(qū)別?
            答案:都是在堆(heap)上進(jìn)行動(dòng)態(tài)的內(nèi)存操作。用malloc函數(shù)需要指定內(nèi)存分配的字節(jié)數(shù)并且不能初始化對(duì)象,new 會(huì)自動(dòng)調(diào)用對(duì)象的構(gòu)造函數(shù)。delete 會(huì)調(diào)用對(duì)象的destructor,而free 不會(huì)調(diào)用對(duì)象的destructor.

             

            1、寫一個(gè)“標(biāo)準(zhǔn)”宏,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。
            .#define Min(X, Y) ((X)>(Y)?(Y):(X))//結(jié)尾沒(méi)有;
            2、嵌入式系統(tǒng)中經(jīng)常要用到無(wú)限循環(huán),你怎么用C編寫死循環(huán)。
            while(1){}或者for(;;)
            3、關(guān)鍵字static的作用是什么?
            定義靜態(tài)變量
            4、關(guān)鍵字const有什么含意?
            表示常量不可以修改的變量。
            5、關(guān)鍵字volatile有什么含意?并舉出三個(gè)不同的例子?
            提示編譯器對(duì)象的值可能在編譯器未監(jiān)測(cè)到的情況下改變。

             


            int (*s[10])(int) 表示的是什么啊
            int (*s[10])(int) 函數(shù)指針數(shù)組,每個(gè)指針指向一個(gè)int func(int param)的函數(shù)。

             


            1.有以下表達(dá)式:
            int a=248; b=4;int const c=21;const int *d=&a;
            int *const e=&b;int const *f const =&a;
            請(qǐng)問(wèn)下列表達(dá)式哪些會(huì)被編譯器禁止?為什么?
            *c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
            *c 這是個(gè)什么東東,禁止
            *d 說(shuō)了是const, 禁止
            e = &a 說(shuō)了是const 禁止
            const *f const =&a; 禁止
            2.交換兩個(gè)變量的值,不使用第三個(gè)變量。即a=3,b=5,交換之后a=5,b=3;
            有兩種解法, 一種用算術(shù)算法, 一種用^(異或)
            a = a + b;
            b = a - b;
            a = a - b; 
            or
            a = a^b;// 只能對(duì)int,char..
            b = a^b;
            a = a^b;
            or
            a ^= b ^= a;
            3.c和c++中的struct有什么不同?
            c和c++中struct的主要區(qū)別是c中的struct不可以含有成員函數(shù),而c++中的struct可以。c++中struct和class的主要區(qū)別在于默認(rèn)的存取權(quán)限不同,struct默認(rèn)為public,而class默認(rèn)為private
            4.#i nclude <stdio.h>
            #i nclude <stdlib.h>
            void getmemory(char *p)
            {
                p=(char *) malloc(100);
                strcpy(p,"hello world");
            }
            int main( )
            {
                char *str=NULL;
                getmemory(str);
                printf("%s/n",str);
                free(str);
                return 0;
               }
            程序崩潰,getmemory中的malloc 不能返回動(dòng)態(tài)內(nèi)存, free()對(duì)str操作很危險(xiǎn)
            5.char szstr[10];
            strcpy(szstr,"0123456789");
            產(chǎn)生什么結(jié)果?為什么?
            長(zhǎng)度不一樣,會(huì)造成非法的OS
            6.列舉幾種進(jìn)程的同步機(jī)制,并比較其優(yōu)缺點(diǎn)。
               原子操作 
            信號(hào)量機(jī)制
               自旋鎖
               管程,會(huì)合,分布式系統(tǒng)

             

            7.進(jìn)程之間通信的途徑
            共享存儲(chǔ)系統(tǒng)
            消息傳遞系統(tǒng)
            管道:以文件系統(tǒng)為基礎(chǔ)
            11.進(jìn)程死鎖的原因
            資源競(jìng)爭(zhēng)及進(jìn)程推進(jìn)順序非法
            12.死鎖的4個(gè)必要條件
            互斥、請(qǐng)求保持、不可剝奪、環(huán)路
            13.死鎖的處理
            鴕鳥策略、預(yù)防策略、避免策略、檢測(cè)與解除死鎖
            15.   操作系統(tǒng)中進(jìn)程調(diào)度策略有哪幾種?
            FCFS(先來(lái)先服務(wù)),優(yōu)先級(jí),時(shí)間片輪轉(zhuǎn),多級(jí)反饋
            8.類的靜態(tài)成員和非靜態(tài)成員有何區(qū)別?
            類的靜態(tài)成員每個(gè)類只有一個(gè),非靜態(tài)成員每個(gè)對(duì)象一個(gè)
            9.純虛函數(shù)如何定義?使用時(shí)應(yīng)注意什么?
            virtual void f()=0;
            是接口,子類必須要實(shí)現(xiàn)
            10.數(shù)組和鏈表的區(qū)別
            數(shù)組:數(shù)據(jù)順序存儲(chǔ),固定大小
            連表:數(shù)據(jù)可以隨機(jī)存儲(chǔ),大小可動(dòng)態(tài)改變

             

            12.ISO的七層模型是什么?tcp/udp是屬于哪一層?tcp/udp有何優(yōu)缺點(diǎn)?
            應(yīng)用層
            表示層
            會(huì)話層
            運(yùn)輸層
            網(wǎng)絡(luò)層
            物理鏈路層
            物理層
            tcp /udp屬于運(yùn)輸層
            TCP 服務(wù)提供了數(shù)據(jù)流傳輸、可靠性、有效流控制、全雙工操作和多路復(fù)用技術(shù)等。
            與 TCP 不同, UDP 并不提供對(duì) IP 協(xié)議的可靠機(jī)制、流控制以及錯(cuò)誤恢復(fù)功能等。由于 UDP 比較簡(jiǎn)單, UDP 頭包含很少的字節(jié),比 TCP 負(fù)載消耗少。
            tcp: 提供穩(wěn)定的傳輸服務(wù),有流量控制,缺點(diǎn)是包頭大,冗余性不好
            udp: 不提供穩(wěn)定的服務(wù),包頭小,開(kāi)銷小  

             


            1:(void *)ptr 和 (*(void**))ptr的結(jié)果是否相同?其中ptr為同一個(gè)指針
            .(void *)ptr 和 (*(void**))ptr值是相同的
            2:int main()
               {
                int x=3;
                printf("%d",x);
                return 1;
               
               }
            問(wèn)函數(shù)既然不會(huì)被其它函數(shù)調(diào)用,為什么要返回1?
            mian中,c標(biāo)準(zhǔn)認(rèn)為0表示成功,非0表示錯(cuò)誤。具體的值是某中具體出錯(cuò)信息

             


            1,要對(duì)絕對(duì)地址0x100000賦值,我們可以用
            (unsigned int*)0x100000 = 1234;
            那么要是想讓程序跳轉(zhuǎn)到絕對(duì)地址是0x100000去執(zhí)行,應(yīng)該怎么做?
            *((void (*)( ))0x100000 ) ( );
            首先要將0x100000強(qiáng)制轉(zhuǎn)換成函數(shù)指針,即:
            (void (*)())0x100000
            然后再調(diào)用它:
            *((void (*)())0x100000)();
            用typedef可以看得更直觀些:
            typedef void(*)() voidFuncPtr;
            *((voidFuncPtr)0x100000)();
            2,已知一個(gè)數(shù)組table,用一個(gè)宏定義,求出數(shù)據(jù)的元素個(gè)數(shù)
            #define NTBL
            #define NTBL (sizeof(table)/sizeof(table[0]))

             

            面試題: 線程與進(jìn)程的區(qū)別和聯(lián)系? 線程是否具有相同的堆棧? dll是否有獨(dú)立的堆棧?
            進(jìn)程是死的,只是一些資源的集合,真正的程序執(zhí)行都是線程來(lái)完成的,程序啟動(dòng)的時(shí)候操作系統(tǒng)就幫你創(chuàng)建了一個(gè)主線程。

             

            每個(gè)線程有自己的堆棧。
            DLL中有沒(méi)有獨(dú)立的堆棧,這個(gè)問(wèn)題不好回答,或者說(shuō)這個(gè)問(wèn)題本身是否有問(wèn)題。因?yàn)镈LL中的代碼是被某些線程所執(zhí)行,只有線程擁有堆棧,如果DLL中的代碼是EXE中的線程所調(diào)用,那么這個(gè)時(shí)候是不是說(shuō)這個(gè)DLL沒(méi)有自己獨(dú)立的堆棧?如果DLL中的代碼是由DLL自己創(chuàng)建的線程所執(zhí)行,那么是不是說(shuō)DLL有獨(dú)立的堆棧?

             

            以上講的是堆棧,如果對(duì)于堆來(lái)說(shuō),每個(gè)DLL有自己的堆,所以如果是從DLL中動(dòng)態(tài)分配的內(nèi)存,最好是從DLL中刪除,如果你從DLL中分配內(nèi)存,然后在EXE中,或者另外一個(gè)DLL中刪除,很有可能導(dǎo)致程序崩潰

             


            unsigned short A = 10;
            printf("~A = %u\n", ~A);

             

            char c=128; 
            printf("c=%d\n",c);

             

            輸出多少?并分析過(guò)程
            第一題,~A =0xfffffff5,int值 為-11,但輸出的是uint。所以輸出4294967285
            第二題,c=0x10,輸出的是int,最高位為1,是負(fù)數(shù),所以它的值就是0x00的補(bǔ)碼就是128,所以輸出-128。
            這兩道題都是在考察二進(jìn)制向int或uint轉(zhuǎn)換時(shí)的最高位處理。

             

            分析下面的程序:
            void GetMemory(char **p,int num)
            {
                *p=(char *)malloc(num);
                
            }        
            int main()
            {
                char *str=NULL;
                
                GetMemory(&str,100);
                
                strcpy(str,"hello");
                
                free(str);
                
                if(str!=NULL)
                {
                    strcpy(str,"world");
                }    
                    
                printf("\n str is %s",str);
                getchar();
            }    
            問(wèn)輸出結(jié)果是什么?希望大家能說(shuō)說(shuō)原因,先謝謝了
            輸出str is world。
            free 只是釋放的str指向的內(nèi)存空間,它本身的值還是存在的.
            所以free之后,有一個(gè)好的習(xí)慣就是將str=NULL.
            此時(shí)str指向空間的內(nèi)存已被回收,如果輸出語(yǔ)句之前還存在分配空間的操作的話,這段存儲(chǔ)空間是可能被重新分配給其他變量的,
            盡管這段程序確實(shí)是存在大大的問(wèn)題(上面各位已經(jīng)說(shuō)得很清楚了),但是通常會(huì)打印出world來(lái)。
            這是因?yàn)椋M(jìn)程中的內(nèi)存管理一般不是由操作系統(tǒng)完成的,而是由庫(kù)函數(shù)自己完成的。
            當(dāng)你malloc一塊內(nèi)存的時(shí)候,管理庫(kù)向操作系統(tǒng)申請(qǐng)一塊空間(可能會(huì)比你申請(qǐng)的大一些),然后在這塊空間中記錄一些管理信息(一般是在你申請(qǐng)的內(nèi)存前面一點(diǎn)),并將可用內(nèi)存的地址返回。但是釋放內(nèi)存的時(shí)候,管理庫(kù)通常都不會(huì)將內(nèi)存還給操作系統(tǒng),因此你是可以繼續(xù)訪問(wèn)這塊地址的,只不過(guò)。。。。。。。。樓上都說(shuō)過(guò)了,最好別這么干。

             

            char a[10],strlen(a)為什么等于15?運(yùn)行的結(jié)果

             

            #i nclude "stdio.h"
            #i nclude "string.h"

             

            void main()
            {

             

            char aa[10];
            printf("%d",strlen(aa));
            }

             

            sizeof()和初不初始化,沒(méi)有關(guān)系;
            strlen()和初始化有關(guān)。

             


            char (*str)[20];/*str是一個(gè)數(shù)組指針,即指向數(shù)組的指針.*/
            char *str[20];/*str是一個(gè)指針數(shù)組,其元素為指針型數(shù)據(jù).*/

             

            long a=0x801010;
            a+5=?
            0x801010用二進(jìn)制表示為:“1000 0000 0001 0000 0001 0000”,十進(jìn)制的值為8392720,再加上5就是8392725羅

             

            1)給定結(jié)構(gòu)struct A 
            {
                   char t:4;
                   char k:4;
                   unsigned short i:8;
                   unsigned long m;
            };問(wèn)sizeof(A) = ?
            給定結(jié)構(gòu)struct A 
            {
                   char t:4; 4位
                   char k:4; 4位
                   unsigned short i:8; 8位      
                   unsigned long m; // 偏移2字節(jié)保證4字節(jié)對(duì)齊
            }; // 共8字節(jié)
            2)下面的函數(shù)實(shí)現(xiàn)在一個(gè)數(shù)上加一個(gè)數(shù),有什么錯(cuò)誤?請(qǐng)改正。
            int add_n ( int n )
            {
                static int i = 100;
                i += n;
                return i;
            }
            當(dāng)你第二次調(diào)用時(shí)得不到正確的結(jié)果,難道你寫個(gè)函數(shù)就是為了調(diào)用一次?問(wèn)題就出在 static上?

             


            // 幫忙分析一下
            #i nclude<iostream.h>
            #i nclude <string.h>
            #i nclude <malloc.h>
            #i nclude <stdio.h>
            #i nclude <stdlib.h>
            #i nclude <memory.h>
            typedef struct AA
            {
                    int b1:5;
                    int b2:2;
            }AA;
            void main()
            {
                    AA aa;
                    char cc[100];
                     strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
                   memcpy(&aa,cc,sizeof(AA));
                    cout << aa.b1 <<endl;
                    cout << aa.b2 <<endl;
            }
            答案是 -16和1
            首先sizeof(AA)的大小為4,b1和b2分別占5bit和2bit.
            經(jīng)過(guò)strcpy和memcpy后,aa的4個(gè)字節(jié)所存放的值是:
            0,1,2,3的ASC碼,即00110000,00110001,00110010,00110011
            所以,最后一步:顯示的是這4個(gè)字節(jié)的前5位,和之后的2位
            分別為:10000,和01
            因?yàn)閕nt是有正負(fù)之分  所以:答案是-16和1

             

            求函數(shù)返回值,輸入x=9999; 
            int func ( x )

                int countx = 0; 
                while ( x ) 
                { 
                    countx ++; 
                    x = x&(x-1); 
                } 
                return countx; 

            結(jié)果呢?
            知道了這是統(tǒng)計(jì)9999的二進(jìn)制數(shù)值中有多少個(gè)1的函數(shù),且有
            9999=9×1024+512+256+15

             

            9×1024中含有1的個(gè)數(shù)為2;
            512中含有1的個(gè)數(shù)為1;
            256中含有1的個(gè)數(shù)為1;
            15中含有1的個(gè)數(shù)為4;
            故共有1的個(gè)數(shù)為8,結(jié)果為8。
            1000 - 1 = 0111,正好是原數(shù)取反。這就是原理。
            用這種方法來(lái)求1的個(gè)數(shù)是很效率很高的。
            不必去一個(gè)一個(gè)地移位。循環(huán)次數(shù)最少。

             

            int a,b,c 請(qǐng)寫函數(shù)實(shí)現(xiàn)C=a+b ,不可以改變數(shù)據(jù)類型,如將c改為long int,關(guān)鍵是如何處理溢出問(wèn)題
            bool add (int a, int b,int *c)
            {
            *c=a+b;
            return (a>0 && b>0 &&(*c<a || *c<b) || (a<0 && b<0 &&(*c>a || *c>b)));
            }

             


            分析:
            struct bit 
            {   int a:3; 
                int b:2; 
                int c:3; 
            }; 
            int main() 

            bit s; 
            char *c=(char*)&s; 
               cout<<sizeof(bit)<<endl;
            *c=0x99;
               cout << s.a <<endl <<s.b<<endl<<s.c<<endl; 
                 int a=-1;
               printf("%x",a);
            return 0; 

            輸出為什么是
            4
            1
            -1
            -4
            ffffffff
            因?yàn)?x99在內(nèi)存中表示為 100 11 001 , a = 001, b = 11, c = 100
            當(dāng)c為有符合數(shù)時(shí), c = 100, 最高1為表示c為負(fù)數(shù),負(fù)數(shù)在計(jì)算機(jī)用補(bǔ)碼表示,所以c = -4;同理 
            b = -1;
            當(dāng)c為有符合數(shù)時(shí), c = 100,即 c = 4,同理 b = 3

             


            位域 :   
            有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié), 而只需占幾個(gè)或一個(gè)二進(jìn)制位。例如在存放一個(gè)開(kāi)關(guān)量時(shí),只有0和1 兩種狀態(tài), 用一位二進(jìn)位即可。為了節(jié)省存儲(chǔ)空間,并使處理簡(jiǎn)便,C語(yǔ)言又提供了一種數(shù)據(jù)結(jié)構(gòu),稱為“位域”或“位段”。所謂“位域”是把一個(gè)字節(jié)中的二進(jìn)位劃分為幾個(gè)不同的區(qū)域, 并說(shuō)明每個(gè)區(qū)域的位數(shù)。每個(gè)域有一個(gè)域名,允許在程序中按域名進(jìn)行操作。 這樣就可以把幾個(gè)不同的對(duì)象用一個(gè)字節(jié)的二進(jìn)制位域來(lái)表示。一、位域的定義和位域變量的說(shuō)明位域定義與結(jié)構(gòu)定義相仿,其形式為:     
            struct 位域結(jié)構(gòu)名     
            { 位域列表 };    
            其中位域列表的形式為: 類型說(shuō)明符 位域名:位域長(zhǎng)度     
            例如:     
            struct bs    
            {    
            int a:8;    
            int b:2;    
            int c:6;    
            };    
            位域變量的說(shuō)明與結(jié)構(gòu)變量說(shuō)明的方式相同。 可采用先定義后說(shuō)明,同時(shí)定義說(shuō)明或者直接說(shuō)明這三種方式。例如:     
            struct bs    
            {    
            int a:8;    
            int b:2;    
            int c:6;    
            }data;    
            說(shuō)明data為bs變量,共占兩個(gè)字節(jié)。其中位域a占8位,位域b占2位,位域c占6位。對(duì)于位域的定義尚有以下幾點(diǎn)說(shuō)明:   

             

            1. 一個(gè)位域必須存儲(chǔ)在同一個(gè)字節(jié)中,不能跨兩個(gè)字節(jié)。如一個(gè)字節(jié)所剩空間不夠存放另一位域時(shí),應(yīng)從下一單元起存放該位域。也可以有意使某位域從下一單元開(kāi)始。例如:     
            struct bs    
            {    
            unsigned a:4    
            unsigned :0 /*空域*/    
            unsigned b:4 /*從下一單元開(kāi)始存放*/    
            unsigned c:4    
            }    
            在這個(gè)位域定義中,a占第一字節(jié)的4位,后4位填0表示不使用,b從第二字節(jié)開(kāi)始,占用4位,c占用4位。   

             

            2. 由于位域不允許跨兩個(gè)字節(jié),因此位域的長(zhǎng)度不能大于一個(gè)字節(jié)的長(zhǎng)度,也就是說(shuō)不能超過(guò)8位二進(jìn)位。   

             

            3. 位域可以無(wú)位域名,這時(shí)它只用來(lái)作填充或調(diào)整位置。無(wú)名的位域是不能使用的。例如:     
            struct k    
            {    
            int a:1    
            int :2 /*該2位不能使用*/    
            int b:3    
            int c:2    
            };    
            從以上分析可以看出,位域在本質(zhì)上就是一種結(jié)構(gòu)類型, 不過(guò)其成員是按二進(jìn)位分配的。   

             

            二、位域的使用位域的使用和結(jié)構(gòu)成員的使用相同,其一般形式為: 位域變量名•位域名 位域允許用各種格式輸出。    
            main(){    
            struct bs    
            {    
            unsigned a:1;    
            unsigned b:3;    
            unsigned c:4;    
            } bit,*pbit;    
            bit.a=1;    
            bit.b=7;    
            bit.c=15;    
            pri

             

            改錯(cuò):
            #i nclude <stdio.h>

             

            int main(void) {

             

                int **p;
                int arr[100];

             

                p = &arr;

             

                return 0;
            }
            解答:
            搞錯(cuò)了,是指針類型不同,
            int **p; //二級(jí)指針
            &arr; //得到的是指向第一維為100的數(shù)組的指針
            #i nclude <stdio.h>
            int main(void) {
            int **p, *q;
            int arr[100];
            q = arr;
            p = &q;
            return 0;
            }

             


            下面這個(gè)程序執(zhí)行后會(huì)有什么錯(cuò)誤或者效果:
            #define MAX 255
            int main()
            {
               unsigned char A[MAX],i;//i被定義為unsigned char
               for (i=0;i<=MAX;i++)
                  A[i]=i;
            }
            解答:死循環(huán)加數(shù)組越界訪問(wèn)(C/C++不進(jìn)行數(shù)組越界檢查)
            MAX=255 
            數(shù)組A的下標(biāo)范圍為:0..MAX-1,這是其一..
            其二.當(dāng)i循環(huán)到255時(shí),循環(huán)內(nèi)執(zhí)行:
            A[255]=255;
            這句本身沒(méi)有問(wèn)題..但是返回for (i=0;i<=MAX;i++)語(yǔ)句時(shí),
            由于unsigned char的取值范圍在(0..255),i++以后i又為0了..無(wú)限循環(huán)下去.

             

            struct name1{
               char str;
               short x;
               int   num;
            }

             

            struct name2{
               char str;
               int num;
               short x;
            }

             

            sizeof(struct name1)=8,sizeof(struct name2)=12
            在第二個(gè)結(jié)構(gòu)中,為保證num按四個(gè)字節(jié)對(duì)齊,char后必須留出3字節(jié)的空間;同時(shí)為保證整個(gè)結(jié)構(gòu)的自然對(duì)齊(這里是4字節(jié)對(duì)齊),在x后還要補(bǔ)齊2個(gè)字節(jié),這樣就是12字節(jié)。

             

            intel:
            A.c 和B.c兩個(gè)c文件中使用了兩個(gè)相同名字的static變量,編譯的時(shí)候會(huì)不會(huì)有問(wèn)題?這兩個(gè)static變量會(huì)保存到哪里(棧還是堆或者其他的)?
            static的全局變量,表明這個(gè)變量?jī)H在本模塊中有意義,不會(huì)影響其他模塊。
            他們都放在數(shù)據(jù)區(qū),但是編譯器對(duì)他們的命名是不同的。
            如果要使變量在其他模塊也有意義的話,需要使用extern關(guān)鍵字。

             

            struct s1
            {
            int i: 8;
            int j: 4;
            int a: 3;
            double b;
            };

             

            struct s2
            {
            int i: 8;
            int j: 4;
            double b;
            int a:3;
            };

             

            printf("sizeof(s1)= %d\n", sizeof(s1));
            printf("sizeof(s2)= %d\n", sizeof(s2));
            result: 16, 24
            第一個(gè)struct s1
            {
            int i: 8;
            int j: 4;
            int a: 3;
            double b;
            };
            理論上是這樣的,首先是i在相對(duì)0的位置,占8位一個(gè)字節(jié),然后,j就在相對(duì)一個(gè)字節(jié)的位置,由于一個(gè)位置的字節(jié)數(shù)是4位的倍數(shù),因此不用對(duì)齊,就放在那里了,然后是a,要在3位的倍數(shù)關(guān)系的位置上,因此要移一位,在15位的位置上放下,目前總共是18位,折算過(guò)來(lái)是2字節(jié)2位的樣子,由于double是8字節(jié)的,因此要在相對(duì)0要是8個(gè)字節(jié)的位置上放下,因此從18位開(kāi)始到8個(gè)字節(jié)之間的位置被忽略,直接放在8字節(jié)的位置了,因此,總共是16字節(jié)。

             

            第二個(gè)最后會(huì)對(duì)照是不是結(jié)構(gòu)體內(nèi)最大數(shù)據(jù)的倍數(shù),不是的話,會(huì)補(bǔ)成是最大數(shù)據(jù)的倍數(shù)

             

            上面是基本問(wèn)題,接下來(lái)是編程問(wèn)題:

             


            本人很弱,這幾個(gè)題也搞不定,特來(lái)求救:
            1)讀文件file1.txt的內(nèi)容(例如):
            12
            34
            56
            輸出到file2.txt:
            56
            34
            12
            (逆序)
            2)輸出和為一個(gè)給定整數(shù)的所有組合
            例如n=5
            5=1+4;5=2+3(相加的數(shù)不能重復(fù))
            則輸出
            1,4;2,3。
            望高手賜教!!

             

            第一題,注意可增長(zhǎng)數(shù)組的應(yīng)用.
            #i nclude <stdio.h>
            #i nclude <stdlib.h>

             

            int main(void)
            {
                     int MAX = 10;
            int *a = (int *)malloc(MAX * sizeof(int));
            int *b;
                
            FILE *fp1;
            FILE *fp2;

             

            fp1 = fopen("a.txt","r");
            if(fp1 == NULL)
            {printf("error1");
                exit(-1);
            }

             

                fp2 = fopen("b.txt","w");
            if(fp2 == NULL)
            {printf("error2");
                exit(-1);
            }

             

            int i = 0;
                int j = 0;

             

            while(fscanf(fp1,"%d",&a[i]) != EOF)
            {
            i++;
            j++;
            if(i >= MAX)
            {
            MAX = 2 * MAX;
            b = (int*)realloc(a,MAX * sizeof(int));
            if(b == NULL)
            {
            printf("error3");
            exit(-1);
            }
            a = b;
            }
            }

             

            for(;--j >= 0;)
               fprintf(fp2,"%d\n",a[j]);

             

            fclose(fp1);
            fclose(fp2);

             

            return 0;
            }

             

            第二題.
            #i nclude <stdio.h>

             

            int main(void)
            {
            unsigned long int i,j,k;

             

            printf("please input the number\n");
            scanf("%d",&i);
                if( i % 2 == 0)
                    j = i / 2;
            else
            j = i / 2 + 1;

             

            printf("The result is \n");
                for(k = 0; k < j; k++)
                 printf("%d = %d + %d\n",i,k,i - k);
            return 0;
            }

             

            #i nclude <stdio.h>
            void main()
            {
            unsigned long int a,i=1;
            scanf("%d",&a);
            if(a%2==0)
            {
                 for(i=1;i<a/2;i++)
                 printf("%d",a,a-i);
            }
            else
            for(i=1;i<=a/2;i++)
                    printf(" %d, %d",i,a-i);
            }

             

            兄弟,這樣的題目若是做不出來(lái)實(shí)在是有些不應(yīng)該, 給你一個(gè)遞規(guī)反向輸出字符串的例子,可謂是反序的經(jīng)典例程.

             

            void inverse(char *p)
            {
                if( *p = = '\0' ) 
            return;
                inverse( p+1 );
                printf( "%c", *p );
            }

             

            int main(int argc, char *argv[])
            {
                inverse("abc\0");

             

                return 0;
            }

             

            借簽了樓上的“遞規(guī)反向輸出”
            #i nclude <stdio.h>
            void test(FILE *fread, FILE *fwrite)
            {
                    char buf[1024] = {0};
                    if (!fgets(buf, sizeof(buf), fread))
            }



            posted @ 2012-04-05 14:54 RTY 閱讀(830) | 評(píng)論 (0)編輯 收藏

            http://www.shnenglu.com/lf426/archive/2008/03/19/44831.html 

            作者:龍飛

            1:擴(kuò)充庫(kù)(Extension Libraries)

                    SDL本身所支持的,僅僅是讀取bmp格式的圖片。要使用其它格式的圖片,我們需要使用SDL的擴(kuò)充庫(kù)。在下面地址,我們可以下載到相關(guān)文件SDL_image-devel-1.2.6-VC8.zip
            http://www.libsdl.org/projects/SDL_image/
                    與SDL本身的設(shè)置一樣,將include下的*.h文件拷貝到:
            C:\MinGW\include\SDL (MinGW)
            C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SDL (VC2008)
                    將*.lib文件拷貝到:
            C:\MinGW\lib (MinGW)
            C:\Program Files\Microsoft Visual Studio 9.0\VC\lib (VC2008)
                    將*.dll文件拷貝到:
            C:\WINDOWS\system32

                    在編譯的時(shí)候,gcc注意增加共同編譯的庫(kù)文件-lSDL_image,比如,我設(shè)置了一個(gè)批處理文件g++img.bat內(nèi)容如下:
            g++ -o MySDL.exe main.cpp -lmingw32 -lSDLmain -lSDL -lSDL_image -mwindows
                    在VC2008中,需要在projec屬性中,Configuration Properties -- Linker -- Input -- Additional Dependencies 下增加SDL_image.lib。

                    在程序的頭文件中,需要增加:
            #include "SDL/SDL_image.h"

            2:更加通用的Display Surface構(gòu)造函數(shù)

                    我們現(xiàn)在可以回頭過(guò)來(lái)修改我們?cè)?/span>SDL入門教程(五):6、對(duì)C++異常機(jī)制的思考,代碼重寫中的Display Surface類的構(gòu)造函數(shù),使其能夠更加通用的讀取其它格式的圖片。
            DisplaySurface::DisplaySurface(std::string file_name, const ScreenSurface& screen):
            fileName(file_name)
            {
                SDL_Surface
            * pSurfaceTemp = IMG_Load(file_name.c_str());
                
            if ( pSurfaceTemp == 0 )
                    
            throw ErrorInfo(SDL_GetError());
                pSurface 
            = SDL_DisplayFormat(pSurfaceTemp);
                
            if ( pSurface == 0 )
                    
            throw ErrorInfo(SDL_GetError());
                SDL_FreeSurface(pSurfaceTemp);
                pScreen 
            = screen.point();
            }
                    IMG_Load()可以讀取多種格式的圖片文件,包括BMP, PNM, XPM, LBM, PCX, GIF, JPEG, TGA和PNG。

            3:將圖片修改為適合顯示的格式
            SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface);
                    在上面的程序中,我們使用到了函數(shù)SDL_DisplayFormat()。在之前的教程中,我一直沒(méi)有用到這個(gè)函數(shù),是因?yàn)槲疫€沒(méi)有發(fā)現(xiàn)用SDL_LoadBMP()的時(shí)候會(huì)出現(xiàn)格式兼容性的問(wèn)題——即使是圖片位深與顯示不一致。但是使用IMG_Load()的時(shí)候,小小的bug出現(xiàn)了。所以,這里我必須使用SDL_DisplayFormat(),將讀取的圖片文件轉(zhuǎn)換為適合顯示的格式。
                    如果轉(zhuǎn)換失敗,或者內(nèi)存溢出,這個(gè)函數(shù)將返回空指針。 

            posted @ 2012-04-04 08:25 RTY 閱讀(627) | 評(píng)論 (0)編輯 收藏

            Configure,Makefile.am, Makefile.in, Makefile文件之間關(guān)系
            2009-08-12 12:14

            1.autoscan (autoconf): 掃描源代碼以搜尋普通的可移植性問(wèn)題,比如檢查編譯器,庫(kù),頭文件等,生成文件configure.scan,它是configure.ac的一個(gè)雛形。

            your source files --> [autoscan*] --> [configure.scan] --> configure.ac

            2.aclocal (automake):根據(jù)已經(jīng)安裝的宏,用戶定義宏和acinclude.m4文件中的宏將configure.ac文件所需要的宏集中定義到文件 aclocal.m4中。aclocal是一個(gè)perl 腳本程序,它的定義是:“aclocal - create aclocal.m4 by scanning configure.ac”
            user input files   optional input     process          output files
            ================ ============== ======= ============

            acinclude.m4 - - - - -.
            V
            .-------,
            configure.ac ------------------------>|aclocal|
            {user macro files} ->| |------> aclocal.m4
            `-------'
            3.autoheader(autoconf): 根據(jù)configure.ac中的某些宏,比如cpp宏定義,運(yùn)行m4,聲稱config.h.in

            user input files optional input process output files
            ================ ============== ======= ============

            aclocal.m4 - - - - - - - .
            |
            V
            .----------,
            configure.ac ----------------------->|autoheader|----> autoconfig.h.in
            `----------'

            4.automake: automake將Makefile.am中定義的結(jié)構(gòu)建立Makefile.in,然后configure腳本將生成的Makefile.in文件轉(zhuǎn)換 為Makefile。如果在configure.ac中定義了一些特殊的宏,比如AC_PROG_LIBTOOL,它會(huì)調(diào)用libtoolize,否則它 會(huì)自己產(chǎn)生config.guess和config.sub

            user input files   optional input   processes          output files
            ================ ============== ========= ============

            .--------,
            | | - - -> COPYING
            | | - - -> INSTALL
            | |------> install-sh
            | |------> missing
            |automake|------> mkinstalldirs
            configure.ac ----------------------->| |
            Makefile.am ----------------------->| |------> Makefile.in
            | |------> stamp-h.in
            .---+ | - - -> config.guess
            | | | - - -> config.sub
            | `------+-'
            | | - - - -> config.guess
            |libtoolize| - - - -> config.sub
            | |--------> ltmain.sh
            | |--------> ltconfig
            `----------'

            5.autoconf:將configure.ac中的宏展開(kāi),生成configure腳本。這個(gè)過(guò)程可能要用到aclocal.m4中定義的宏。

            user input files   optional input   processes          output files
            ================ ============== ========= ============

            aclocal.m4 ,autoconfig.h.in - - - - - - -.
            V
            .--------,
            configure.ac ----------------------->|autoconf|------> configure
             
            6. ./configure的過(guò)程

            .-------------> [config.cache]
            configure* --------------------------+-------------> config.log
            |
            [config.h.in] -. v .--> [autoconfig.h]
            +-------> config.status* -+
            Makefile.in ---' `--> Makefile
             
            7. make過(guò)程
             
            [autoconfig.h] -.
            +--> make* ---> 程序
            Makefile ---'
             
            .---------,
            config.site - - ->| |
            config.cache - - ->|configure| - - -> config.cache
            | +-,
            `-+-------' |
            | |----> config.status
            config.h.in ------->|config- |----> config.h
            Makefile.in ------->| .status|----> Makefile
            | |----> stamp-h
            | +--,
            .-+ | |
            | `------+--' |
            ltmain.sh ------->|ltconfig|-------> libtool
            | | |
            `-+------' |
            |config.guess|
            | config.sub |
            `------------'

            .--------,
            Makefile ------>| |
            config.h ------>| make |
            {project sources} ---------------->| |--------> {project targets}
            .-+ +--,
            | `--------' |
            | libtool |
            | missing |
            | install-sh |
            |mkinstalldirs|
            `-------------'
            實(shí)例:
            在/hello/目錄下創(chuàng)建一個(gè)hello.c文件,并編譯運(yùn)行它:

            #cd /hello/

            (1) 編寫源文件hello.c:

            #include<stdio.h>
            int main(int argc, char** argv)
            {
            printf("Hello, GNU!n");
            return 0;
            }

            [litao@vm0000131 hello]$ ll
            total 4
            -rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c

            一、autoscan

            [litao@vm0000131 hello]$ autoscan
            autom4te: configure.ac: no such file or directory
            autoscan: /usr/bin/autom4te failed with exit status: 1
            [litao@vm0000131 hello]$ ll
            total 8
            -rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
            -rw-rw-r-- 1 litao litao 457 Aug 12 12:03 configure.scan
            -rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c

            已經(jīng)生成了configure.scan,autoscan.log文件

            將configure.scan 修改為 configure.in,最后修改的內(nèi)容如下:

            [litao@vm0000131 hello]$ mv configure.scan configure.in
            [litao@vm0000131 hello]$ vim configure.in

            # -*- Autoconf -*-
            # Process this file with autoconf to produce a configure script.

            AC_PREREQ(2.59)
            AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
            AC_CONFIG_SRCDIR([hello.c])
            #AC_CONFIG_HEADER([config.h])
            AM_INIT_AUTOMAKE(hello, 1.0)
            # Checks for programs.
            AC_PROG_CC

            # Checks for libraries.

            # Checks for header files.

            # Checks for typedefs, structures, and compiler characteristics.

            # Checks for library functions.
            AC_OUTPUT(Makefile)

            二、acloacl

            [litao@vm0000131 hello]$ aclocal

            生成 aclocal.m4 和 autom4te.cache (生成aclocal.m4的過(guò)程中涉及到configure.in)

            [litao@vm0000131 hello]$ ll
            total 44
            -rw-rw-r-- 1 litao litao 31120 Aug 12 12:08 aclocal.m4
            drwxr-xr-x 2 litao litao 4096 Aug 12 12:08 autom4te.cache
            -rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
            -rw-rw-r-- 1 litao litao 496 Aug 12 12:08 configure.in
            -rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c

            三、antoconf

            [litao@vm0000131 hello]$ autoconf
            生成 configure (根據(jù) configure.in, 和 aclocal.m4)
            [litao@vm0000131 hello]$ ll
            total 168
            -rw-rw-r-- 1 litao litao 31120 Aug 12 12:08 aclocal.m4
            drwxr-xr-x 2 litao litao 4096 Aug 12 12:11 autom4te.cache
            -rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
            -rwxrwxr-x 1 litao litao 122297 Aug 12 12:11 configure
            -rw-rw-r-- 1 litao litao 496 Aug 12 12:08 configure.in
            -rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c

            四、編寫Makefile.am:

            AUTOMAKE_OPTIONS= foreign
            bin_PROGRAMS= hello
            hello_SOURCES= hello.c

            五、automake

            生成 Makefile.in, depcomp, install-sh, 和 missing (根據(jù) Makefile.am, 和 aclocal.m4)

            [litao@vm0000131 hello]$ automake
            configure.in: required file `./install-sh' not found
            configure.in: required file `./missing' not found
            Makefile.am: required file `./depcomp' not found
            [litao@vm0000131 hello]$ automake --add-missing
            configure.in: installing `./install-sh'
            configure.in: installing `./missing'
            Makefile.am: installing `./depcomp'
            [litao@vm0000131 hello]$ ll
            total 192
            -rw-rw-r-- 1 litao litao 31120 Aug 12 12:08 aclocal.m4
            drwxr-xr-x 2 litao litao 4096 Aug 12 12:14 autom4te.cache
            -rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
            -rwxrwxr-x 1 litao litao 122297 Aug 12 12:11 configure
            -rw-rw-r-- 1 litao litao 496 Aug 12 12:08 configure.in
            lrwxrwxrwx 1 litao litao 31 Aug 12 12:16 depcomp -> /usr/share/automake-1.9/depcomp
            -rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c
            lrwxrwxrwx 1 litao litao 34 Aug 12 12:16 install-sh -> /usr/share/automake-1.9/install-sh
            -rw-rw-r-- 1 litao litao 69 Aug 12 12:15 Makefile.am
            -rw-rw-r-- 1 litao litao 16561 Aug 12 12:16 Makefile.in
            lrwxrwxrwx 1 litao litao 31 Aug 12 12:16 missing -> /usr/share/automake-1.9/missing

            六、configure
            生成 Makefile, config.log, 和 config.status


            posted @ 2012-04-03 22:20 RTY 閱讀(823) | 評(píng)論 (0)編輯 收藏

            導(dǎo)讀:

            /C:在預(yù)處理輸出中保留注釋語(yǔ)句
            /c:只編譯,不連接,相當(dāng)于在"Build"菜單下選擇了"Compile"
            /D:定義常量和宏,與源程序里的#define 有相同效果
            /E:預(yù)處理C、C++源文件,將源文件中所有的預(yù)編譯指令及宏展開(kāi),將注釋去掉,然后將預(yù)處理器的輸出拷貝至標(biāo)準(zhǔn)輸出設(shè)備輸出,并且在每個(gè)文件的開(kāi)頭和末尾加入#line
            /EH:指定編譯器用何種異常處理模型
            /EP:同/E,只是去掉了#line
            /F:設(shè)置程序的堆棧大小
            /FA:設(shè)置生成何種列表文件(匯編、匯編與機(jī)器碼、匯編與源碼、匯編與機(jī)器碼以及源碼)
            /Fa:指定用/FA設(shè)置的列表文件的存放路徑及(或)文件名
            /FD:生成文件的相互依賴信息
            /Fd:設(shè)置程序數(shù)據(jù)庫(kù)文件(PDB)的存放路徑及(或)文件名
            /Fe:設(shè)置最終可執(zhí)行文件的存放路徑及(或)文件名
            /FI:預(yù)處理指定的頭文件,與源文件中的#include有相同效果
            /Fm:創(chuàng)建map文件
            /Fo:設(shè)置編譯后Obj文件的存放路徑及(或)文件名
            /Fp:設(shè)置預(yù)編譯文件(pch)的存放路徑及(或)文件名
            /FR:生成瀏覽信息(sbr)文件
            /Fr:同/FR,不同之處在于/Fr不包括局部變量信息
            /G3:為80386處理器優(yōu)化代碼生成
            /G4:為80486處理器優(yōu)化代碼生成
            /G5:為Pentium處理器優(yōu)化代碼生成
            /G6:為Pentium Pro處理器優(yōu)化代碼生成
            /GA:為Windows應(yīng)用程序作優(yōu)化
            /GB:為Pentium處理器優(yōu)化代碼生成,使用80386、80486、Pentium、Pentium Pro的混合指令集,是代碼生成的默認(rèn)選項(xiàng)(程序?qū)傩赃x項(xiàng)中Processor對(duì)應(yīng)Blend)
            /GD:為Windows動(dòng)態(tài)庫(kù)(dll)作優(yōu)化,此開(kāi)關(guān)在VC6中沒(méi)有實(shí)現(xiàn)
            /Gd:指定使用__cdecl的函數(shù)調(diào)用規(guī)則
            /Ge:激活堆棧檢測(cè)
            /GF:消除程序中的重復(fù)的字符串,并將她放到只讀的緩沖區(qū)中
            /Gf:消除程序中的重復(fù)字符串
            /Gh:在每個(gè)函數(shù)的開(kāi)頭調(diào)用鉤子(hook)函數(shù)--penter
            /Gi:允許漸進(jìn)編譯
            /Gm:允許最小化rebuild
            /GR:允許運(yùn)行時(shí)類型信息(Run-Time Type Infomation)
            /Gr:指定使用__fastcall的函數(shù)調(diào)用規(guī)則
            /Gs:控制堆棧檢測(cè)所用內(nèi)存大小
            /GT:支持用__declspec(thread)分配的數(shù)據(jù)的fier-safety
            /GX:允許同步異常處理,與/EHsc開(kāi)關(guān)等價(jià)
            /Gy:允許編譯器將每一個(gè)函數(shù)封裝成COMDATs的形式,供連接器調(diào)用
            /GZ:允許在Debug build 的時(shí)候捕捉Release build的錯(cuò)誤
            /Gz:指定使用__stdcall的函數(shù)調(diào)用規(guī)則
            /H:限制外部名字的長(zhǎng)度
            /HELP:列出編譯器的所有的命令開(kāi)關(guān)
            /I:指定頭文件的搜索路徑
            /J:將char的缺省類型從signed char改成unsigned char
            /LD:創(chuàng)建一個(gè)動(dòng)態(tài)連接庫(kù)
            /LDd:創(chuàng)建一個(gè)Debug版本的動(dòng)態(tài)鏈接庫(kù)
            /link:將指定的選項(xiàng)傳給連接器
            /MD:選擇多線程、DLL版本的C Run-Time庫(kù)
            /MDd:選擇多線程、DLL、Debug版本的C Run-Time庫(kù)
            /ML:選擇單線程版本的C Run—Time庫(kù)
            /MLd:選擇單線程、Debug版本的C Run—Time庫(kù)
            /MT:選擇多線程版本的C Run-Time庫(kù)
            /MTd:選擇多線程、Debug版本的C Run—Time庫(kù)
            /nologo:不顯示程序的版權(quán)信息
            /O1:優(yōu)化使產(chǎn)生的可執(zhí)行代碼最小
            /O2:優(yōu)化使產(chǎn)生的可執(zhí)行代碼速度最快
            /Oa:指示編譯器程序里沒(méi)有使用別名,可以提高程序的執(zhí)行速度
            /Ob:控制內(nèi)聯(lián)(inline)函數(shù)的展開(kāi)
            /Od:禁止代碼優(yōu)化
            /Og:使用全局優(yōu)化
            /Oi:用內(nèi)部函數(shù)去代替程序里的函數(shù)調(diào)用,可以使程序運(yùn)行的更快,但程序的長(zhǎng)度變長(zhǎng)
            /Op:提高浮點(diǎn)數(shù)比較運(yùn)算的一致性
            /Os:產(chǎn)生盡可能小的可執(zhí)行代碼
            /Ot:產(chǎn)生盡可能塊的可執(zhí)行代碼
            /Ow:指示編譯器在函數(shù)體內(nèi)部沒(méi)有使用別名
            /Ox:組合了幾個(gè)優(yōu)化開(kāi)關(guān),達(dá)到盡可能多的優(yōu)化
            /Oy:阻止調(diào)用堆棧里創(chuàng)建幀指針
            /Q1f:對(duì)核心級(jí)的設(shè)備驅(qū)動(dòng)程序生成單獨(dú)的調(diào)試信息
            /QI0f:對(duì)Pentium 0x0f錯(cuò)誤指令作修正
            /Qifdiv:對(duì)Pentium FDIV錯(cuò)誤指令作修正
            /P:將預(yù)處理輸出寫到指定文件里,文件的后綴名為I
            /TC:將命令行上的所有文件都當(dāng)作C源程序編譯,不管后綴名是否為.c
            /Tc:將指定的文件當(dāng)作C源程序編譯,不管后綴名是否為.c
            /TP:將命令行上的所有文件都當(dāng)作C++源程序編譯,不管后綴名是否為.cpp
            /Tp:將指定文件當(dāng)作C++源程序編譯,不管后綴名是否為.cpp
            /U:去掉一個(gè)指定的前面定義的符號(hào)或常量
            /u:去掉所有前面定義的符號(hào)或常量
            /V:在編譯的obj文件里嵌入版本號(hào)
            /vd:禁止/允許構(gòu)造函數(shù)置換
            /vmb:選擇指針的表示方法,使用這個(gè)開(kāi)關(guān),在聲明指向某個(gè)類的成員的指針之前,必須先定義這個(gè)類
            /vmg:選擇指針的表示方法,使用這個(gè)開(kāi)關(guān),在聲明指向某個(gè)類的成員的指針之前,不必先定義這個(gè)類,但要首先指定這個(gè)類是使用何種繼承方法
            /vmm:設(shè)置指針的表示方法為Single Inheritance and Multiple Inheritance
            /vms:設(shè)置指針的表示方法為Single Inheritance
            /vmv:設(shè)置指針的表示方法為Any class
            /W:設(shè)置警告等級(jí)
            /w:禁止所有警告
            /X:阻止編譯器搜索標(biāo)準(zhǔn)的include 目錄
            /Yc:創(chuàng)建預(yù)編譯頭文件(pch)
            /Yd:在所有的obj文件里寫上完全的調(diào)試信息
            /Yu:在build過(guò)程中使用指定的預(yù)編譯頭文件
            /YX:指示編譯器若預(yù)編譯頭文件存在,則使用它,若不存在,則創(chuàng)建一個(gè)
            /Z7:生成MSC7.0兼容的調(diào)試信息
            /Za:禁止語(yǔ)言擴(kuò)展(Microsoft Extensions to C)
            /Zd:調(diào)試信息只包含外部和全局的符號(hào)信息以及行號(hào)信息
            /Ze:允許語(yǔ)言擴(kuò)展(Microsoft Extensions to C)
            /Zg:為源文件里面定義的每個(gè)函數(shù)生成函數(shù)原型
            /ZI:生成程序庫(kù)文件(Pdb)并支持Edit and Continue調(diào)試特性
            /Zi:生成程序庫(kù)文件(pdb),包含類型信息和符號(hào)調(diào)試信息
            /ZL:從obj文件里去掉缺省的庫(kù)文件名
            /Zm:設(shè)置編譯器的內(nèi)存分配xianzhi
            /Zn:禁止瀏覽信息文件里面的封裝
            /Zp:設(shè)置結(jié)構(gòu)成員在內(nèi)存里面的封裝格式
            /Zs:快速檢查語(yǔ)法錯(cuò)誤
            --------------------------
            vc所支持的文件類型


            DSW:全稱是Developer Studio Workspace,最高級(jí)別的配置文件,記錄了整個(gè)工作空間的配置信息,她是一個(gè)純文本的文件,在vc創(chuàng)建新項(xiàng)目的時(shí)候自動(dòng)生成
            DSP:全稱是Developer Studio Project,也是一個(gè)配置文件,不過(guò)她記錄的是一個(gè)項(xiàng)目的所有配置信息,純文本文件
            OPT:與DSW、DSP配合使用的配置文件,她記錄了與機(jī)器硬件有關(guān)的信息,同一個(gè)項(xiàng)目在不同的機(jī)器上的opt文件內(nèi)容是不同的
            CLW:記錄了跟ClassWizard相關(guān)的信息,如果丟失了clw文件,那么在Class View面板里就沒(méi)有類信息
            PLG:實(shí)際上是一個(gè)超文本文件,可以用Internet Explorer打開(kāi),記錄了Build的過(guò)程,是一個(gè)日志型文件
            RC:資源描述文件,記錄了所有的資源信息,在資源編輯器里作的修改,實(shí)際上都是對(duì)RC文件的修改
            RC2:附加的資源描述文件,不能直接資源編輯器修改,只能手工添加,可以用來(lái)添加額外的資源
            RES:經(jīng)過(guò)資源編輯器編譯之后的資源文件,以二進(jìn)制方式存放
            SBR:編譯器生成的瀏覽信息文件,在代碼導(dǎo)航的時(shí)候非常有用,她需要在編譯時(shí)指定/FR或者/Fr開(kāi)關(guān)
            BSC:BSCMAKE.EXE將所有的SBR文件作為輸入,經(jīng)過(guò)處理之后輸出一個(gè)BSC文件,在代碼導(dǎo)航的時(shí)候?qū)嶋H用到的是BSC文件
            ILK:當(dāng)選定漸增型編譯連接時(shí),連接器自動(dòng)生成ILK文件,記錄連接信息
            PDB:全稱是Program DataBase,即程序數(shù)據(jù)庫(kù)文件,用來(lái)記錄調(diào)試信息,是一個(gè)相當(dāng)重要的文件,沒(méi)有他,程序無(wú)法正常調(diào)試
            LIB:如果項(xiàng)目輸出是Dll的話,一般會(huì)輸出一個(gè)跟項(xiàng)目同名的Lib文件,記錄輸出的函數(shù)信息
            EXP:同Lib,是跟Dll一起生成的輸出文件
            PCH:全稱是PreCompiled Header,就是預(yù)先編譯好的頭文件,在編譯時(shí)指定/Yu開(kāi)關(guān)時(shí)編譯器自動(dòng)生成



            本文轉(zhuǎn)自
            http://www.shnenglu.com/sunraiing9/archive/2007/11/26/37323.html

            posted @ 2012-03-30 20:46 RTY 閱讀(558) | 評(píng)論 (0)編輯 收藏

            導(dǎo)讀:


            版權(quán)聲明:轉(zhuǎn)載時(shí)請(qǐng)以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明
            http://chenshine.blogbus.com/logs/4414354.html


            剛 進(jìn)入計(jì)算機(jī)相關(guān)專業(yè)領(lǐng)域時(shí),大家最先用過(guò)的調(diào)試器大多會(huì)是Turbo C。它雖然古老但用過(guò)的人卻很多,然而嚴(yán)格的講,Turbo C是一個(gè)集成開(kāi)發(fā)環(huán)境,雖然擁有獨(dú)立的編譯器,鏈接器,卻沒(méi)有獨(dú)立的調(diào)試器,這和Visual Studio一樣。如果你做過(guò)DOS,早期Windows下的匯編,也許你會(huì)對(duì)Debug,CodeView等調(diào)試工具熟悉,但這些工具太老 了,Debug甚至不能調(diào)試32位程序,介紹它們與這篇文章的主旨不符,如果你對(duì)它們感興趣,可以去查閱相關(guān)資料。本文主要是介紹與調(diào)試技術(shù)相關(guān)的理論知 識(shí)以及常用調(diào)試器的使用,Windows設(shè)備驅(qū)動(dòng)程序與內(nèi)核的調(diào)試等。具體的講解方法是理論結(jié)合實(shí)踐,并且是站在給新手看的角度,循序漸進(jìn)的,用一個(gè)一個(gè) 調(diào)試會(huì)話向你展示每個(gè)重要命令的使用。



            目錄

            1。調(diào)試器
            2。調(diào)試信息
            3。用戶模式程序的調(diào)試
            4。驅(qū)動(dòng)程序與內(nèi)核的調(diào)試

            1 調(diào)試器

            1。1 概覽

            調(diào) 試器,與編譯器,鏈接器一樣,都屬于基礎(chǔ)軟件,它們?cè)谥谱魃隙加泻艽蟮碾y度,但盡管如此,現(xiàn)實(shí)中還是有不少專業(yè)級(jí)的調(diào)試器,微軟官方的就有 cdb,ntsd,WinDbg,kd等,還有SoftIce,OllyDbg等來(lái)自于其它公司的優(yōu)秀調(diào)試器。本文不可能對(duì)這幾個(gè)調(diào)試器一一介紹,一個(gè)是 限于篇幅,另一個(gè)是上面列舉的這幾個(gè)調(diào)試器無(wú)論是哪一個(gè)都需要你花很長(zhǎng)的時(shí)間去完全掌握(在市面上有很多書籍甚至專門講解某一個(gè)調(diào)試器的使用,比如 SoftIce)。雖然本文不會(huì)講解SoftIce的詳細(xì)使用,但我還是要對(duì)它進(jìn)行簡(jiǎn)短的介紹,因?yàn)樗忻耍踔帘萕indows出生的早。

            1。2 SoftIce

            SoftIce 是NuMega公司生產(chǎn)的調(diào)試器,產(chǎn)于80年代后期,直到今天為止,這個(gè)軟件已經(jīng)變革過(guò)好幾次了,因?yàn)樘幚砥鞯捏w系結(jié)構(gòu)在更新,操作系統(tǒng)也在更新,所以調(diào) 試器也必須相應(yīng)的更新。它之所以有名,那是與歷史有關(guān)的,在Intel推出386 Cpu的時(shí)候,NuMega立即讓SoftIce支持了386 Cpu的新特性,同時(shí)吸引了大量黑客的使用,使它在黑客界產(chǎn)生了一定的地位(功能強(qiáng)大的調(diào)試器可以對(duì)軟件的保護(hù)機(jī)制進(jìn)行破解,如突破序列號(hào)之類的)。在 Windows推出時(shí),所有的調(diào)試器都不適用這種新的系統(tǒng)軟件體系結(jié)構(gòu)了,唯一能用的就是微軟自己生產(chǎn)的調(diào)試器,卻很拙劣,這時(shí)NuMega又對(duì) SoftIce進(jìn)行了變革,不僅讓它可以在新的系統(tǒng)上很好的工作,甚至還可以調(diào)試Windows的內(nèi)核,這是當(dāng)時(shí)是不敢想象的。也正是因?yàn)樗芎玫男阅埽?卓越的功能,它成為了黑客們的寵兒,并且培養(yǎng)了幾代的黑客。讀完本文后,你自己應(yīng)該有能力去探索它,或許你也可以在這幾款調(diào)試器里找到適合自己的。

            1。3 微軟的調(diào)試工具

            本 文主要介紹的是微軟官方的調(diào)試器,并且MS微軟也最積極,調(diào)試工具包一直在更新中。在微軟的調(diào)試器里,大家可能最為熟悉Visual Studio Debugger,就是你在Visual C++里使用的那個(gè),它并不是一個(gè)單獨(dú)可運(yùn)行的程序,而是內(nèi)嵌在Visual Studio中的,它的功能相對(duì)于上面幾個(gè)調(diào)試器來(lái)說(shuō)要弱很多,這里并不會(huì)對(duì)它進(jìn)行介紹,如果你想全方面的了解它的話,你可以去參考MSDN,那里專門有 幾章講解它,是一份很好的文檔化的資源(而且還是中文的)。其它的微軟調(diào)試工具cdb,ntsd,WinDbg,kd都在微軟的一個(gè)安裝包里,被稱作Debugging Tools for Windows(10 多M的大小,請(qǐng)通過(guò)這個(gè)鏈接下載并安裝,一會(huì)兒就要用到)。這些調(diào)試器在下文中會(huì)分別介紹,這里先做一個(gè)簡(jiǎn)單的區(qū)別,cdb與ntsd幾乎是一樣的程序, 唯一的不同是cdb是一個(gè)CUI程序,即Console程序,而ntsd是GUI程序,但ntsd并沒(méi)有產(chǎn)生窗口,而是又分配了一個(gè)Console窗口, 這個(gè)Console窗口就相當(dāng)于是cdb。它與真正的cdb執(zhí)行完全一樣的功能(官方如是說(shuō),然而實(shí)際上還有一些個(gè)不同)。在命令行中啟動(dòng)它們時(shí)下面兩句 命令有一樣的效果(C:/Progs/Debug是調(diào)試工具包的安裝位置):

            C:/Progs/Debug/>start cdb
            C:/Progs/Debug/>ntsd

            cdb 與ntsd是用來(lái)調(diào)試用戶模式應(yīng)用程序的。kd調(diào)試器也是一個(gè)命令行程序,不過(guò)正如其名kernel debugger所描述的一樣,它是內(nèi)核調(diào)試器的,是驅(qū)動(dòng)程序開(kāi)發(fā)者,系統(tǒng)Hacker的最愛(ài)。WinDbg是一個(gè)稱職的GUI程序,它有菜單,有工具 欄,還有多個(gè)子窗口,可以分別顯示源代碼,調(diào)用棧,命令等,它既可以調(diào)試ring 0程序,也可以調(diào)試ring 3程序,其實(shí)它只是一個(gè)殼而已,當(dāng)調(diào)試ring 3級(jí)程序時(shí)它實(shí)際上是用cdb/ntsd,而當(dāng)調(diào)試ring 0級(jí)程序時(shí)是用kd。WinDbg的到來(lái)吸引了很多的人使用,你也將會(huì)發(fā)現(xiàn),它確實(shí)是一款優(yōu)秀的調(diào)試器。

            2 調(diào)試信息

            調(diào)試器之所以能夠工作,完全是依賴于編譯和鏈接程序時(shí)所生成的調(diào)試信息,當(dāng)然調(diào)試信息是具有一定的格式的。

            2。1 格式

            微 軟的調(diào)試信息格式經(jīng)過(guò)了幾代變化,最終形成了Program DataBase這種格式,并且這種格式還在進(jìn)行版本上的更新,VS.Net所用的新的Program DataBase版本與Visual C++ 6.0所用的老的版本是不兼容的,并且你也可以用編譯器和鏈接器明確指定你想要生成的調(diào)試信息格式,這一點(diǎn)下文中有闡述。

            2。2 內(nèi)容

            關(guān) 于調(diào)試信息我們還必須知道兩件事,一是調(diào)試信息包括哪些內(nèi)容,二是調(diào)試信息儲(chǔ)存在什么地方。其實(shí)調(diào)試信息所應(yīng)該包括的內(nèi)容正是調(diào)試信息格式變化的原因,從 COFF格式,到CodeView格式,到Program DataBase格式,調(diào)試信息變得越來(lái)越豐富了,并且是只多不少。Program DataBase格式的調(diào)試信息中主要包括了所有全局函數(shù),static 函數(shù),全局變量,static變量,局部變量,函數(shù)形參的名字及其位置,源代碼與可執(zhí)行文件中指令的映射信息,每個(gè)函數(shù)與變量的類型,以及FPO信息,編 輯和繼續(xù)信息。編輯與繼續(xù)信息主要用于在Visual Studio中調(diào)試時(shí),可以在調(diào)試的同時(shí)編輯源代碼,并在接下來(lái)的調(diào)試中得到體現(xiàn)。Program DataBase格式的調(diào)試信息包含了這么多的內(nèi)容,所以用這種調(diào)試信息來(lái)調(diào)試程序時(shí),你將能夠得到更多,更準(zhǔn)確,更深入的反饋。

            2。3 存儲(chǔ)位置

            調(diào) 試信息的存儲(chǔ)位置是與其格式相關(guān)的,Program DataBase格式的調(diào)試信息存儲(chǔ)在一個(gè)單獨(dú)的文件里,擴(kuò)展名為pdb。像以前的CodeView格式的調(diào)試信息即可存儲(chǔ)在單獨(dú)的文件里,又可存儲(chǔ)在編 譯時(shí)所生成的obj文件中。知道了這些知識(shí)后,我們就可以正確地生成調(diào)試信息了。在后面的內(nèi)核調(diào)試中我們還要繼續(xù)談到它。

            3 用戶模式程序的調(diào)試

            根 據(jù)上面的講述,我們可以用cdb或WinDbg來(lái)進(jìn)行ring 3程序的調(diào)試,這里先講解cdb。cdb允許你啟動(dòng)某個(gè)被調(diào)試程序(以下稱debugee)的一個(gè)新的實(shí)例來(lái)進(jìn)行調(diào)試,即先創(chuàng)建cdb,然后cdb再把你 所指定的程序創(chuàng)建為一個(gè)新進(jìn)程進(jìn)而對(duì)其調(diào)試,也允許debugee在已經(jīng)運(yùn)行的情況下被cdb attach上。cdb還可以對(duì)Crash Dump(程序崩潰時(shí)的內(nèi)存Copy,下文將會(huì)說(shuō)明)進(jìn)行調(diào)試,只需要加上-z選項(xiàng),后面再加上Crash Dump的文件名即可。這幾種調(diào)試方式下面將會(huì)一一講述。

            3。1 調(diào)試前的準(zhǔn)備

            第 2節(jié)中對(duì)調(diào)試信息進(jìn)行了理論上的說(shuō)明,接下來(lái)我們來(lái)看看在實(shí)際中應(yīng)該如何操作。首先我們的程序必須要經(jīng)過(guò)編譯,鏈接,并且在編譯和鏈接時(shí)還要指定一些選項(xiàng) 以正確地生成調(diào)試信息。這里所使用的編譯器是cl.exe,鏈接器是link.exe,都是微軟官方的,Visual Studio就是用的這兩個(gè)(CTRL+F5就是順序調(diào)用cl和link的快捷鍵),如果你安裝了Visual C++或Visual Studio,就會(huì)有它們,另外一種選擇是安裝SDK,也能夠得到它們。本文所用的cl.exe和link.exe是Visual C++ 6.0的版本。若要生成調(diào)試信息,編譯時(shí)我們需要加上的選項(xiàng)應(yīng)是/Zi,而鏈接時(shí)則要加上/debug。在下面的調(diào)試中,我們將用C語(yǔ)言來(lái)寫程序,所以你 有必要知道用C語(yǔ)言寫出來(lái)的程序與用匯編寫出來(lái)的有什么不同。首先,每個(gè)程序都有一個(gè)入口函數(shù),它的地址需要在鏈接時(shí)指定,并被鏈接器放到最終可執(zhí)行文件 的頭部,通常用匯編語(yǔ)言寫的程序,有選擇的,你可以在源代碼中指定入口函數(shù),而用C語(yǔ)言寫的程序則需要在鏈接的時(shí)候來(lái)指定入口函數(shù),說(shuō)到這你可能不以為 然,“C語(yǔ)言寫的程序的入口函數(shù)不就是main嗎?“。實(shí)際上,控制臺(tái)C程序的入口函數(shù)默認(rèn)情況下是C運(yùn)行時(shí)的啟動(dòng)函數(shù):mainCRTStartup。 然后由這個(gè)函數(shù)調(diào)用你寫的main函數(shù),所以可執(zhí)行文件的頭部存放的入口地址是mainCRTStartup的地址,而不是你寫的main函數(shù)地址。 mainCRTStartup主要做了一些為了正確執(zhí)行C/C++程序的初始化工作。它已經(jīng)由微軟寫好了,由鏈接器自動(dòng)鏈接到可執(zhí)行文件中。如果你在程序 中不使用C語(yǔ)言的庫(kù)以及一些ANSI規(guī)定的全局變量,只是單純地使用C語(yǔ)言這種語(yǔ)法,那么你也可以不鏈接mainCRTStartup,直接指定你自己寫 的某個(gè)函數(shù)為入口函數(shù),這也是我們?cè)谙挛闹兴褂玫姆椒ǎ唧w的做法是在鏈接時(shí)加入如下選項(xiàng):/subsystem:console /entry:你的入口函數(shù)名稱。這個(gè)入口函數(shù)應(yīng)該是不帶參數(shù)的。現(xiàn)在我們來(lái)總結(jié)一下上面所講的內(nèi)容,假定你的源程序名為exam.c,你想指定的入口函 數(shù)為main,那么應(yīng)該如下生成可執(zhí)行程序:

            C:/Pro/>cl /Zi exam.c /link /debug /subsystem:console /entry:main
            另 外,就算你不鏈接mainCRTStartup(它會(huì)調(diào)用很多的Win32 API),也不在源程序中調(diào)用任何的系統(tǒng)函數(shù)。那么系統(tǒng)還是會(huì)把一些動(dòng)態(tài)鏈接庫(kù),如kernel32.dll,Ntdll.dll等動(dòng)態(tài)鏈接到你的程序所 對(duì)應(yīng)的進(jìn)程里,即把它們映射到你的程序?qū)?yīng)的進(jìn)程地址空間里。這是因?yàn)樵谀闼付ǖ娜肟诤瘮?shù)運(yùn)行之前,還會(huì)有一系列的 Kernel32.dll,Ntdll.dll中的函數(shù)要運(yùn)行。即在用戶空間中你指定的入口函數(shù),例如上面的main,根本不是第一個(gè)運(yùn)行的函數(shù)。那么那 些函數(shù)是做什么的呢,通過(guò)大量的反匯編和調(diào)試能夠推斷出它們是做一些進(jìn)程,線程在用戶空間的初始化,設(shè)置一些異常楨等。在下面的調(diào)試中我們將會(huì)用一些手段 來(lái)研究它們。這些函數(shù)是操作系統(tǒng)的一部分,因些我們必須從官方網(wǎng)站下載它的符號(hào)文件,當(dāng)然不下載也行,那么你將面臨的會(huì)是一大堆的警告。說(shuō)到下載,沒(méi)有比 這更簡(jiǎn)單的了,你不需要預(yù)先的下載,只需要添加一個(gè)環(huán)境變量_NT_SYMBOL_PATH即可,而真正的下載工作由調(diào)試器來(lái)做,這個(gè)環(huán)境變量的值與已存 在的PATH環(huán)境變量類似,是由分號(hào)分隔的一系列的路徑組成。這些路徑應(yīng)該包括你的調(diào)試信息文件(pdb文件)所在地,如前面的C:/Pro/。如果要下 載系統(tǒng)文件如Kernel32.dll,Ntdll.dll的pdb文件,你僅僅需要再加一個(gè)這樣的路徑:SRV*D:/Symbols*http: //msdl.microsoft.com/download/symbols,其中D:/Symbols是可更換的,你可以換成任何一個(gè)其它的路徑,這 個(gè)D:/Symbls是用來(lái)存放從后面的URL路徑所下載下來(lái)的系統(tǒng)調(diào)試信息文件的。其實(shí)你也可以預(yù)先下載系統(tǒng)調(diào)試信息文件到一個(gè)路徑里,然后在 _NT_SYMBOL_PATH里指定那個(gè)目錄,但這樣一來(lái)有兩個(gè)缺點(diǎn),一是你必須得進(jìn)行版本的匹配,做這件事簡(jiǎn)直太乏味了,二是你一次需要把整個(gè)操作系 統(tǒng)的調(diào)試信息文件都下載下來(lái),可能會(huì)需要1G的空間。而通過(guò)前面設(shè)置環(huán)境變量的方式,調(diào)試器會(huì)根據(jù)需要只下載這次調(diào)試會(huì)話所需要的調(diào)試信息文件,并且它會(huì) 自動(dòng)給你匹配版本。由于我們將要編寫的源代碼都在C:/Pro/文件夾中,生成的pdb文件也在C:/Pro/中,所以我們的 _NT_SYMBOL_PATH環(huán)境變量應(yīng)該如下設(shè)置,假設(shè)你希望系統(tǒng)pdb文件下載到D:/Symbols:
            C:/Pro/>set _NT_SYMBOL_PATH=SRV*D:/Symbols*http://msdl.microsoft.com/download/symbols;C:/Pro/
            最后,我們需要在命令行中啟動(dòng)cdb調(diào)試器,但當(dāng)前目錄通常是源代碼文件夾C:/Pro/,為了避免如下冗余的鍵入:

            C:/Pro/>C:/Progs/Debug/cdb example1.exe
            應(yīng)該為cdb,ntsd,WinDbg設(shè)置PATH環(huán)境變量:

            C:/Pro/>set PATH=%PATH%;C:/Progs/Debug/
            這里的C:/Progs/Debug是Debugging Tools for Windows的安裝目錄。以后就可以這樣來(lái)調(diào)試了:

            C:/Pro/>cdb example1.exe

            3。2 cdb啟動(dòng)新實(shí)例的調(diào)試

            3。2。1 編寫一源程序,啟動(dòng)cdb

            首先我編寫了下面的C程序,先用這個(gè)程序來(lái)介紹一些基本的命令,并且來(lái)驗(yàn)證一下調(diào)試信息中是否確切包含了上面所說(shuō)的那些內(nèi)容:

            [example1.c]
            int 		gVar;
            static int sgVar;
            int Inc(int Param);
            static int sDec(int sParam);
            void main(void)
            {
            int lVar;
            static int slVar;
            lVar = 3;
            slVar = 4;
            gVar = Inc(lVar);
            sgVar = sDec(slVar);
            }
            int Inc(int Param)
            {
            return (Param+1);
            }
            int sDec(int sParam)
            {
            return (sParam-1);
            }
            對(duì)這個(gè)程序用上面所講的方法編譯鏈接:
            C:/Pro/>cl /Zi example1.c /link /debug /subsystem:console /entry:main
            接下來(lái)啟動(dòng)cdb調(diào)試器:

            C:/Pro/>cdb example1.exe

            Microsoft (R) Windows Debugger
            Copyright (c) Microsoft Corporation. All rights reserved.

            CommandLine: example1.exe
            Symbol search path is: SRV*D:/Symbols*http://msdl.microsoft.com/download/symbols
            Executable search path is:
            ModLoad: 00400000 00406000 example1.exe
            ModLoad: 7c920000 7c9b4000 ntdll.dll
            ModLoad: 7c800000 7c91c000 C:/WINDOWS/system32/kernel32.dll
            (c94.c24): Break instruction exception - code 80000003 (first chance)
            eax=00251eb4 ebx=7ffd4000 ecx=00000001 edx=00000002 esi=00251f48 edi=00251eb4
            eip=7c921230 esp=0012fb20 ebp=0012fc94 iopl=0 nv up ei pl nz na po nc
            cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
            ntdll!DbgBreakPoint:
            7c921230 cc int 3
            0:000>
            cdb 輸出了此時(shí)主線程的上下文信息(這個(gè)例子中也只有這一個(gè)線程)以及程序斷點(diǎn)信息后便會(huì)進(jìn)入一個(gè)新的提示符:0:000>。以后我們會(huì)一直工作在這種 類型的提示符上,下面在這個(gè)提示符上輸入一個(gè)命令來(lái)加載所有的調(diào)試信息文件,此時(shí)可能會(huì)慢一些,因?yàn)橐螺d系統(tǒng)DLL的pdb文件,所以要確保你能上網(wǎng)。

            0:000>.reload /f

            看到這個(gè)以"."號(hào)做為前綴的命令,可能你會(huì)覺(jué)得怪怪的,但實(shí)際上還有用"!"號(hào)做前綴的呢,用"."號(hào)做前綴的命令表示元命令,而用"!“號(hào)做前綴的命令表示擴(kuò)展命令,這里只做一個(gè)簡(jiǎn)單的區(qū)分即可。

            其 實(shí)這時(shí)我們所要調(diào)試的程序已經(jīng)運(yùn)行起來(lái)了,不過(guò)停在了某處,主線程處于凍結(jié)狀態(tài)。這一點(diǎn)和Linux的Gnu調(diào)試器GDB不一樣,對(duì)于GDB調(diào)試器,你先 要設(shè)置一個(gè)斷點(diǎn),然后再鍵入運(yùn)行命令(如果自己不手動(dòng)設(shè)置一個(gè)斷點(diǎn),那么程序?qū)?huì)一直運(yùn)行直到結(jié)束,你根本沒(méi)有調(diào)試的機(jī)會(huì)。),這時(shí)程序才處于運(yùn)行狀態(tài)。 沒(méi)有運(yùn)行和運(yùn)行之后處于凍結(jié)狀態(tài)是兩個(gè)完全不同的概念。那么我們這個(gè)example1.exe停在了什么地方呢。下面我將介紹一個(gè)很重要的命令,用它我們 可以來(lái)研究這方面的問(wèn)題。

            3。2。2 查看堆棧及用戶空間的初始化

            用kb命令可以來(lái)查看堆棧,它顯示棧上一些重要的信息。

            0:000>kb
            ChildEBP RetAddr Args to Child
            0012fb1c 7c95edc0 7ffdf000 7ffd4000 00000000 ntdll!DbgBreakPoint
            0012fc94 7c941639 0012fd30 7c920000 0012fce0 ntdll!LdrpInitializeProcess+0xffa
            0012fd1c 7c92eac7 0012fd30 7c920000 00000000 ntdll!_LdrpInitialize+0x183
            00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7
            這個(gè)命令所列出來(lái)的信息后面還要詳細(xì)介紹,這里先關(guān)注一下函數(shù)的調(diào)用關(guān)系。從上面的列表可以看到有四個(gè)函數(shù),這四個(gè)函數(shù)都是ntdll模塊里的,從下至上函數(shù)依次被調(diào)用。要注意這是當(dāng)前線程的用戶棧里所有的東西,就四個(gè)函數(shù),KiUserApcDispatcher是第一個(gè),上面已經(jīng)提到過(guò),在你指定的入口函數(shù)執(zhí)行之前還有很多的函數(shù)被調(diào)用,KiUserApcDispatcher是第一個(gè)被調(diào)用的,接下來(lái)它再調(diào)用_LdrpInitialize_LdrpInitialize調(diào)用LdrpInitializeProcess,再調(diào)用DbgBreakPoint。至于是誰(shuí)調(diào)用的KiUserApcDispatcher,我現(xiàn)在只能簡(jiǎn)單的告訴你是操作系統(tǒng)調(diào)度例程調(diào)度的結(jié)果。深入地探討它就離開(kāi)本文的主題了。現(xiàn)在我們可以肯定的是程序停在了DbgBreakPoint里,因?yàn)樗菞I献詈笠粋€(gè)函數(shù)。從cdb調(diào)試器的輸出可以看到example1.exe停在了DbgBreakPoint函數(shù)里的int 3語(yǔ)句上,int 3是一個(gè)異常,它將會(huì)通知操作系統(tǒng)掛起這個(gè)線程,并且通知調(diào)試器,這是操作系統(tǒng)對(duì)調(diào)試的一個(gè)支持。其實(shí)DbgBreakPoint函數(shù)只有一條語(yǔ)句,那就是int 3。敏感點(diǎn)的人可能會(huì)想到,這樣一來(lái),所有的程序,無(wú)論是否被調(diào)試,在運(yùn)行的時(shí)候最初都會(huì)執(zhí)行DbgBreakPoint函數(shù)了,這也太傻了吧?情況并非如此,當(dāng)我們鍵入cdb example1.exe時(shí),cdb在啟動(dòng)example1.exe的時(shí)候會(huì)加一個(gè)特殊的標(biāo)記,在這種情況下LdrpInitializeProcess才會(huì)調(diào)用DbgBreakPoint,這又是操作系統(tǒng)對(duì)調(diào)試的一個(gè)支持。


            本文轉(zhuǎn)自
            http://chenshine.blogbus.com/logs/4414354.html

            posted @ 2012-03-30 20:45 RTY 閱讀(840) | 評(píng)論 (0)編輯 收藏

                 前面學(xué)習(xí)中,很多地方都用到了C++和JavaScript相互通信。今天就學(xué)習(xí)QtScript模塊吧。

                Qt 包含完全集成的 ECMA 標(biāo)準(zhǔn)腳本引擎。Qt Script 集成了 QObject,為腳本提供了 Qt 的信號(hào)與槽 (Signals & Slots) 機(jī)制,可在 C++ 和腳本之間進(jìn)行集成。 腳本支持可使開(kāi)發(fā)事半功倍,QtScript提供腳本錯(cuò)誤報(bào)告,用戶可用自己的腳本跟蹤程序缺陷.

               下面是一個(gè)簡(jiǎn)單的hello程序。

               

             

            1. //main.cpp  
            2. #include <QtGui/QApplication>  
            3. #include <QMessageBox>  
            4. #include <QtScript/QtScript>  
            5. #include <QPushButton>  
            6. #include "mainwindow.h"  
            7.   
            8. int main(int argc, char *argv[])  
            9. {  
            10.     Q_INIT_RESOURCE(helloscript);  
            11.     QApplication app(argc, argv);  
            12.     QScriptEngine engine;  
            13.   
            14.     //國(guó)際化  
            15.     QTranslator translator;  
            16.     translator.load("helloscript_la");  
            17.     app.installTranslator(&translator);  
            18.     engine.installTranslatorFunctions();  
            19.   
            20.     QPushButton button;  
            21.     QScriptValue scriptButton = engine.newQObject(&button);//生成C++對(duì)象的代理腳本對(duì)象  
            22.     engine.globalObject().setProperty("button", scriptButton);//將對(duì)象注冊(cè)到j(luò)avascript  
            23.   
            24.     //讀取js文件  
            25.     QString fileName(":/helloscript.js");  
            26.     QFile scriptFile(fileName);  
            27.     scriptFile.open(QIODevice::ReadOnly);  
            28.     QTextStream stream(&scriptFile);  
            29.     QString contents = stream.readAll();  
            30.     scriptFile.close();  
            31.   
            32.     QScriptValue result = engine.evaluate(contents, fileName);//執(zhí)行腳本  
            33.     if(result.isError()) {//解析js文件是否有錯(cuò)誤  
            34.         QMessageBox::critical(0, "Hello Script",  
            35.                               QString::fromLatin1("%0:%1: %2")  
            36.                               .arg(fileName)//文件名  
            37.                               .arg(result.property("lineNumber").toInt32())//錯(cuò)誤行號(hào)  
            38.                               .arg(result.toString()));//錯(cuò)誤信息  
            39.         return -1;  
            40.     }  
            41.     return app.exec();  
            42. }  
              

             

             

             

             

            [javascript] view plaincopy
            1. //helloscript.js  
            2. button.text = qsTr('Hello World');//note that the qTr() function is used to allow for translation  
            3. button.styleSheet = 'font-style: italic; color: #12FF12';  
            4. button.show();//調(diào)用show()槽函數(shù)  
            5. button.clicked.connect(  
            6.     function(){  
            7.        print('Hello QtScript');  
            8.     }  
            9. );  

             

             

            記住還需要在.pro文件中加入:QT       += script

             

                1、QScriptEngine類為程序提供一個(gè)嵌入式腳本環(huán)境。一個(gè)應(yīng)用程序中可以添加多個(gè)腳本引擎;每一個(gè)引擎都是一個(gè)輕量級(jí)自包含的虛擬機(jī)。通過(guò)調(diào)用腳本引擎的evaluate()函數(shù)可以執(zhí)行腳本.

               

            [c-sharp] view plaincopy
            1. QScriptEngine engine;  
            2. QScriptValue result = engine.evaluate("(3*2)-1");  
            3. qDebug() << "Result: " << result.toInt32();  

             

                

             

              

            1. QScriptEngine engine;  
            2. QScriptValue func = engine.evaluate("(function(a, b) { return a+b;})");  
            3. QScriptValueList args;  
            4. args << 1 << 2;  
            5. QScriptValue result = func.call(QScriptValue(), args);  
            6. qDebug() << "Result: " << result.toInt32();  

             

             

             

                2、QScriptValue是一個(gè)Qt Script數(shù)據(jù)類型的容器,支持ECMA-262定義的類型,如:

                 原始數(shù)據(jù)類型:Undefined,Null,Boolean,Number,String,對(duì)象類型。

                 另外Qt Script還內(nèi)建支持QVariant,QObject和QMetaObject.

                  >>對(duì)于基對(duì)象(object-based)類型(包括Date和RegExp),使用QScriptEngine對(duì)象的newT()函數(shù)(如QScriptEngine::newObject())創(chuàng)建一個(gè)你期望的QScriptValue類型。

                  >>對(duì)于原始數(shù)據(jù)類型,直接使用QScriptValue構(gòu)造函數(shù)加載。

                  isT()方法能夠被用來(lái)測(cè)試一個(gè)值是否是你確定的數(shù)據(jù)類型。toT()方法用來(lái)將QScriptValue轉(zhuǎn)換成其他類型。當(dāng)然你也可以用qscriptvalue_cast()方法.

            posted @ 2012-03-29 13:43 RTY 閱讀(2050) | 評(píng)論 (0)編輯 收藏

            Most of us would not have expected the next major version of Mac OS X so quickly this time. But, Apple has released the developer preview-1 of OS X 10.8 Mountain Lion recently.  While people were talking about iPad 3 and iPhone 5, Mac desktop users surprised by latest OS from Apple (though it is not a final version for end users). Mac OS X 10.8 is still a developer preview version to run and test the new OS. You can directly download the official distribution of 10.8 if you have valid Apple developer ID.  Here I’m sharing few useful links to download OS X 10.8 Mountain Lion without developer login.

            These files should be enough to run on normal Intel or virtual machines by using hackintosh methods.

            Mountain Lion OS brings most of the features of iOS (iPad and iPhone) to desktop OS environment on top of existing Lion OS X 10.7. The major features of new OS include;

            • Messages – replaces iChat to bring full iMessage support to the Mac
            • Notification Center – just like iOS
            • Share Sheets – allows easy sharing of links, videos, photos between apps
            • AirPlay mirroring – send wireless video to an Apple TV
            • Notes
            • Reminders
            • Game Center
            • Twitter Integration
            • Gatekeeper – anti-Malware app installation guard

            You can find out more information here at official link to Mountain Lion.

            Hackintosh Versions of Mac OS X 10.8,

            Here is the link to download developer preview –1 of OS X 10.8 Mountain Lion (you must have developer id to download form apple site)

             

            How to Download Torrent and Hackintosh versions of Mac OS X 10.8 Mountain Lion

            As I mentioned earlier, the official download works only with developer login. If you are trying to download though torrent sites, here is the good news.

            1) Untouched version

            This torrent should be working fine as per the comments on this torrent forum. I have just finished downloading this torrent, and will update you soon on how to install it on VMware or VirtualBox. This version is not modified (as mentioned ‘untouched’) to work on Hackintosh platform, but I’m hoping this will work with VMware and VirtualBox on Intel based Windows computers. I could see a comment saying he managed to install it on VMware successfully.

            Download link of torrent

            2) Hackintosh Version

            On the same forum someone called this as Hackintosh version, but I’m not sure how it will be working.  I think this image doesn’t require installation. Just you can restore to USB stick or virtual machine hard disk, install Chameleon bootloader and boot the Hackintosh or virtual machine. If this works as said, I’m sure that will save huge time and work around. I will have a try after few days once I succeeded with above original image.

            Download link of torrent

            Stay tuned with Sysprobs for more Hackintosh on VMware and VirtualBox of Mac OS X 10.8 Mountain Lion news.

            Recommended Posts

            posted @ 2012-03-18 09:31 RTY 閱讀(642) | 評(píng)論 (0)編輯 收藏

            This article explains how to create a bootable (Mac) OS X 10.8 mountain Lion image (and ISO) for VMware workstation on Intel based Windows 7 computer. Recently I have mentioned about official 10.8 developer preview download and torrent download of latest OS from Apple. The original DMG file can not be booted on any hackintosh methods. But, by using this guide we can prepare a bootable image of Mountain Lion OS X and start the installation on VMware workstation as guest virtual machine.

            This guide is nothing to do with Hackintosh on physical computer. I have tested on desktop virtualization software VMware workstation only. So, it will be useful to run the developer preview version of OS X 10.8 without disturbing your physical Operating Systems.  Also, it is very safe, easy and possible to use with multiple Operating Systems simultaneously.

            OK, let’s come to our point. Here I’m explaining how to prepare the OS X 10.8 image and ISO which can be booted on VMware workstation with Intel based Windows computers. Usually the official dmg file should be used inside an existing Mac OS machine to install it in different partition (dual boot) or update the existing OS X. So, starting the installation on fresh virtual machine with same dmg file is not possible without doing few modifications.

            This method is exactly same which we used earlier to prepare Lion OS X 10.7 bootable image. Since I already explained each steps with Lion OS X earlier, I’m not going to repeat the same instructions here. Anyhow, keep reading…..

             

            What You Need?

            1) A working Snow Leopard or Lion OS X virtual machine on VMware or VirtualBox.

            More information available on how to install Snow Leopard on VMware, VirtualBox and Lion OS X on VMwareVirtualBox.

            2) Mountain Lion DMG file (Click here to read more)

             

            Summary – What We Are Going to Do?

            1) We will attach a new virtual hard disk (5GB) to existing Mac OS X virtual machine.

            2) Mount the Mountain Lion dmg file inside virtual machine.

            3) Restore the BaseSystem and packages (from downloaded dmg file) to newly attached virtual hard disk from virtual machine. Also few modifications.

            4) Now we can attach the ‘prepared’ 5GB virtual hard disk to new virtual machine to boot and start the installation.

            That’s it. Its very easy. But please follow the instruction correctly.

             

            Steps to Create Bootable OS X 10.8 Mountain Lion DMG on VMware Workstation

            1) Attach a 5GB new virtual hard disk to working Mac OS X  virtual machine. In this example, I’m doing it with Lion OS X (10.7) VM on VMware workstation, my host is Windows 7 32 bit.

            added disk

            2) Start the VM. Initialize the disk and format the newly added 5GB external hard disk with following configuration.

            Single partition with ‘Mac OS X Extended (Journaled)’ and ‘Apple Partition Map’ type which is available under Options in below screen.

            create new partition

            3) Now, we need to mount the 10.8 installation file. As you are aware OS X 10.8 installation file is in DMG format which will not work directly with VMware workstation. I tried to convert the DMG file to ISO on Windows 7 host as mentioned earlier in Sysprobs, but for some reasons it failed.

            So, I have directly copied mountain Lion dmg file (using USB disk) into working Lion 10.7 virtual machine. Then mounted by double clicking the dmg file.

            mounting dmg file

            4) Make sure its mounted properly. Check the listed volumes as shown below.

            mounted disk

            Above screen shows the mounted OS X 10.8 dmg file as ‘Mac OS X Install ESD’ and my new hard disk which I formatted in Step 2 as ‘bootablelion’.

            5) We are ready to start the restore and copy important packages process from mounted dmg file to new hard disk.

            As I said, the further steps clearly mentioned with screen shots earlier for Lion OS X (10.7).

            Please click here to visit the previous guide and follow the steps carefully.

            Also, you can create Mountain Lion bootable ISO file using the same method, which is clearly mentioned by these videos ( Click here)

             

            IMPORTANT NOTE:

            In previous guide, the new hard disk named as ‘LionInstaller’, but in this new example it is named as ‘bootablelion’. Also, when you restore the BaseSystem image, it may overwrite the partition name and you will get a new name as ‘Mac OS X Install ESD 1’. So, either rename the partition again before continue next steps or type the new name correctly on appropriate places while typing the commands.

            6) After new disk created properly, it can be attached to new virtual machine and start Mountain Lion installation. Please make sure, you have already applied VMware unlocker to be able to run Mac OS X guest virtual machines on Windows platform. Check our earlier guide on VMware 8.0 and 8.0.1 unlocker.

            Here is the first screen booted by ‘prepared’ 5GB hard disk on VMware workstation 8.0.1 on Windows 7 32 bit host.

            I will provide the step by step guide and additional required installation for Mountain Lion OS X 10.8 on VMware workstation in coming days.

            first screen

            I’m sure this guide will be helpful to prepare the bootable image of Mountain Lion for VMware workstation and VM Player. Mostly this should work with Oracle VirtualBox too, but we need to find out the correct boot loader for that. I will keep searching for that and update in this blog later.

            Have fun!

            Recommended Posts

            posted @ 2012-03-18 09:29 RTY 閱讀(2642) | 評(píng)論 (0)編輯 收藏

            僅列出標(biāo)題
            共31頁(yè): 1 2 3 4 5 6 7 8 9 Last 
            香港aa三级久久三级老师2021国产三级精品三级在 | 综合网日日天干夜夜久久| 亚洲精品无码成人片久久| 丰满少妇人妻久久久久久4| 国内精品九九久久精品| 久久精品国产一区| 热re99久久6国产精品免费| 久久男人AV资源网站| 91精品观看91久久久久久 | 99久久人人爽亚洲精品美女| 99久久精品国产一区二区| 久久精品亚洲精品国产欧美| 亚洲狠狠久久综合一区77777 | 国产午夜电影久久| 看久久久久久a级毛片| 99久久这里只精品国产免费| 久久久久一本毛久久久| 91秦先生久久久久久久| 国产成人综合久久综合| 精品久久久久久亚洲精品 | www.久久热.com| 潮喷大喷水系列无码久久精品| 欧洲性大片xxxxx久久久| 久久久久婷婷| 欧美精品丝袜久久久中文字幕| 热99re久久国超精品首页| 国产一级做a爰片久久毛片| 热99re久久国超精品首页| 99热都是精品久久久久久| 草草久久久无码国产专区| 99精品国产在热久久| av午夜福利一片免费看久久| 亚洲国产天堂久久综合网站 | 色综合久久久久| 久久黄视频| 无码乱码观看精品久久| 2021国内精品久久久久久影院| 婷婷久久五月天| 久久人人爽人人爽人人AV| 久久亚洲高清观看| 婷婷久久综合九色综合绿巨人|