程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> goto的好處

goto的好處

編輯:關於C語言

 

向來都是 不要用goto,破壞可讀性,容易是bug頻出。我也深信不疑。

最近維護一個程序代碼,包了N多層了(超過5層),裡面有while if for,

我在跳出來的時候用了一次goto,還挺好用,但是沒發現什麼異常。

網上百度了一下goto總結了一下他的作用:

 

不使用goto

 

int i = 0, j = 0; 

while( true ) 

     while ( true ) 

     { 

     if ( 4 == j ) 

     break; 

     j++; 

     } 

     If ( 4 == i ) 

     break; 

     } 

     i++; 

int i = 0, j = 0;

while( true )

{

        while ( true )

        {

        if ( 4 == j )

        break;

        j++;

        }

        If ( 4 == i )

        break;

        }

        i++;

}使用goto

 

int i = 0, j = 0; 

while ( true ) 

     while ( true ) 

     { 

     if ( 4 == j && 4 == i ) 

     goto EXIT_WHILE; 

     j++; 

     } 

     i++; 

EXIT_WHILE: 

... 

int i = 0, j = 0;

while ( true )

{

        while ( true )

        {

        if ( 4 == j && 4 == i )

        goto EXIT_WHILE;

        j++;

        }

        i++;

}

EXIT_WHILE:

...如果不使用goto,很難一下子看出循環出口是i=4,j=4。而用了goto之後這一點變得一目了然了,而EXIT

 

標記就在循環外,很好找,所以代碼的可讀性並沒有降低多少。

 

 

 

 

看Microsoft的msxml—sdk裡面的例子,他用了goto

 

#include <stdio.h>  

#include <msxml2.h>  

 

// You might need to add the msxml4/sdk/(inc, lib) directories   

// to the Tools->Options...->Directories in Visual Studio.  

//  

// You might also need to append "msxml2.lib" to the  

// Project->Settings...->Link->Object/Libray Modules field.  

 

int main(int argc, char* argv[]) 

   HRESULT hr; 

   IXMLDOMDocument3 *pXMLDoc = NULL; 

   IXMLDOMParseError * pObjError = NULL; 

   BSTR bstr = NULL; 

   VARIANT_BOOL status; 

   VARIANT vSrc; 

 

   CoInitialize(NULL); 

 

   hr = CoCreateInstance(CLSID_DOMDocument40,  

                     NULL,  

                     CLSCTX_INPROC_SERVER,  

                     IID_IXMLDOMDocument3, 

                     (void**)&pXMLDoc); 

 

   if (FAILED(hr))  

   { 

      printf("Failed to CoCreate an instance of an XML DOM\n"); 

      printf("Error code: %x\n", hr); 

      goto clean; 

   } 

 

   hr = pXMLDoc->put_async(VARIANT_FALSE); 

   if (FAILED(hr)) 

   { 

      printf("Failed to set async property\n"); 

      goto clean; 

   } 

 

   hr = pXMLDoc->put_validateOnParse(VARIANT_FALSE); 

   if (FAILED(hr)) 

   { 

      printf("Failed to set validateOnParse\n"); 

      goto clean; 

   } 

 

   hr = pXMLDoc->put_resolveExternals(VARIANT_FALSE); 

   if (FAILED(hr)) 

   { 

      printf("Failed to disable resolving externals.\n"); 

      goto clean; 

   } 

 

   VariantInit(&vSrc); 

   V_BSTR(&vSrc) = SysAllocString(L"stocks.xml"); 

   V_VT(&vSrc) = VT_BSTR; 

 

   hr = pXMLDoc->load(vSrc, &status); 

 

   if(status!=VARIANT_TRUE) 

   { 

      hr = pXMLDoc->get_parseError(&pObjError); 

      hr = pObjError->get_reason(&bstr); 

      printf("Failed to load DOM from books.xml. %S\n",bstr); 

      goto clean; 

   } 

 

   hr = pXMLDoc->get_xml(&bstr); 

   printf("stocks.xml:\n%S\n", bstr); 

 

clean:    

   if (bstr) 

      SysFreeString(bstr); 

   if (&vSrc)  

      VariantClear(&vSrc); 

   if (pObjError) 

      pObjError->Release(); 

   if (pXMLDoc) 

      pXMLDoc->Release(); 

   CoUninitialize(); 

   return 0; 

 

#include <stdio.h>

#include <msxml2.h>

 

// You might need to add the msxml4/sdk/(inc, lib) directories

// to the Tools->Options...->Directories in Visual Studio.

//

// You might also need to append "msxml2.lib" to the

// Project->Settings...->Link->Object/Libray Modules field.

 

int main(int argc, char* argv[])

{

   HRESULT hr;

   IXMLDOMDocument3 *pXMLDoc = NULL;

   IXMLDOMParseError * pObjError = NULL;

   BSTR bstr = NULL;

   VARIANT_BOOL status;

   VARIANT vSrc;

 

   CoInitialize(NULL);

 

   hr = CoCreateInstance(CLSID_DOMDocument40,

                     NULL,

                     CLSCTX_INPROC_SERVER,

                     IID_IXMLDOMDocument3,

                     (void**)&pXMLDoc);

 

   if (FAILED(hr))

   {

      printf("Failed to CoCreate an instance of an XML DOM\n");

      printf("Error code: %x\n", hr);

      goto clean;

   }

 

   hr = pXMLDoc->put_async(VARIANT_FALSE);

   if (FAILED(hr))

   {

      printf("Failed to set async property\n");

      goto clean;

   }

 

   hr = pXMLDoc->put_validateOnParse(VARIANT_FALSE);

   if (FAILED(hr))

   {

      printf("Failed to set validateOnParse\n");

      goto clean;

   }

 

   hr = pXMLDoc->put_resolveExternals(VARIANT_FALSE);

   if (FAILED(hr))

   {

      printf("Failed to disable resolving externals.\n");

      goto clean;

   }

 

   VariantInit(&vSrc);

   V_BSTR(&vSrc) = SysAllocString(L"stocks.xml");

   V_VT(&vSrc) = VT_BSTR;

 

   hr = pXMLDoc->load(vSrc, &status);

 

   if(status!=VARIANT_TRUE)

   {

      hr = pXMLDoc->get_parseError(&pObjError);

      hr = pObjError->get_reason(&bstr);

      printf("Failed to load DOM from books.xml. %S\n",bstr);

      goto clean;

   }

 

   hr = pXMLDoc->get_xml(&bstr);

   printf("stocks.xml:\n%S\n", bstr);

 

clean:  

   if (bstr)

      SysFreeString(bstr);

   if (&vSrc)

      VariantClear(&vSrc);

   if (pObjError)

      pObjError->Release();

   if (pXMLDoc)

      pXMLDoc->Release();

   CoUninitialize();

   return 0;

 

}

使用goto後,指針集中釋放,即使出現內存洩露也很容易發現,而且指針空間的釋放都

只出現了1次-------出錯易排查。

 

借那句經典的話吧:goto少用、慎用,但是不能禁用。

摘自 lingxiu0613的專欄

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