【24】C语言 | 调试技巧

news2024/11/28 2:31:39

目录

1、调试概念:

2、Debug和Release的介绍

3、windows中的快捷键

4、案例一:求1!+ 2!+3!+...+n!

5、案例二:下面的代码输出什么?

6、案例三:实现一个strcopy的函数 

7、实现一个函数strlen,用到优化:const 和assert

8、常见的错误分类 :


1、调试概念:

  • 调试(英语: Debugging /Debug ),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程J

调试的基本步骤

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

2、Debug和Release的介绍

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

3、windows中的快捷键

F9

  • 创建断点和取消断点 断点的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。

F5

  • 启动调试,经常用来直接调到下一个断点处
  • #F9和F5一般是配合使用的,F9设置断点,断点前的代码不做调试,要调试断点后的代码,当F10以后,断点之前的代码执行完成,在按F5会在断点之后执行一次

F10

  • 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句

F11

  • 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最长用的)。

CTRL+ F5

  • 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。

内存上的

4、案例一:求1!+ 2!+3!+...+n!

int main()
{
    int n = 0;
    int i = 0;
    int ret = 1;
    int sum = 0;
    int j = 0;
    scanf("%d",&n);
    for(j = 1; j<=n; j++)
    {
         for(i = 1;i <=j; i++)
        {
            ret*=i;
        }
        sum += ret;
    }    
    printf("%d\n",sum);
    return 0;
}
//此代码输入3得出的结果是15,有误

开始调试:

1、F10一步一步的看结果,看出来当i==3的时候,ret初识值是2有误

2、设置一个断点,条件是i==3,再观察ret的值,发现没有初始化ret,下面代码改正

 

int main()
{
    int n = 0;
    int i = 0;
    int ret = 1;
    int sum = 0;
    int j = 0;
    scanf("%d",&n);
    for(j = 1; j<=n; j++)
    {
        ret = 1;
         for(i = 1;i <=j; i++)
        {
            ret*=i;
        }
        sum += ret;
    }    
    printf("%d\n",sum);
    return 0;
}

5、案例二:下面的代码输出什么?

//下面的代码输出什么?
int main()
{
    int i = 0;
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    for(i=0;i<=12;i++)
    {
        arr[i] = 0;
        printf("hehe\n");
    }
    return 0;
}

通过调试发现 i 和arr[12] 的地址是一样的,如图: 

 

  • 1、i 和 arr是局部变量,局部变量是放在栈区上的
  • 2、栈区内存的使用习惯是:先使用高地址空间,再使用低地址空间
  • 3、数组随着下标的增长地址是由低到高变化
  • 4、如果i和arr换一下定义的时候就不会碰到了

6、案例三:实现一个strcopy的函数 

void my_strcopy(char* dest,char* soc)
{
    while(*soc != '\0')
    {
        *dest = *soc;
        dest++;
        soc++;
    }
    *dest = *soc;
}
int main()
{
    char arr1[20] = "xxxxxxxxxxxxxxx";
    char arr2[] = "hello";
    my_strcopy(arr1,arr2);
    printf("%s\n",arr1);

    return 0;
}

 【1】也可以进行优化为:

void my_strcopy(char* dest,char* soc)
{
    while(*soc != '\0')
    {
        *dest++ = *soc++;
    }
    *dest = *soc;
}
int main()
{
    char arr1[20] = "xxxxxxxxxxxxxxx";
    char arr2[] = "hello";
    my_strcopy(arr1,arr2);
    printf("%s\n",arr1);

    return 0;
}

 【2】再优化为:

void my_strcopy(char* dest,char* soc)
{
    while(*dest++ = *soc++)  //即把“\0”拷贝过去了,又停止了
    {
        ;
    }
    *dest = *soc;
}
int main()
{
    char arr1[20] = "xxxxxxxxxxxxxxx";
    char arr2[] = "hello";
    my_strcopy(arr1,arr2);
    printf("%s\n",arr1);

    return 0;
}

【3】再优化为:

#include<assert.h>
void my_strcopy(char* dest,char* soc)
{
    assert(soc != NULL);   //防止arr2为NULL时候报错
    while(*dest++ = *soc++)
    {
        ;
    }

}
int main()
{
    char arr1[20] = "xxxxxxxxxxxxxxx";
    char arr2[] = "hello";
    my_strcopy(arr1,arr2);
    printf("%s\n",arr1);

    return 0;
}

#理解const(断言)下列://const如果再*的左边

{
    int num = 10;
    const int* p = &num;
    //p是指针变量
    //*p是指针指向的内容
    //const修饰子帧变量的时候
    //const如果再*的左边,修饰的是*p,表示指针指向的内容,*p是不可以被改变的的
    
    *p = 20; //这就话就会报错:“表达式必须是可修改的左值”
 p = &n; // 这就话没有问题

    return 0;
}

const如果放在*的右边

int main()
{
    int num = 10;
    int* const p = &num;
    int n = 20;
    //p是指针变量
    //*p是指针指向的内容
    //const修饰子帧变量的时候
    //const如果放在*的右边即:int* const,就表示指针p不可以改变,但是指针指向的内容是可以改变的    
    *p = 20; //这句话没有问题
    p = &n; //这就话就会报错:“表达式必须是可修改的左值”

    return 0;
}

【4】再进行优化:

#include<assert.h>
void my_strcopy(char* dest,const char* soc)  //加const把soc固定了,防止soc和dest写反
{
    assert(soc != NULL);  
    while(*dest++ = *soc++)
    {
        ;
    }

}
int main()
{
    char arr1[20] = "xxxxxxxxxxxxxxx";
    char arr2[] = "hello";
    my_strcopy(arr1,arr2);
    printf("%s\n",arr1);

    return 0;
}

 【5】再优化:

#include<assert.h>
//strcpy 这个库函数,其实返回的是目标空间的起始地址
char* my_strcopy(char* dest,const char* soc)  //加const把soc固定了,防止soc和dest写反
{
    char* ret = dest;
    assert(soc != NULL);  
    assert(dest !=NULL);
    
    while(*dest++ = *soc++)
    {
        ;
    }
    return ret;
}
int main()
{
    char arr1[20] = "xxxxxxxxxxxxxxx";
    char arr2[] = "hello";

    printf("%s\n",my_strcopy(arr1,arr2));

    return 0;
}

7、实现一个函数strlen,用到优化:const 和assert

#include<assert.h>
int my_strlen(const char* str)
{
    assert(str != NULL);
    int count = 0;
    while(*str != '\0')
    {
        str++;
        count++;
    }
    return count;
}

int main()
{
    char arr[] = "hello bite";
    printf("%d\n",my_strlen(arr));

    return 0;
}

8、常见的错误分类 :

编译型错误

直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。

链接型错误

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误。

运行时错误

借助调试,逐步定位问题。最难搞。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/180379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零入门容器云网络实战-3->Underlay网络与Overlay网络总结

本篇文章主要用于收集、整理、总结关于Underlay网络以及overlay网络相关知识点。 1、underlay网络介绍&#xff1f; 1.1、什么是underlay网络&#xff1f; Underlay网络就是&#xff1a; 传统IT基础设施网络&#xff0c;由交换机和路由器等设备组成&#xff0c;借助以太网协议…

3分钟搭建起聊天机器人需要的NoneBot2环境

创建nonebot2运行环境 官网上说这里的Python版本要高于3.8.0&#xff0c;还会有其他的依赖。 所以这里推荐大家使用虚拟环境&#xff0c;Poetry、venv、Conda&#xff0c;我这里用的是conda环境&#xff08;不同的项目依赖可能有所不同&#xff0c;所以才创建虚拟环境&#xf…

[羊城杯 2020]EasySer

目录 信息搜集 代码审计 参数扫描 信息搜集 先扫下目录 .htaccess&#xff1b;robots.txt&#xff1b;flag.php&#xff1b;index.php 在robots.txt下看到了/star1.php 进入star1.php发现出现ser.php <!-- 小胖说用个不安全的协议从我家才能进ser.php呢&#xff01; !--…

蓝桥杯刷题015——最少刷题数(二分法+前缀和)

问题描述 小蓝老师教的编程课有 N 名学生, 编号依次是 1…N 。第 i 号学生这学期刷题的数量是 Ai​ 。 对于每一名学生, 请你计算他至少还要再刷多少道题, 才能使得全班刷题比他多的学生数不超过刷题比他少的学生数。 输入格式 第一行包含一个正整数 N 。 第二行包含 N 个整数:…

学成在线项目开发技巧整理---第一部分

学成在线项目开发技巧整理---第一部分1.数据字典2.http-client远程测试插件,可以保存测试数据3.三种跨域解决4.具有多层级数据查询思路5.Mybaits分页插件原理6.根据文件后缀解析出mime-type7.大文件上传8.Spring事务什么时候会失效9.分布式文件系统MinIo10.构建独立文件系统11.…

3.3Sram和Dram

文章目录一、引子二、存储元件1.DRAM芯片&#xff08;1&#xff09;栅极电容1&#xff09;存储2&#xff09;读出&#xff08;2&#xff09;物理特性&#xff08;3&#xff09;DRAM刷新&#xff08;4&#xff09;DRAM地址线复用2.SRAM芯片&#xff08;1&#xff09;双稳态触发器…

爬虫之JS的解析

JS的解析 学习目标&#xff1a; 了解 定位js的方法了解 添加断点观察js的执行过程的方法应用 js2py获取js的方法 1 确定js的位置 对于前面人人网的案例&#xff0c;我们知道了url地址中有部分参数&#xff0c;但是参数是如何生成的呢&#xff1f; 毫无疑问&#xff0c;参数肯…

gin全解

文章目录介绍安装快速开始&#xff08;三种启动方式&#xff09;参数获取querystring参数其他不常用方法表单参数&#xff08;form参数&#xff09;其他不常用方法获取path参数参数绑定文件上传单个文件多个文件请求&#xff08;ctx.Request)响应gin.H{}字符串响应JSON/YAML/TO…

一起自学SLAM算法:8.2 Cartographer算法

连载文章&#xff0c;长期更新&#xff0c;欢迎关注&#xff1a; Gmapping代码实现相对简洁&#xff0c;非常适合初学者入门学习。但是Gmapping属于基于滤波方法的SLAM系统&#xff0c;明显的缺点是无法构建大规模的地图&#xff0c;这一点已经在第7章中讨论过了。而基于优化的…

Python爬虫之findall和lxml

Python爬虫之findall和lxml 提示&#xff1a;前言 Python爬虫之findall和lxml 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录Python爬虫之findall和lxml前言一、导入包二、设置URL和获取视频链接三、解析视频名字…

31. 实战:PyQuery获取小电视Top100详细信息(文末源码)

目录 前言 &#xff08;链接放在评论区&#xff09;&#xff08;链接放在评论区&#xff09;&#xff08;链接放在评论区&#xff09; 目的 &#xff08;链接放在评论区&#xff09;&#xff08;链接放在评论区&#xff09;&#xff08;链接放…

趣味三角——第4章——三角学迈向解析化

第4章 三角学迈向解析化(或分析化) 目录 4.1 三角学迈向解析化的过程简述 4.2 Franois Vieter对三角学解析化的贡献 “Thus the analysis of angular sections involves geometric and arithmetic secrets which hitherto have been penetrated by no one(因此&#xf…

Idea中指定xml文件失效

目录一、&#x1f407; 项目场景&#xff1a;二、&#x1f407; 问题描述三、&#x1f407; 原因分析&#xff1a;四、&#x1f407; 解决方案&#xff1a;一、&#x1f407; 项目场景&#xff1a; 最近狮子在搞一个项目&#xff0c;需要用到数据库多表查询&#xff0c;所以在…

数据挖掘,计算机网络、操作系统刷题笔记35

数据挖掘&#xff0c;计算机网络、操作系统刷题笔记35 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;orac…

【论文翻译】Jointformer :一种基于误差预测和改进的三维人体姿态估计的单帧提升变压器

摘要 单目三维人体姿态估计技术有望极大地提高人体运动数据的可用性。表现最好的单幅图像2D3D提升模型使用图卷积网络(GCNs)&#xff0c;通常需要一些手动输入来定义不同身体关节之间的关系。我们提出了一种新的基于变压器的方法&#xff0c;该方法使用更广泛的自我注意机制来…

nodejs+vue高校网上报名系统

本课题利用nodejsVue设计实现网上报名系统。系统的主要功能是&#xff1a;用户在线注册信息之后&#xff0c;利用注册时填写的用户账号与密码&#xff0c;登入系统后&#xff0c;对注册的个人信息进行修改&#xff0c;在线报名&#xff0c;能正确的提交有送报考的基本信息&…

【图卷积网络】01-卷积神经网络:从欧氏空间到非欧氏空间

人工神经网络发展浪潮 第三次浪潮——卷积神经网络 加拿大多伦多大学教授&#xff0c;机器学习领域泰斗Geoffery Hinton及其学生在《科学》上发表了一篇论文 &#xff08;Hinton, G. E . Reducing the Dimensionality of Data with Neural Networks[J]. Science, 2006, 313(578…

【Typescript学习】使用 React 和 TypeScript 构建web应用(二)部分UI、useState、useRef、Props

教程来自freecodeCamp&#xff1a;【英字】使用 React 和 TypeScript 构建应用程序 跟做&#xff0c;仅记录用 其他资料&#xff1a;https://www.freecodecamp.org/chinese/news/learn-typescript-beginners-guide/ 第二天 以下是视频(0:18-0:40) 的内容 目录第二天1 App 函数…

【二叉树】java实现代码,详解二叉树,带大家更深刻的掌握二叉树递归思想

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#x1fa90;&#x1fa90;&#x1fa90;&#xff0c;在探索数据结构的旅程中&#xff0c;二叉树可以说是数据结构中的重点&#xff0c;笔试面试经常出现的问题&#xff0c;同时也是难点。&#x1f425;&#x1f425;&#x1f4…

【Java开发】Spring Cloud 09 :微服务网关 Gateway

Spring Cloud Gateway&#xff08;简称 Gateway&#xff09;&#xff0c;它在微服务架构中扮演的角色是“微服务网关”&#xff0c;Nginx 和 Gateway 在微服务体系中的分工是不一样的。Gateway 作为更底层的微服务网关&#xff0c;通常是作为外部 Nginx 网关和内部微服务系统之…