久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C語(yǔ)言中幾種輸出調(diào)試信息的方法

 just_person 2012-09-03

在調(diào)試程序時(shí),輸出調(diào)試信息是一種普遍,、有效的方法,。輸出調(diào)試信息一般有以下五種方法:

方法一:直接使用屏幕打印函數(shù)printf,。

該方法直接在需要輸出調(diào)試信息的位置使用函數(shù)printf輸出相應(yīng)的調(diào)試信息,,以及某些關(guān)鍵變量的值,。我們通過(guò)以下求階層的函數(shù)fact來(lái)看看該方法的調(diào)試程序過(guò)程,。

 #include <stdio.h>
 int fact(int n)
 {
         int i,f=1;
         for( i=1; i<=n; i++)
         {
                 f += i;
         }
         return f;
 }
 int main()
 {
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序1: 有bug的求階層函數(shù)

程序1編譯運(yùn)行的結(jié)果如下:

4!=11

結(jié)果錯(cuò)誤,。為了找到結(jié)果錯(cuò)誤的原因,我們?cè)谡Z(yǔ)句"f += i;"之后插入函數(shù)printf輸出調(diào)試信息,,如程序2,。

 #include <stdio.h>
 int fact(int n)
 {
         int i,f=1;
         for( i=1; i<=n; i++)
         {
                 f += i;
                 printf("i=%d ; f=%d/n", i, f);
         }
         return f;
 }
 int main()
 {
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序2: 加入函數(shù)printf輸出調(diào)試信息的求階層函數(shù)

再編譯運(yùn)行該程序,,屏幕輸出如下:

i=1 ; f=2 i=2 ; f=4 i=3 ; f=7 i=4 ; f=11 4!=11

原來(lái)語(yǔ)句"f += i"錯(cuò)了,應(yīng)該為"f *=i",。修改過(guò)來(lái)(見(jiàn)程序3),,再編譯運(yùn)行,結(jié)果如下:

i=1 ; f=1 i=2 ; f=2 i=3 ; f=6 i=4 ; f=24 4!=24 #include <stdio.h>
 int fact(int n)
 {
         int i,f=1;
         for( i=1; i<=n; i++)
         {
                 f *= i;
                 printf("i=%d ; f=%d/n", i, f);
         }
         return f;
 }
 int main()
 {
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序3: 修改正確的求階層函數(shù)

調(diào)試完成,,bug找到,,并修改正確。然后將加入的調(diào)試的函數(shù)printf 刪除或注釋掉,。

該方法的缺點(diǎn)是(1)在正式發(fā)布的程序中需要去除或注釋掉這些調(diào)試語(yǔ)句,;(2)若程序又出現(xiàn)bug,則又需要重新插入函數(shù)printf輸出調(diào)試信息,,造成工作的重復(fù),。

方法二:自定義調(diào)試函數(shù)debug。

為 了避免方法一的缺點(diǎn),,可以利用條件編譯技術(shù),,如程序4自定義調(diào)試函數(shù)debug。當(dāng)程序正式發(fā)布的編譯時(shí)取消宏定義__DEBUG__,,在正式發(fā)布的程序 中就不會(huì)輸出調(diào)試信息,。若又出現(xiàn)bug,只要重新在編譯程序時(shí)定義宏__DEBUG__即可恢復(fù)原來(lái)的調(diào)試信息輸出,??梢栽诰帉?xiě)程序時(shí)就有目的事先插入些 調(diào)試語(yǔ)句,這將有益于調(diào)試程序,。另外,可以根據(jù)需要編寫(xiě)函數(shù)debug,,將調(diào)試信息輸出到除屏幕以外的其它地方,,如文件或syslog服務(wù)器等。

 #include <stdio.h>
 
 #ifdef __DEBUG__
 #include <stdarg.h>
 void debug(const char *fmt, ...)
 {
         va_list ap;
         va_start(ap, fmt);
         vprintf(fmt, ap);
         va_end(ap);
 }
 #else
 void debug(const char *fmt, ...)
 {
 }
 #endif
 
 int fact(int n)
 {
         int i, f = 1;
         for( i=1; i<=n; i++)
         {
                 f *= i;
                 debug("i=%d ; f=%d/n", i, f);
         }
         return f;
 }
 int main()
 {
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序4: 自定義調(diào)試函數(shù)debug

該方法的缺點(diǎn)是(1)調(diào)試信息要么全部輸出,,要么全不輸出,;(2)要重新輸出調(diào)試信息時(shí)需要重新編譯程序。

方法三:含調(diào)試等級(jí)的自定義調(diào)試函數(shù)debug,。

可 以繼續(xù)改進(jìn)方法,,避免方法二中的缺點(diǎn)。我們可以根據(jù)調(diào)試信息的細(xì)節(jié)程度,,將調(diào)試信息分成不同的等級(jí),。調(diào)試信息的等級(jí)必須大于0,若調(diào)試信息細(xì)節(jié)程度越高,, 則等級(jí)越高,。在輸出調(diào)試信息時(shí),,若調(diào)試等級(jí)高于調(diào)試信息等級(jí)才輸出調(diào)試信息,否則忽略該調(diào)試信息,,如程序5,。當(dāng)調(diào)試等級(jí)為0時(shí),則不輸出任何調(diào)試信息,。

 #include <stdio.h>
 #include <stdlib.h>   /* atoi() */
 
 #include <stdarg.h>
 
 int debug_level;
 void debug(int level, const char *fmt, ...)
 {
         if( level <= debug_level )
         {
                 va_list ap;
                 va_start(ap, fmt);
                 vprintf(fmt, ap);
                 va_end(ap);
         }
 }
 
 int fact(int n)
 {
         int i, f = 1;
         for( i=1; i<=n; i++)
         {
                 f *= i;
                 debug(250, "i=%d ; f=%d/n", i, f);
         }
         return f;
 }
 int main(int argc, char *argv[])
 {
         if ( argc < 2 )
         {
                 debug_level = 0;
         }
         else
         {
                 debug_level = atoi(argv[1]);
         }
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序5: 含調(diào)試等級(jí)的自定義調(diào)試函數(shù)debug

用命令"gcc -Wall -o fact fact.c"編譯程序5,,得到可執(zhí)行文件 fact。若需要輸出調(diào)試信息,,只需要指定調(diào)試等級(jí)不低于250即可,,如運(yùn)行命令"./fact 250",否則將不會(huì)輸出調(diào)試信息,。

這樣,,在正式發(fā)布版中包含調(diào)試信息也無(wú)傷大雅了,因?yàn)橹恍鑼⒄{(diào)試等級(jí)配置為0,,將不會(huì)出現(xiàn)任何調(diào)試信息,。

該方法的缺點(diǎn)是效率不太高,因?yàn)椴还苷{(diào)試信息是否需要輸出,,都會(huì)進(jìn)行一次函數(shù)調(diào)用,。若不需要輸出調(diào)試信息,這次函數(shù)調(diào)用就多余了,。

方法四:調(diào)試等級(jí)的判斷放在自定義調(diào)試函數(shù)debug之外,。

為了減少不必要的函數(shù)調(diào)用,可以用宏定義將調(diào)試等級(jí)的判斷放在函數(shù)debug之外,,如程序6,。

 #include <stdio.h>
 #include <stdlib.h>   /* atoi() */
 
 #include <stdarg.h>
 
 int debug_level;
 
 #define debug(level, fmt, arg...) /
         if( level <= debug_level ) __debug(fmt, ##arg)
 
 void __debug(const char *fmt, ...)
 {
         va_list ap;
         va_start(ap, fmt);
         vprintf(fmt, ap);
         va_end(ap);
 }
 
 int fact(int n)

 {
         int i, f = 1;
         for( i=1; i<=n; i++)
         {
                 f *= i;
                 debug(250, "i=%d ; f=%d/n", i, f);
         }
         return f;
 }
 int main(int argc, char *argv[])
 {
         if ( argc < 2 )
         {
                 debug_level = 0;
         }
         else
         {
                 debug_level = atoi(argv[1]);
         }
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序6: 調(diào)試等級(jí)的判斷放在自定義調(diào)試函數(shù)debug之外

這種方法對(duì)于不需要輸出的高等級(jí)的調(diào)試信息操作來(lái)說(shuō),僅僅多了個(gè)兩個(gè)整數(shù)之間的大小判斷,。在正式的程序運(yùn)行時(shí),,效率是有所提高的。

但 這種調(diào)試信息輸出的方法依然不夠完美,。對(duì)于一個(gè)大項(xiàng)目,,一般分為若干個(gè)模塊,bug將會(huì)定位到某個(gè)或某幾個(gè)模塊,。若整個(gè)項(xiàng)目的調(diào)試信息都輸出,,信息量將會(huì) 非常大,也容易干擾調(diào)試人員的思維,。這時(shí),,我們需要的是只輸出我們關(guān)心的那些模塊的調(diào)試信息,但該方法并不能達(dá)到我們的要求。它只能根據(jù)調(diào)試等級(jí)輸出信 息,,對(duì)于同一調(diào)試等級(jí)的信息要么全輸出,,要么全不輸出。

方法五:根據(jù)不同的功能模塊分別定義不同的調(diào)試等級(jí),。

在squid[1]中,,定義了以下的功能模塊調(diào)試等級(jí)變量和調(diào)試函數(shù):

 int debugLevels[MAX_DEBUG_SECTIONS];
 #define debug(SECTION, LEVEL) /
         ((_db_level = (LEVEL)) > debugLevels[SECTION]) ? (void) 0 : _db_print

然后在程序中如下使用它:

 debug(17, 3) ("fwdStateFree: %p/n", fwdState);

上述調(diào)試函數(shù)很靈活,,可以在不同的模塊中定義有不同的調(diào)試等級(jí),,當(dāng)需要調(diào)試某功能時(shí),,只需將該模塊的調(diào)試等級(jí)定義為相應(yīng)的等級(jí),,就可輸出需要的調(diào)試信息。

根據(jù)方法五的思想,,本人編寫(xiě)了my_debug.h(見(jiàn)程序7)和my_debug.c 文件(見(jiàn)程序8),。該文件可以應(yīng)用于C語(yǔ)言程序中,支持根據(jù)不同的功能模塊分別定義不同的調(diào)試等級(jí),。

 #ifndef MY_DEBUG_H
 #define MY_DEBUG_H
 
 #include <stdio.h>
 
 // 模塊功能號(hào)
 enum {
  MY_SECTION_FACT = 0,
  MY_SECTION_nnn1,
  MY_SECTION_nnn2,
  MY_SECTION_nnnn, 
  MY_SECTION_END,
 };
 
 // 非my_debug.c文件的外部變量聲明
 #ifndef MY_DEBUG_C
 extern int __my_allow_debug_levels[MY_SECTION_END];
 #endif
 
 // (內(nèi)部使用) 判斷"SECTION"模塊功能號(hào)是否允許"DEBUG_LEVEL"等級(jí)的調(diào)試信息輸出
 #define __my_unallow_debug(SECTION, DEBUG_LEVEL) /
  ( DEBUG_LEVEL > __my_allow_debug_levels[SECTION] )
 
 // (內(nèi)部使用) 調(diào)試信息輸出函數(shù)
 #define __my_debug(FORMAT, ARG...) /
  printf("%s:%d %s: " FORMAT, __FILE__, __LINE__, __FUNCTION__, ##ARG)
 
 // 初始化"SECTION"模塊功能號(hào)的調(diào)試等級(jí)
 #define my_init_debug_levels(SECTION, ALLOW_DEBUG_LEVEL) /
  ( __my_allow_debug_levels[SECTION] = ALLOW_DEBUG_LEVEL )
 
 // 調(diào)試信息輸出函數(shù),該信息為"SECTION"模塊功能號(hào)"DEBUG_LEVEL"等級(jí)的調(diào)試信息
 #define my_debug(SECTION, DEBUG_LEVEL) /
         ( __my_unallow_debug(SECTION, DEBUG_LEVEL) ) ? (void) 0 : __my_debug
 
 #endif //MY_DEBUG_H
 程序7: my_debug.h

 #define  MY_DEBUG_C
 #include "my_debug.h"
 
 int __my_allow_debug_levels[MY_SECTION_END];
 
 程序8: my_debug.c

要使用上述文件,,先得根據(jù)功能模塊的數(shù)目擴(kuò)展my_debug.h中的“模塊功能號(hào)”枚舉類(lèi)型,,然后在程序相應(yīng)位置中調(diào)用宏定義my_init_debug_levels 初始化相應(yīng)模塊的調(diào)試等級(jí),,在所有需要輸出調(diào)試信息的位置如下編寫(xiě)即可,。

my_debug(MY_SECTION_FACT, 250)("i=%d ; f=%d/n", i, f);

下面我們來(lái)看看如何在fact.c中使用它們(見(jiàn)程序9)。

 #include <stdio.h>
 #include <stdlib.h>
 
 #include "my_debug.h"
 
 int fact(int n)
 {
         int i, f = 1;
         for( i=1; i<=n; i++)
         {
                 f *= i;
                 my_debug(MY_SECTION_FACT, 250)("i=%d ; f=%d/n", i, f);
         }
         return f;
 }
 int main(int argc, char *argv[])
 {
         if ( argc < 2 )
         {
                 my_init_debug_levels(MY_SECTION_FACT, 0);
         }
         else
         {
                 my_init_debug_levels(MY_SECTION_FACT, atoi(argv[1]));
         }
         printf( "4!=%d/n", fact(4) );
         return 0;
 }
 程序9: fact.c

參考文獻(xiàn):

[1] squid, http://www.

 

轉(zhuǎn)載:http://blog.csdn.net/thinkerABC/article/details/615378

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多