代码的调试技巧

简介: 代码的调试技巧

什么是bug

bug的本意是指昆虫、小虫、损坏、缺陷等意思,一般地,在程序设计中的术语,bug是在软件运行中因为程序代码本身有错误而造成的功能不正常、体验不佳、数据丢失、非正常中断、死机等现象。

调试是什么?有多重要?

调试是什么?

调试是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。在调试的过程中我们可以监控程序的每一个细节,包括变量、函数的调用过程、内存的变化等等。

调试的基本技巧

  • 发现程序错误的存在;
  • 以隔离、消除等方式对错误进行定位;
  • 确定错误产生的原因;
  • 提出纠正错误的解决办法;
  • 对程序错误改正,重新测试。

Debug和Release的介绍

Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便于用户很好的使用。

代码:

#include<stdio.h>
int main()
{
  char* p = "hello";
  printf("%s\n", p);
  return 0;
}

以上代码在Debug环境的展示:

以上代码在Release环境下的展示:

反汇编对比:

所以我们说的调试就是在Debug版本的环境中,找到代码中的潜伏问题的过程。

编译器进行了那些优化呢?请看下面的代码:

#include<stdio.h>
int main()
{
  int i = 0;
  int arr[10] = { 0 };
  for (i = 0; i <= 12; i++)
  {
    arr[i] = 0;
    printf("haha\n");
  }
  return 0;
}

如果是Debug模式去编译,程序的死循环。

但是如果是Release版本去编译的话,程序没有死循环。

Windows环境调试介绍

调试准备

在环境中选择debug选项,才能使代码正常调试。

学会快捷键

F5

启动调试

F9

创建断点和取消断点

F10

逐过程,一个过程可以是一次函数的调用,或者是一个语句。

F11

逐语句,就是每次执行一条语句,这个快捷键可以使我们进入函数的内部。

CTRL+F5

开始执行不调试。

调试的时候查看程序当前信息

查看临时变量的值

在调试开始之后,用于观察变量的值。

代码:

#include<stdio.h>
int main()
{
  int a = 0;
  a = 10;
  printf("%d", a);
  return 0;
}

先按F10在菜单栏上面找到调试点击—>窗口—>点击监视

查看内存信息

也是相同的方法,点击窗口之后在点击内存。

查看调用堆栈

也是相同的方法,点击窗口之后再点击调用堆栈。

查看汇编信息

在调试开始之后,右键鼠标,选择反汇编

在调试开始之后,点击菜单栏上的调试,再点击窗口,就可以找到反汇编。

查看寄存器信息

在调试开始之后,选择菜单栏上的调试,再选择窗口,选择寄存器。

如何写出好(易于调试)的代码

优秀的代码

  • 代码运行正常;
  • bug很少;
  • 效率很高;
  • 可读性高;
  • 可维护性高;
  • 注释清晰;
  • 文档齐全。

常见的技巧

  • 使用assert
  • 尽量使用const
  • 养成良好的代码风格
  • 添加必要的注释
  • 避免代码的陷阱

案例:

模拟实现库函数strcpy()

代码如下:

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* arr2,const char* arr)
{
  char* ret = arr2;
  //断言
  assert(arr2 != NULL);
  assert(arr != NULL);
  while (*arr2++ = *arr++)
    ;
  return ret;
}
int main()
{
  char arr[] = "abcd";
  char arr2[20] = "XXXXXXXXXXX";
  /*my_strcpy(arr2, arr);
  printf("%s", arr2);*/
  printf("%s", my_strcpy(arr2, arr));
  return 0;
}

const的作用

修饰指针变量的时候:

  1. const如果再*号的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变,但是指针变量本身是可以改变的。
  2. const如果再*号的右边,修饰的是指针变量本身,保证了指针变量的内容不能改变,但是可以通过改变指针变量的指向来改变内容。

编程常见的错误

编译类型错误

直接查看错误信息,解决问题。

链接型错误

一般是标识符名不存在或者拼写错误。

运行错误

借助调试,一步来排查。

相关文章
|
5月前
|
网络协议 网络安全 网络架构
开发者急盼!Cisco Packet Tracer超详细下载安装教程,附中文版插件使用步骤!
Cisco Packet Tracer是思科推出的专业路由器模拟器,适用于学习IOS配置、故障排查及网络拓扑构建。支持多种协议(STP、OSPF等),含无线功能与安全设备。本文提供下载链接、安装教程及高级功能介绍,如复杂网络仿真、可视化调试、自动化脚本和行业场景模拟等,助你高效学习网络技术并启用中文语言包。
1861 17
开发者急盼!Cisco Packet Tracer超详细下载安装教程,附中文版插件使用步骤!
|
12月前
|
自动驾驶 物联网 5G
毫米波技术及其在5G网络中的应用详解
毫米波技术及其在5G网络中的应用详解
1189 3
|
存储 机器学习/深度学习 人工智能
AIGC训练场景下的存储特征研究
在今天这样以AIGC为代表的AI时代下,了解训练场景对于存储的具体诉求同样是至关重要的。本文将尝试解读WEKA的一个相关报告,来看看AIGC对于存储有哪些具体的性能要求。
95331 8
|
算法 调度 UED
操作系统中的进程调度策略及其对系统性能的影响
本文深入探讨了操作系统中进程调度的多种策略,包括先来先服务、短作业优先、优先级调度、轮转与多级队列等,并分析了它们对系统性能的具体影响。通过比较不同调度算法的效率和公平性,本文旨在为系统管理员提供选择合适调度策略的依据,以优化系统的整体表现。
二次元风格404页面源码
二次元风格404页面源码
273 11
二次元风格404页面源码
|
缓存 弹性计算 Java
云效产品使用报错问题之maven仓设置为私有后,赋予成员权限未生效,拉包401要如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
关系型数据库 Java 数据库
docker部署postgresql数据库和整合springboot连接数据源
docker部署postgresql数据库和整合springboot连接数据源
284 0
|
机器学习/深度学习 自然语言处理 语音技术
Transformer框架
Transformer框架
331 1
|
存储 运维 监控
SRE方法论之监控设计
监控系统的四个黄金指标是:延迟(Latency)、流量(Traffic)、错误(Errors)、饱和度(Saturation)