• 使用预处理器帮助调试


    前言

      你是否遇到过以下情况?

      情况一:为了调试方便,代码中夹杂各种cout语句。当调试好了,把这些语句删了,运行“正式版”后,又发现新问题,只得把这些cout语句一个个添加回去再进行调试。如此不断循环。

      情况二:希望在代码中获取到源文件的文件名,当前代码行号,编译时间等信息。

      情况三:纠结于是否实现某些概率极低(几乎不存在)的错误检测

      如果有,那么这篇随笔适合你,或者说,预处理器带来的调试技术适合你。

    技巧一:设置调试区代码开关

      请看下面的源代码:

     1 #include <iostream>
     2  
     3 using namespace std;
     4  
     5 int main()
     6 {
     7     /*
     8     * 源代码区一
     9     */
    10 
    11     #ifdef DEBUG1
    12     cout << "DEBUG1" << endl;
    13     #endif
    14  
    15     /*
    16      * 源代码区二
    17     */
    18 
    19     #ifdef DEBUG2
    20     cout << "DEBUG2" << endl;
    21     #endif
    22 
    23     /*
    24      * 源代码区三
    25     */
    26 
    27     return 0;
    28  }                                    

      两段包含cout语句的代码段都是调试语句,而两个宏DEBUG1和DEBUG2就是所谓的开关。现在假设我想执行上面的那段调试代码,则可以输入以下指令打开DEBUG1开关并完成编译(这条命令等效于在源文件开头加上#define DEBUG1再编译):

    1 g++ -DDEBUG1 1.cpp -o run

      运行结果如下:

      

      结果显示DEBUG1开关对应的调试语句得到执行。可以用同样的方法操纵开关DEBUG2及其对应调试代码。明白了吧,你可以通过打开开关自由地选择需要编译并运行的调试区代码

    技巧二:使用预定义宏获取相关信息

      预处理器提供了一些预定义的宏可获取编译,文件的相关信息,参见下面代码:

     1 #include <iostream>
     2 
     3 using namespace std; 
     4 
     5 int main()
     6 {
     7     cout << "文件名: " << __FILE__ << endl;
     8     cout << "当前行号: " << __LINE__ << endl;
     9     cout << "编译日期: " << __DATE__ << endl;
    10     cout << "编译时间: " << __TIME__ << endl;
    11 
    12     return 0;
    13 }

      运行结果:

      

    技巧三:使用assert断言宏确保某个条件不发生

      基本格式为 assert(表达式)。当表达式为真,语句不做任何事情,否则语句输出错误并终止程序执行,请看下面代码:

     1 #include <iostream>
     2 #include <cassert>    // 要使用assert断言宏必须包含这个头文件
     3  
     4 using namespace std;
     5  
     6 int main()
     7 {
     8     int t=0;
     9     cin >> t;
    10 
    11     assert (t !=0);
    12     cout << "t: " << t << endl;
    13  
    14     return 0;
    15 }

      assert在这里的作用是确保t不等于0。如果t=0,程序会弹出错误并停止运行。编译代码并运行,

      当输入为0时运行结果:

      

      当输入其他数字时运行结果:

      

      最后要强调的是,assert只是调试工具,它绝对不能代替逻辑检查参与到异常处理中。

      

  • 相关阅读:
    Android开发 使用 adb logcat 显示 Android 日志
    【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410
    C语言 结构体相关 函数 指针 数组
    C语言 命令行参数 函数指针 gdb调试
    C语言 指针数组 多维数组
    Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
    C语言 内存分配 地址 指针 数组 参数 实例解析
    CRT 环境变量注意事项
    hadoop 输出文件 key val 分隔符
    com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Too many connections
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3213282.html
Copyright © 2020-2023  润新知