自学C语言——VS实用调试技巧总结

接上一篇:自学C语言——扫雷游戏(无递归)

什么是bug

        “bug”本意是昆虫或虫子,一般指电脑系统或程序中,隐藏着一些未被发现的缺陷或者问题,简称程序漏洞。

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

        格蕾丝·霍波(Grace Murray Hopper,是一位为美国海军工作的电脑专家,也是最早将人类语言融入到电脑程序的人之一。)她公布过早期电子计算机的一个故障原因,通常错误地归功于她。这个版本的故事源自下面这段话:“在1946年,当霍波退役后后,她加入哈佛大学的计算机实验室,继续研究马克II型和马克III型计算机的工作。操作员在追踪马克II型的错误时发现继电器中有一只飞蛾,遂有bug术语。这个bug被仔细移除,并被贴在日志本上。这带来的第一个bug,就是我们今日所说的错误(error)或程序中的故障(glitch)。”

什么是调试(debug)

        当我们发现程序中存在的问题时,下一步就是找到问题并修复问题。

        这个找问题的过程称为调试,英文叫debug(消灭bug)的意思。

        调试一个程序,首先是承认出现了问题,然后通过各种手段去定位问题的位置,可能是逐过程的调试,也可能是隔离和屏蔽代码的方式,找到问题所在的位置,然后确定错误产生的原因,再修复代码,重新测试。

debug和release

再VS上编辑代码时,能看到有debug和release两个选项:

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

        程序员在写代码的时候,需要经常性的调试代码,就设置为debug,这样编译产生的是debug版本的可执行程序,其中包含调试信息,是可以直接调试的。

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

        当程序员写完代码,测试再对程序进行测试,直到程序的质量符合交付给用户使用的标准,这个时候就会设置为release,编译产生的就是release版本的可执行程序,这个版本是用户使用的,无需包含调试信息等。

同样的一段代码,release版本比debug版本的可执行文件大小要小得多。

VS调试快捷键

环境准备

需要一个支持调试的开发环境,把VS设置为debug

快捷键

F5:启动调试,经常用来直接跳到下一个断点处,一般是和F9配合使用。

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

F9:创建断点和取消断点

        断点:作用是可以在程序的任意位置设置断点,打上断点就可以使得程序执行到想要的位置暂停执行,接下来就可以使用F10,F11这些快捷键,观察代码的执行细节。

        条件断点:满足一定条件才能触发断点。

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

F11:逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部。 在函数调用的地方,想进入函数内部观察细节,必须使用F11,如果使用F10,直接完成函数调用

......

监视和内存观察

监视可以打开多个窗口,方便进行观察

内存是由二进制保存,十六进制的形式展示的

最左边是地址0x000......

最右边是解析(基本没用)

调试举例

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0;
	int arr[10] = { 0 };
	//给数组元素的赋值
	for (i = 0; i < 10; i++)
	{
		arr[i] = 10 - i;
	}
	//打印数组元素
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int c = Add(3, 5);
	printf("%d\n", c);
	return 0;
}
#include <stdio.h>

int main()
{
    int arr[10] = { 0 };
    int num = 100;
    char c = 'w';

    int i = 0;
    for (i = 0; i < 10; i++)
    {
        arr[i] = i;
    }
    return 0;
}
求1!+2!+3!+4!+...10!的和


求n的阶乘
5! = 1*2*3*4*5
4! = 1*2*3*4
n! = 1*2*..*n

int main()
{
	int n = 0;
//	scanf("%d", &n);

	int i = 0;
	int ret = 1;
	int sum = 0;

	for (n = 1; n <= 10; n++)
	{
		ret = 1;
		for (i = 1; i <= n; i++)
		{
			ret *= i;
		}
		sum += ret;
	}
	
	printf("%d\n", sum);

	return 0;
}
int main()
{
	int n = 0;
//	scanf("%d", &n);

	int i = 0;
	int ret = 1;
	int sum = 0;

	for (n = 1; n <= 10; n++)
	{
		ret *= n;
		sum += ret;
	}
	
	printf("%d\n", sum);

	return 0;
}
//VS2022 X86 debug 模式下

#include <stdio.h>

int main()
{
    int i = 0;
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

    printf("&i = %p\n", &i);
    printf("&arr[9] = %p\n", &arr[9]);


    /* for (i = 0; i <= 12; i++)
     {
         arr[i] = 0;
         printf("hehe\n");
     }*/

    return 0;
}

栈区:

默认情况下,先使用高地址处的空间,再使用低地址处的空间。数组随着下标的增长,地址是由低到高变化的,代码在运行的过程中,会依赖编译环境,这个是取决于编译器的。

#define  _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

void test(int arr[])
{

}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	test(arr);
	return 0;
}
int main()
{
	printf("hehe\n");
	return 0;
}

int add(int x, int y)
{
	return x + y;
}

int main()
{
	int a = 10;
	int b = 20;
	int c = Add(a, b);

	return 0;
}
#include <stdio.h>

int main()
{
	printf("hehe\n");
	main();
	return 0;
}
#include <stdio.h>

int Fact(int n)
{
	if (n == 0)
		return 1;
	else
		return n * Fact(n - 1);
}

int main()
{
	int n = 0;
	scanf("%d", &n);//5
	int r = Fact(n);
	printf("%d\n", r);

	return 0;
}

 

编程常见的错误归类

  1. 语法错误
  2. 链接错误
  3. 运行时错误
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

混迹网络的权某

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值