目录
一.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