C语言调试

本文介绍了Debug和Release模式的区别,详细讲解了Windows环境下C语言调试的技巧,包括自动窗口、局部变量窗口、监视窗口、调用堆栈和查看寄存器。此外,还讨论了优秀代码实践,如使用const关键字和优化strcpy函数,并提供了strlen功能的实现以及编程常见错误的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一.Debug和Release介绍

二.Windows环境调试介绍

三.窗口介绍

(1)自动窗口和局部变量窗口

(2)监视窗口

(3)调用堆栈

(4)查看汇编信息

(5)查看寄存器 

四.优秀的代码

五.练习实现strlen功能


一.Debug和Release介绍

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

Release称为发布版本,往往进行了各种优化,使得代码大小和运行速度上都是最优的,一边用户的使用,没有调试信息,得到的.exe文件大小比较小

直接就会将10个数打印出来

二.Windows环境调试介绍

ctrl+F5:编译-链接+生成可执行程序

按下F5后会一直执行程直到程序运行结束,通常与F9配合使用,进行调试

设置断点,不能跳过scanf(),必须进行完互动才可以跳到断点

注:

调试过程中尽量不要返回到上一步,因为结果会不准确

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

三.窗口介绍

(1)自动窗口和局部变量窗口

自动窗口只会显示一个函数内部的变量,跳到下一个函数,上一个函数内部的变量就消失了

 局部变量窗口也会有局部变量上下跳动,观察不方便

(2)监视窗口

输入什么就查看什么

注:

对于数组的查看

当在主函数时,可以输入数组名对全部元素进行查看

当进行传址调用时,输入数组名就只能查看第一个元素,但可以在数组名后加逗号再加数字, 进行多个元素的查看

(3)调用堆栈

(4)查看汇编信息

(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("明日小路");
	}

	return 0;
}

编译器一直在执行循环,可能并不会进行越界访问的报错 

但如果将定义的i变量放在数组后面进行定义,就可以避免死循环

四.优秀的代码

release版本会将assert()优化掉

const 关键字可以对指针进行相关的修饰

下面对于strcpy代码进行自定义和优化

#include <string.h>
void my_strcpy(char* dest, char* sour)
{
	while (*sour != '\0')
	{
		*dest = *sour;
		dest++;
		sour++;
	}
	*dest = *sour;
}
int main()
{
	char arr1[20] = "XXXXXXXXXXXXXXXXX";
	char arr2[] = "Komichi Akebi";
	my_strcpy(arr1, arr2);
	printf("%s", arr1);
	return 0;
}

优化后

#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* sour)//加const 可以有效避免使用函数时将源字符和目标空间弄混
{
	char* ret = dest;

	assert(sour != NULL);
	assert(dest != NULL);
	while (*dest++ = *sour++);
	return ret;//返回值是目标空间的首元素地址,目的是实现链式访问
}
int main()
{
	char arr1[20] = "XXXXXXXXXXXXXXXXX";
	char arr2[] = "Komichi Akebi";
	printf("%s", my_strcpy(arr1, arr2));//函数具有返回值可以直接进行打印,可以实现链式访问
将一个函数的返回值作为另一个函数的参数
	return 0;
}

注:

对于常变量const

1.const的放在*左边

但是p变量本身的值是可以进行修改的 

2.const放在*右边

3.当在*的左边和右边都放上const ,则指针所指向的变量和指针本身都不能进行修改了

五.练习实现strlen功能

#include <assert.h>
int my_strlen(const char* str)//加const还是为确保str防止进行修改
{
	int count = 0;//记得对变量进行初始化
	assert(str);//进行断言,防止传入NULL
	while (*str++)
	{
		count++;
	}
	return count;
}
int main()
{
	char arr1[] = "Komichi Akebi";//定义数组的格式要写对,数组名后记得写[ ]
	int len = my_strlen(arr1);
	printf("%d", len);
	return 0;
}

问题:

1.不能对空指针NULL进行解引用操作

2.主函数里面数组在定义的时候,不需要加const,对于在传址的时候将指针用const进行修饰,只是将主函数中定义的一个不够安全的数组变得更加安全

编程常见的一些错误

C语言编译器在编译时会对代码进行修改,如将函数名前面加上下划线

链接错误不会找到对应的错误位置去

 后期有兴趣可以深入学习git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值