【C语言初阶(20)】调试练习题

文章目录

  • 前言
  • 实例1
  • 实例2

前言

  • 在我们开始调试之前,应该有个明确的思路;
  • 程序是如何完成工作的、变量到达某个步骤时的值应该是什么、出现的问题大概会在什么位置。
  • 这些东西在调试之前都需要先确认下来,不然自己都不知道自己在调试个什么东西了。

实例1

题目内容

  • 求 1!+2!+3! …+ n! ;不考虑溢出。

使用调试分析出下面代码的问题是什么

  • 注意:不要用经验来判断问题出在哪,全当第一次遇见这些代码,光瞪眼肯定是没法解决问题的。
int main()
{
	int i = 0;
	int sum = 0;			//保存最终结果
	int n = 0;
	int ret = 1;			//保存 n 的阶乘
	scanf("%d", &n);		//输入 3,结果应该是:1! + 2! +3! = 9
	
	for(i=1; i<=n; i++)
	{
		int j = 0;
		
		for(j=1; j<=i; j++)
		{
			ret *= j;
		}
		sum += ret;		//将 1 到 i 之间的数字累乘到 ret 上去就是 i 的阶乘
	}
	
	printf("%d\n", sum);
	
	return 0;
}
  • 结果显然和我们想象中的有所出入。

在这里插入图片描述

调试分析

  • 调试过程中,我们需要观察 sum、ret、i、n 、j 这几个变量的值的变化。
    • 调试过程中需要我们先给 n 输入一个值,此时已经给了个 3 给 n。

在这里插入图片描述

  • 第一次循环,i 初始化为 1,j 初始化为 1,满足条件 j <= i,进入内层循环。将 j = 1 乘到 ret 上,此时 ret 变为 1。

在这里插入图片描述

  • 内循环完一遍之后 j++ 变成了 2。2 <= i 的条件就不成立了,将算出的 1 的阶乘 + 到 sum 上去。此时 sum 变成了 1.

在这里插入图片描述

  • 求完一遍阶乘之后,令 i++ 变成了 2,那么内循环就要算出 2 的阶乘,重新令 j 初始化为 1,满足循环条件,将 j = 1 乘到 ret 上去,ret 的结果也是 1。

在这里插入图片描述

  • 然后 j++ 变成 了 2,将 j = 2 乘 到 ret 上,此时 ret 就变成了 2。

在这里插入图片描述

  • j++ 变成了 3,不满足循环条件 j <= i,退出循环,然后将 ret = 2 累加到 sum 上去,此时 sum 变成了 3。目前为止还没有任务问题。

在这里插入图片描述

  • 累加完了之后让 i++ 变成了 3,满足 i <= n(3) 的条件,现在要求 3 的阶乘。让 j 初始化为 1 从 1 开始 一直乘到 3。将 1 乘给 ret 之后发现,ret 的值变成 2,开始有点不对劲了。

在这里插入图片描述

  • j++ 变成 2,将 j = 2 乘 给 ret 此时 ret 变成了 4,然后 j++ 变成了 3,将 3 继续乘到 ret 上,此时 ret 变成了 12,ret = 12 明显不是 3 的阶乘。所以问题应该就是出在这里了。
  • 因为 ret 是在循环体外面创建的,在循环过程中 ret 的值被改了就回不到 1 了,用会变的值来进行累乘,结果肯定不如人意了。

在这里插入图片描述
在这里插入图片描述

  • 最终将 ret = 12 加到 sum 上去 3 + 12 结果 15 就这么出来了。

在这里插入图片描述

代码修改

  • 将在循环体外部的 ret 放到循环体内部,每次循环完一轮之后都让 ret 的值重新变回 1,就不会影响最终结果了。

在这里插入图片描述

实例2

分析下面代码出现死循环的原因

  • 前提:该代码仅限在 VS + X86 环境 + Debug 模式下验证。
#include <stdio.h>

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("hello word!\n");
	}
	
	return 0;
}

在这里插入图片描述

调试分析

  • 很明显数组访问是直接越界了,但是前面 9 次的赋值是没有问题的。

在这里插入图片描述

  • 再观察 i 的值,在数组越界到 10、11 的时候,i 的值都还算正常。可唯独到了 arr[12] 的时候,i 的值居然被改成 0;
  • 也就是说,i 和 arr[12] 挂上了钩,arr[12] 只要被赋值成 0,i 也会被改成 0,i 无法自增到 13 自然就无法退出循环直接就导致死循环了。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 此时再观察 arr[12] 以及 i 的地址会发现,这两个家伙在你不知情的情况下已经住到同一个地址去了,难怪将 arr[12] 改为 0 会让 i 也跟着一块变。

在这里插入图片描述

代码分析

  • 现在要创建一个局部变量 i ,为 i 在栈上先分配一块空间;
  • 然后再创建数组 arr ,为 arr 分配一快空间;
  • 局部变量都是按照的方式(从搞地质向低地址使用)创建的,也就是说先被创建出来的 i 在内存中 在 arr 数组的下面。

在这里插入图片描述

  • 数组按照往下越界得情况来看的话,arr[12] 刚好就越界到了 i 所在的空间。
  • 前提中提到过的特殊情况下,先创建的 i 与 后创建的 arr 数组之间就是隔着两个整型的空间,所与才会越界越着越着就让摸到 i 了。

在这里插入图片描述

问题解决方案

  • 这段代码最大的问题就是数组的越界访问,没啥可说的,把这个改过来就行了。
#include <stdio.h>

int main()
{
	int i = 0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	
	for(i = 0; i < 10; i++)
	{
		arr[i] = 0;
		printf("hello word!\n");
	}
	
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg aresample_swr_opts的解析

ffmpeg option的解析 aresample_swr_opts是AVFilterGraph中的option。 static const AVOption filtergraph_options[] {{ "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,{ .i64 AVFILTER_THREAD_SLICE }, 0, INT_MA…

二十三种设计模式第二十篇--备忘录模式

备忘录模式&#xff0c;备忘录模式属于行为型模式。它允许在不破坏封装的情况下捕获和恢复对象的内部状态。保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象&#xff0c;该模式通过创建一个备忘录对象来保存原始对象的状态&#xff0c;并将其存储在一个负责管理备…

使用adb通过电脑给安卓设备安装apk文件

最近碰到要在开发板上安装软件的问题&#xff0c;由于是开发板上的安卓系统没有解析apk文件的工具&#xff0c;所以无法通过直接打开apk文件来安装软件。因此查询各种资料后发现可以使用adb工具&#xff0c;这样一来可以在电脑上给安卓设备安装软件。 ADB 就是连接 Android 手…

测试libcurl库的demo时,报错 curl_easy_perform() failed: SSL connect error

系统&#xff1a;麒麟V10 arm roothg-TR3250:/home/cur765/curl-7.65.3/docs/examples# cat /etc/os-release NAME"Kylin" VERSION"银河麒麟桌面操作系统(国防版)V10" VERSION_US"Kylin Linux Desktop (GFB)V10" IDkylin ID_LIKEdebian PRETT…

CloudDriver一款将各种网盘云盘挂在到电脑本地变成本地磁盘的工具 教程

平时我们的电脑可能由于大量的文件资料之类的导致存储空间可能不够&#xff0c;所以我们可以选择将网盘我们的本地磁盘用来存放东西。 CloudDrive 是一款可以将 115、阿里云盘、天翼云盘、沃家云盘、WebDAV 挂载到电脑中&#xff0c;成为本地硬盘的工具&#xff0c;支持 Window…

职工管理系统(code)

首先创建头文件、源文件&#xff0c;再编程。&#xff08;B站黑马程序员视频笔记&#xff09; 一、头文件.h 1、boss.h #pragma once #include<iostream> using namespace std; #include "worker.h"//老板类 class Boss :public Worker { public://构造函数B…

最优化方法

一. 图论 1.最小生成树 图的生成树是它的一颗含有其所有顶点的无环连通子图,一 幅加权图的最小生成树(MST)是它的一颗权值(树中的所有边的权值之和) 最小的生成树 • 适用场景&#xff1a;道路规划、通讯网络规划、管道铺设、电线布设等 题目数据 kruskal算法 稀疏图&#x…

【Git系列】了解什么是版本控制

&#x1f433;了解什么是版本控制 &#x1f9ca;1. 什么是版本控制&#x1f9ca;2. 为什么要有版本控制&#x1f9ca;3. 常见的版本控制工具&#x1f9ca;4. 版本控制分类&#x1fa9f;4.1 本地版本控制&#x1fa9f;4.2 集中版本控制&#x1fa9f;4.3 分布式版本控制 学习git之…

Elasticsearch和Kibana的安装及验证

金翅大鹏盖世英&#xff0c;展翅金鹏盖世雄。 穿云燕子锡今鸽&#xff0c;踏雪无痕花云平。 ---------------- 2023.7.31.101 ----------------- 本文密钥&#xff1a;365 Elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎&#xff0c;常用来进行全文检索、…

redis 第三章

目录 1.主从复制 2.哨兵 3.集群 4.总结 1.主从复制 结果&#xff1a; 2.哨兵 3.集群 4.总结 通过集群&#xff0c;redis 解决了写操作无法负载均衡&#xff0c;以及存储能力受到单机限制的问题&#xff0c;实现了较为完善的高可用方案。

安全学习DAY09_加密逆向,特征识别

算法逆向&加密算法分类&#xff0c;特征识别 文章目录 算法逆向&加密算法分类&#xff0c;特征识别算法概念&#xff0c;分类单向散列加密 - MD5对称加密 - AES非对称加密 - RSA 常见加密算法识别特征&#xff0c;解密特点MD5密文特点BASE64编码特点AES、DES特点RSA密文…

Stable Diffusion 硬核生存指南:WebUI 中的 VAE

本篇文章聊聊 Stable Diffusion 生态中呼声最高、也是最复杂的开源模型管理图形界面 “stable-diffusion-webui” 中和 VAE 相关的事情。 写在前面 Stable Diffusion 生态中有一个很重要的项目&#xff0c;它对于 SD 生态繁荣做出的贡献可以说居功至伟&#xff0c;自去年八月…

【C++】string

string 1. 简单了解string2. string的常用接口3. 简单模拟实现string4. 写时拷贝5. 练习 1. 简单了解string string是表示字符串的字符类&#xff0c;其底层是basic_string模板类的实例化&#xff0c;只能存储单字节的字符串&#xff0c;不能操作多字节和变长字符的序列。在使…

LLM微调 | Adapter: Parameter-Efficient Transfer Learning for NLP

目的&#xff1a;大模型预训练微调范式&#xff0c;微调成本高。adapter只只微调新增的小部分参数【但adapter增加了模型层数&#xff0c;引入了额外的推理延迟。】 Adapters最初来源于CV领域的《Learning multiple visual domains with residual adapters》一文&#xff0c;其…

Android 13(T) - Media框架(1)- 总览

从事Android Media开发工作三年有余&#xff0c;刚从萌新变成菜鸟&#xff0c;一路上跌跌撞撞学习&#xff0c;看了很多零零碎碎的知识&#xff0c;为了加深对Android Media框架的理解&#xff0c;决定在这里记录下学习过程中想到的一些问题以及一些思考&#xff0c;也希望对初…

更好搭建负载测试环境的六个技巧

如果你如我昨天谈到的客户一样&#xff0c;花费了24到48个小时用于每个负载测试环境的搭建&#xff0c;那你的测试及构建部署能力绝对是受限的。 搭建一个仿真测试环境对于做好负载测试非常重要&#xff0c;同时它也是一个非常具有挑战性的任务&#xff0c;需要考虑技术解决、…

【CSS】手写 Tooltip 提示组件

文章目录 效果示例代码实现 效果示例 代码实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>一颗不甘坠落的流星</title><style>body {padding: 120px;}.tooltip {position: relative;display: inline-blo…

【Linux取经路】进度条小程序

文章目录 一、预备知识1.1 回车换行1.2 缓冲区 二、倒计时2.1 注意事项 三、进度条3.1 源代码3.2 代码分析3.2 实际使用场景 一、预备知识 1.1 回车换行 一般意义上的回车换行是两个独立的独立的动作&#xff0c;而C语言中的\n则同时完成了回车和换行的工作。回车是将光标移动…

【EI/SCOPUS会议征稿】2023年第四届新能源与电气科技国际学术研讨会 (ISNEET 2023)

作为全球科技创新大趋势的引领者&#xff0c;中国一直在为科技创新创造越来越开放的环境&#xff0c;提高学术合作的深度和广度&#xff0c;构建惠及全民的创新共同体。这些努力为全球化和创建共享未来的共同体做出了新的贡献。 为交流近年来国内外在新能源和电气技术领域的最新…

谈谈网络端口的概念、分类,以及常见的端口号

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、网络端口的概念 二、网络端口的分类 1、公认端口 2、注册端口 3、动态和私有端口 三、网络端口的作用 四、常见的端口号 1、…