Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【C语言】调试技巧

【C语言】调试技巧

作者头像
謓泽
发布于 2022-12-12 05:21:12
发布于 2022-12-12 05:21:12
84300
代码可运行
举报
文章被收录于专栏:【C】系列【C】系列
运行总次数:0
代码可运行

各位小伙伴们大家好,我是泽奀( ̄o ̄) . 相信大家在编写C程序中会遇到很多代码的Bug.所以本篇博客就带大家如何调试C的技巧,这样在遇到有错误的代码,也不必惊慌,只需调试下,Bug就再也不会存在了哈哈哈~隔。 

目录

😀什么是bug? 

💢臭虫:

⬛什么是调试?

🕳调试的基本步骤

🥓Debug和Release

🍖Debug:

🍗Release:

😐本质区别:

🚗Debug 版本:

🚓Release 版本:

✨Release版本优化:

🎉运行与调试常用的快捷键 

🎊查看程序的信息

🎇如何写出好的代码?

🎄优秀的代码

🎋常见的coding技巧 

🎍assert代码使用:

什么是bug? 

bug:Bug的原意:可以称之为“臭虫",现在指代的是漏洞,就是在安全系统上出现缺陷,攻击者可以对未授权的情况下进行攻击,Bug(计算机漏洞) 可以形容在各个领域范围之内所出现的漏洞。

 臭虫:

  • 中文常称BUG为“缺陷”。而且,“缺陷”一词更能反映事情的本质。因为“臭虫”是从外面飞进去的,并非程序本身有问题。而程序本身存在的问题,是程序原来就具有的。因此,在这里将BUG翻译为“系统漏洞”更合适。

由来:第一代的计算机是由许多庞大且昂贵的真空管组成,并利用大量的电力来使真空管发光。可能正是由于计算机运行产生的光和热,引得一只小虫子(Bug)钻进了一支真空管内,导致整个计算机无法正常工作。研究人员费了半天时间,总算发现原因所在,把这只小虫子从真空管中取出后,计算机又恢复正常。后来,Bug这个名词就沿用下来,用来表示电脑系统或程序中隐藏的错误、缺陷、漏洞等问题。

1945年,计算机还是由机械式继电器和真空管驱动的,机器有房间那么大。体现当时技术水平的MarkⅡ,是由哈佛大学制造的一个庞然大物。当技术人员正在进行不整机运行时,它突然停止了工作。他们爬上去找原因,发现这台巨大的计算机内部一组继电器的触点之间有一只飞蛾,这显然是由于飞蛾受光和热的吸引,飞到了触点上,然后被高电压击死。与Bug相对应,人们将发现Bug并加以纠正的过程叫做“Debug”(中文称作“调试”),意即“捉虫子”或“杀虫子”。

什么是调试?

调试其实就是找出bug,计算机有bug一定是你程序的问题。所有发生的程序的问题都是有迹可循的,我们只需要顺藤摸瓜最后一步步解决。

一名优秀的程序员,必然是一名优秀的侦探。每一次的调试其实就是破案的过程。

调试:英文DeBug,又称作是除错,是发现和减少计算机程序设备中和电子仪器错误的过程。

调试的基本步骤

  • 发现程序的错误所在: 
  1. 程序员(写程序)
  2. 软件测试人员(测试程序的重要性)
  3. 用户/玩家

代价最小的是程序员,代价最大的是用户。

  • 以隔离消除的方式对错误进行定义
  • 确定错误的产生
  • 提出纠正的错误方法
  • 对程序的错误给予改正,并且改正完之后进行重新的修正

Debug和Release

Debug:

通常为调试版本,它包含的调试信息,并且不会做进行任何的优化,便于程序员的调试信息。

概念:

1937年,美国青年霍华德·艾肯找到IBM公司为其投资200万美元研制计算机,第一台成品艾肯把它取名为:马克1号(mark1),又叫“自动序列受控计算机”,从这时起IBM公司由生产制表机,肉铺磅秤,咖啡研磨机等乱七八糟玩意儿行业,正式跨进“计算机”领地。为马克1号编制程序的是哈佛的一位女数学家格蕾丝·霍珀,有一天,她在调试程序时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍珀诙谐的把程序故障统称为“臭虫.............(BUG)”,把排除程序故障叫DEBUG,而这奇怪的“称呼”,后来成为计算机领域的专业行话。从而debug意为排除程序故障的意思。

Release:

称之为发布版本,它往往是根据各种进行了优化,使得程序的代码都是最佳优的,以便让用户更好的去使用。

本质区别:

Debug和Release编译方式的本质区别

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。 Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。还有大小的区别,因为Debug的版本是可以进行调试的(包含了相应的调试信息),而Release版本是不能进行调试的。

Debug 和 Release 的真正秘密,在于一组编译选项。

下面列出了分别针对二者的选项

(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Release 版错误,在此不讨论)

Debug 版本:

/MDd /MLd 或 /MTd 使用 Debug runtime library(调试版本的运行时刻函数库)

/Od 关闭优化开关

/D "_DEBUG " 相当于 #define _DEBUG,打开编译调试代码开关(主要针对 assert函数)

/ZI 创建 Edit and continue(编辑继续)数据库,这样在调试过 程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误

/Gm 打开最小化重链接开关,减少链接时间

Release 版本:

/MD /ML 或 /MT 使用发布版本的运行时刻函数库

/O1 或 /O2 优化开关,使程序最小或最快

/D "NDEBUG " 关闭条件编译调试代码开关(即不编译assert函数)

/GF 合并重复的字符串,并将字符串常量放到只读内存,防止 被修改

实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。

  • 采用Debug的话,如果用Debug代码来编译可执行程序的话,我们也会产生一个Debug的版本的一个可执行程序
  • 采用Release的话,就是发布版本,可执行的程序。——(简化)

Release版本优化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
    int i = 0;
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    for(i=0;i<=12;i++)
    {
        printf("hello C\n");
        arr[i] = 0;
    }
    system("pause");
}

大家可以分别试一下就会发现不同之处了,分别用Debug和Release运行以下程序。这里是当你for循环的结果为假的时候,它的i又会重置为0,然后一直这个样子重复循环打印for语句的循环内容。因为arr这里跟i它们两个人是同一块空间,那么当你改变arr[i]的时候int i也会改变。因为它们的地址是一样的,所以才会改变。

由于这个程序涉及范围到栈区一些相关的知识点的内容,在这里我跟大家简单的说下。

栈区:栈区的默认使用是先使用高地址处的空间,然后在使用低地址处的空间。数组的下标随着增长,地址是由低到高变化的。当然如果你在不同的编译器上运行它的死循环的位置可能不同。你们也可以在不同的编译器上运行一下对比一下


运行与调试常用的快捷键 

运行:Ctrl + F11 使用快捷键Ctrl + F11可以快速运行当前选中的资源文件。 调试:F11:是逐步 它是会进入函数的 把程序细化到步 shift + F11,跳出函数 F10 是逐行 在某条语句调用一个函数的时候 它不会进入(除非那里设有断点) F9:切换断点 使用快捷键F11可以快速调试当前选中的资源文件。 断点调试操作:F5、F6、F7、F8 F5和F9的快捷键可以进行配合使用。

在断点调试时,快捷键F6是执行下一步(单步跳过);F5是执行当前调用内部细节步骤的下一步(单步跳入);F7是跳过方法内部的执行步骤,直接返回到方法外的下一步(单步返回);F8是跳出断点调试(跳过调试,继续执行代码,在下一个断点处暂停再次进入断点调试)。


查看程序的信息

ctrl + F5:开始执行不调试,如果你想让程序而不调试就可以进行使用。

自动窗口:当我们程序在执行中的时候,打开自动窗口,自动的把某些程序的上下文变量自动给你观察,这就是自动窗口的功能。

局部变量:和自动窗口差不多其实,但是它有一个缺点是它不能想监视谁就监视谁。

监视:监视这个作用就比较好了,当你想监视的话就输入那个变量的值,它就会呈现在你的监视当中,这样你就可以随时随地的去进行观察那个变量了。(监视窗口可以说是博主用的最多的了)

内存:如果我们想进行观察当前程序执行的内存的话,这个时候就是你输入观察的内存信息了。

(内存窗口也是用的可以说是非常多的了)

调用堆栈:在这里简单的和各位小伙伴们说下,像栈一样的逻辑给大家给展示出来它的一个逻辑,顶上往前放数据再往顶上出数据,可以很好反馈程序当中的代码的调栈的调用逻辑。

初学者掌握调试的内容可以达到事半功倍的效果,多多使用调试可以提高程序执行代码的效率。

如何写出好的代码?

优秀的代码

  • 代码整洁且规范
  • 注释清晰,且通俗易懂(代指写代码的人)
  • 可读性,有效性,可维护性
  • bug尽量能够达到自己能够预期的范围之内,就是bug少,或者几乎没有bug
  • 文档齐全,不乱去堆放 

常见的coding技巧 

  • 养成良好的编码风格
  • 注释必要的还是要去添加,提高代码的可读性
  • 避免编码的陷阱
  • 尽量使用const
  • 使用assert,头文件#include<assert.h>,在assert();里面的表达式如果为真的话,assert表达式为真就什么都不会发生,如果assert的表达式为假,那么就会报错。

在这里简单的跟大家介绍一下const的关键字:const修饰的数据是常类型,常类型的变量或者对象的值是不可以被该变的,也就是被它修饰过的是常量,相比之下const常量和#define是有点类似的,但是在我们用数组的时候还是要区分一下,因为数组里面 [常量表达式],此时我如果 const int n = 10 假设赋值给arr数组,int arr[n] = {0};结果是不行的,虽然加了const关键字,但实际上也只是变量只不过是不能被修改的变量。那么如果我们这里用的是#define—定义符号常量就可以了。 

assert代码使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
#include<assert.h>
int My_strlen(const char* pb)
{
	int Count = 0;//计数
	assert(*pb != NULL);//保证指针的有效性 NULL —— 空指针
	while (*pb != '\0')
	{
		Count++;
		*pb++;
	}
	return Count;
}
int main(void)
{
	char arr[20] = "nihao C";
	int ret = My_strlen(arr);
	printf("arr(strlen) = %d\n", ret);
	return 0;
}

最后,我想跟大家说程序遇到bug不要害怕,勇敢的去面对它吧,加油奥里给!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
实战渗透 - 一个怎么够?我全都要!
内容是通过扫描备份文件得到文件源代码进行代码审计,所以自己打算写一个专门扫描此类信息的工具。
重生信息安全
2020/08/25
6730
实战渗透 - 一个怎么够?我全都要!
记一次开源OA组合拳RCE漏洞审计过程
某开源OA存在前台SQL注入和后台RCE漏洞,可以用SQL注入跑出来后台账号密码,登录后打后台RCE,组合拳达到前台RCE的效果。
亿人安全
2025/03/20
1470
记一次开源OA组合拳RCE漏洞审计过程
Asp.Net无刷新上传并裁剪头像
开发网站几乎都做过上传图片并截图,做个无刷新Asp.Net上传并截图示例 实现功能: 1.选择文件,自动上传并生成缩放图(上传带进度条),形成预览图 2.在预览区,实现鼠标拖拽截图区,截取图片(示例截图区按缩放图小边为截图正方形长度,可扩展为截图区可变形式) 3.点击保存,截取小图,保存截取图并显示在页面上,并删除原缩略图 示例截图: image.png image.png -----------------------------------------------------------------
Porschev
2018/01/16
3.6K0
Asp.Net无刷新上传并裁剪头像
实战|记一次从文件备份泄露到主机上线
对于测试的第一项当然是弱口令,bp跑了一通词典,无果。目录又爆破了一通,发现一个web.rar可通,赶紧下载看看,如下图所示。
亿人安全
2022/12/23
6480
实战|记一次从文件备份泄露到主机上线
记一次某开源OA白名单后缀限制下巧用系统设计getshell
如 d=systam&m=admin|admin&a=login 相当于调用 webmain/system/admin/adminAction.php#login
亿人安全
2025/02/26
1320
记一次某开源OA白名单后缀限制下巧用系统设计getshell
练习文件保存按照日期来创建文件夹,并保存
上传页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form action="UploadStoreByDate.ashx" method="post" enctype="multipart/for
静心物语313
2020/03/24
9210
jQuery Uploadify结合C#实现带进度条的上传
jQuery Uploadify结合C#实现带进度条的上传 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="UpLoad.aspx.cs" Inherits="UploadifyDemo_UpLoad" %> <html xmlns="http://www.w3.org/1999/xhtml"&gt; <head id="Head1" runat="server"> <title>Jquery Uploadify上传带进度条</tit
用户8671053
2021/11/03
1.2K0
bootstrap-fileinput文件上传&后台接收处理
使用bootstrap-fileinput进行文件上传,有丰富的属性、方法、事件,还有好多demo供参考。
全栈程序员站长
2022/06/26
2.6K0
bootstrap-fileinput文件上传&后台接收处理
常见.NET功能代码汇总 (2)
常见.NET功能代码汇总 23,获取和设置分级缓存 获取缓存:首先从本地缓存获取,如果没有,再去读取分布式缓存 写缓存:同时写本地缓存和分布式缓存 private static T GetGradeCache<T>(string key) where T:struct { MemoryCacheManager localCache = MemoryCacheManager.Instance; if (!localCache.IsSet(k
用户1177503
2018/02/27
7880
FckEditor 2.6.4升级手记
说是升级,其实就是把原来的版本替换掉 1.先到www.fckeditor.net上下载fckeditor(html/js包)和fckeditor.net(专用于aspx环境中处理上传的dll包) 2.将fckeditor中"_"开头的文件都删除掉(基本上都是源码和说明性文档,没啥用处) 3.修改fckconfig.js FCKConfig.DefaultLanguage  = 'zh-cn' ; //改为简体中文 ... var _FileBrowserLanguage = 'aspx' ; // 设置上
菩提树下的杨过
2018/01/23
1.2K0
前台任意文件上传漏洞-智慧校园系统
智慧校园管理系统前台注册页面存在文件上传,由于没有对上传的文件进行审查导致可上传恶意文件控制服务器
MssnHarvey
2022/08/10
1.1K0
前台任意文件上传漏洞-智慧校园系统
基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用
Bootstrap文件上传插件File Input是一个不错的文件上传控件,但是搜索使用到的案例不多,使用的时候,也是一步一个脚印一样摸着石头过河,这个控件在界面呈现上,叫我之前使用过的Uploadify 好看一些,功能也强大些,本文主要基于我自己的框架代码案例,介绍其中文件上传插件File Input的使用。关于Uploadify的控件介绍,可以参考我之前的随笔介绍《基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用》。 1、文件上传插件File Input介绍 这
MonroeCode
2018/02/09
2.5K0
基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用
C#/.NET RestSharp网络组件实现上传文件到远程服务器【可跨域传文件】
以前给大家分享了一个C#/.NET的网络组件–RestSharp,具体请参考:推荐一个.NET(C#)的HTTP辅助类组件–restsharp 今天再给大家示范一下如何应用RestSharp这个网络组件来实现可跨域的文件上传功能。 在文章的末尾我会把这个示例项目的源码下载发布出来。 本项目由一个客户端和一个ASP.NET WEB API 2来演示。客户端主要用于模拟用户的上传文件操作,而WEB API则是来接收用户上传的文件。在这里,我只贴出这两个部分的核心代码。 首先是WEB API(RestSharp
Rector
2018/02/01
4.3K0
一起来学SpringBoot | 第十七篇:轻松搞定文件上传
文件上传和下载是 JAVA WEB中常见的一种操作,文件上传主要是 将文件通过IO流传输到服务器的某一个特定的文件夹下;刚开始工作那会一个上传文件常常花费小半天的时间,繁琐的代码量以及 XML配置让我是痛不欲生;值得庆幸的是有了 SpringBoot短短的几句代码就能实现文件上传与本地写入操作....
battcn
2018/08/03
9030
一起来学SpringBoot | 第十七篇:轻松搞定文件上传
实战渗透某大型传销组织 - 有思路有干货
前言:在这疫情每况加峻的时世下,我和阿浪师傅无意发现一传销组织站点居然还在为非作歹!作案连连!现在连买口罩的钱都没有了,居然还出来诈骗!老百姓容易么!?反正我俩是忍不住了!准备磨刀霍霍向狼群,提刀就是干它!
用户1631416
2020/03/12
1.6K0
Ladon捕获0day payload批量getshell
使用2011版菜刀访问某个webshell,发现被WAF拦截,,使用2016版可连,想看一下两者的发包特征,搭个IIS、Apache、Nginx、Tomcat环境来看post数据,默认中间件不显示这些数据,有些人可能压根就不会搭,你本意只是想看个发包,还要浪费时间去搭环境?当然也可以使用WireShark等抓包工具,但是又不会用怎么办?没事使用Ladon一条命令就搞定,非常简单。以前教大家用过Ladon的web模块捕获windows密码、获取无回显RCE漏洞命令回显、架设WEB远程下载payload、测试漏洞等,实际上还有很多用途,比如捕获0day、捕获工具payload等
用户8478399
2022/09/22
1.6K0
Ladon捕获0day payload批量getshell
ASP.NET Core文件上传与下载(多种上传方式)
前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在整理吧. ASP.NET Core 2.0 发展到现在,已经很成熟了.下个项目争取使用吧. 正文 1.使用模型绑定上传文件(官方例子) 官方机器翻译的地址:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads 这里吐槽一下 - -,这TM的机器翻译..还不如自己看E文的.. 首先我们需要
GuZhenYin
2018/03/30
5.7K0
ASP.NET Core文件上传与下载(多种上传方式)
记一次某大学渗透过程
其实看到18001端口开放大概就猜出了是Weblogic系统,等待fofa识别后果然
亿人安全
2022/06/30
7220
记一次某大学渗透过程
解决ASP.NET Core Mvc文件上传限制问题
  在ASP.NET Core MVC中,文件上传的最大上传文件默认为20MB,如果我们想上传一些比较大的文件,就不知道怎么去设置了,没有了Web.Config我们应该如何下手呢?
yoyofx
2018/09/05
1.7K0
ASP.NET MVC5+EF6+EasyUI 后台管理系统(87)-MVC Excel导入和导出
前言: 导入导出实在多例子,很多成熟的组建都分装了导入和导出,这一节演示利用LinqToExcel组件对Excel的导入,这个是一个极其简单的例子。 我并不是说导入的简单。而是LinqToExcel让我们对Excel操作更加简单! 最后我们将利用ClosedXML输出Excel。这个比现流行NPOI与EPPlus更加优秀的组件,以Open XML SDK为基础,所以只支持xlsx,不支持xls格式(现阶段谁没有个office2007以上版本) 他导出的Excel根据官方描述,兼容性远超同行对手
用户1149182
2018/01/16
1.6K0
ASP.NET MVC5+EF6+EasyUI 后台管理系统(87)-MVC Excel导入和导出
推荐阅读
相关推荐
实战渗透 - 一个怎么够?我全都要!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验