程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 用匯編的眼光看C++(之循環流程)

用匯編的眼光看C++(之循環流程)

編輯:C++入門知識

 

【 聲明:版權所有,歡迎轉載,請勿用於商業用途。  聯系信箱:feixiaoxing @163.com】

 

 

    循環是我們編程中遇到的另外一項重要技術。通過反復的迭代運算,我們可以獲取想要的任何結果。當然這種迭代是有基本條件的,或是以時間為條件的,或是以空間為條件的,或者是某一種外來交互作為條件的。循環的方式有很多種,但是常用的還是:while、for、do-while、goto這幾種。很多公司的項目都不喜歡goto,這其中倒不是說goto不好,主要是goto的隨意性太大,一旦用的不好,就會降低代碼的可讀性,反而影響其他人的工作效率。

 

    (1)do-while為什麼先執行,後判斷?

 

    老規矩,我們還是先看代碼示例再說:

 

 

21:       int m = 10; 

00401638   mov         dword ptr [ebp-4],0Ah 

22:       do { 

23:           printf("%d\n", m); 

0040163F   mov         eax,dword ptr [ebp-4] 

00401642   push        eax 

00401643   push        offset string "%d\n" (0046f01c) 

00401648   call        printf (00420fb0) 

0040164D   add         esp,8 

24:           m ++; 

00401650   mov         ecx,dword ptr [ebp-4] 

00401653   add         ecx,1 

00401656   mov         dword ptr [ebp-4],ecx 

25:       }while(m < 10); 

00401659   cmp         dword ptr [ebp-4],0Ah 

0040165D   jl          process+1Fh (0040163f) 

    如果換成while呢?

 

21:       int m = 10; 

00401638   mov         dword ptr [ebp-4],0Ah 

22:       while(m < 20) 

0040163F   cmp         dword ptr [ebp-4],14h 

00401643   jge         process+41h (00401661) 

23:       { 

24:           printf("%d\n", m); 

00401645   mov         eax,dword ptr [ebp-4] 

00401648   push        eax 

00401649   push        offset string "%d\n" (0046f01c) 

0040164E   call        printf (00420fb0) 

00401653   add         esp,8 

25:           m ++; 

00401656   mov         ecx,dword ptr [ebp-4] 

00401659   add         ecx,1 

0040165C   mov         dword ptr [ebp-4],ecx 

26:       } 

0040165F   jmp         process+1Fh (0040163f) 

27:   } 

    其實,上面的代碼表現已經很明顯了。do-while的時候,模塊上來先進行運算,然後再判斷數據范圍的大小;while就不一樣,上來就進行判斷,判斷成功就繼續運行,否則就退出循環模塊,如果是for的情況呢?

 

21:       for(int m = 10; m < 20; m++) 

00401638   mov         dword ptr [ebp-4],0Ah 

0040163F   jmp         process+2Ah (0040164a) 

00401641   mov         eax,dword ptr [ebp-4] 

00401644   add         eax,1 

00401647   mov         dword ptr [ebp-4],eax 

0040164A   cmp         dword ptr [ebp-4],14h 

0040164E   jge         process+4Ch (0040166c) 

22:       { 

23:           printf("%d\n", m); 

00401650   mov         ecx,dword ptr [ebp-4] 

00401653   push        ecx 

00401654   push        offset string "%d\n" (0046f01c) 

00401659   call        printf (00420fc0) 

0040165E   add         esp,8 

24:           m ++; 

00401661   mov         edx,dword ptr [ebp-4] 

00401664   add         edx,1 

00401667   mov         dword ptr [ebp-4],edx 

25:       } 

0040166A   jmp         process+21h (00401641) 

    我們發現,其實for和上面的while,do-while有點小區別。在m第一次賦值的時候,並不進行加1處理,而是直接跳到地址0x40164a處運行,判斷m數值和20進行判斷。判斷成功,則跳入循環模塊,否則越過循環模塊。那麼,在循環處理結束後呢?也就是m++後,循環模塊是怎麼處理的?我們發現代碼又回到了0x00401641處處理。但是這裡並不是整個循環模塊開始出的代碼,而是對m進行自增處理。完成自增後,繼續判斷,下面的流程和第一次一樣,不再贅述。

 

    (2)多重循環怎麼跳出來?

 

    很多朋友編碼的時候都有這樣的一個困擾,有的時候希望在多層循環中尋找某一個條件的變量,但是在找到特定變量後,希望趕快退出循環。我們應該怎麼做呢,下面是我個人的做法,僅供大家參考。

 

 

int flag = 0;  

       for(int m = 1; m < 20 && !flag; m++) 

    for(int n = 1; n < 20 && !flag; n++) 

    { 

        for(int t = 1; t < 20 && !flag; t++) 

        { 

            if(/* special conditions are satisfied */) 

                flag = 1; 

        } 

    } 

 

    (3)while(1)是否有其他的表示方法?

 

 

int flag = 0; 

for(;;) { 

    /* code segment */ 

 

do{ 

    /* code segment */ 

}while(1); 

 

 loop: 

    /* code segment */ 

 

if(!flag) 

    goto loop; 

 

總結:

    其實,循環中還有很多的細節需要處理,你比如說:

 

    (1)循環的時候請務必填上程序終止的條件

 

    (2)循環的時候注意8位char和32和int之間的區別,務必不要死循環

 

    (3)字符的循環務必注意‘\0’

 

    (4)不要把循環、判斷合二為1,給你的同事留條活路,不要以為while(*dst ++  = *src ++);這樣寫代碼很帥

 

    (5)務必注意自己的返回值是你需要的那個地址,還是前一個地址,還是下一個地址

 

     (6)不要在for(;;)中添加額外的語句,加的越多,風險越多

 

     

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved