一、VS上的Debug和Release模式
•Debug
被称为调试版本,包含调试信息,并且不做任何优化,便于程序员调试程序
•Release
被称为发布版本,里面的程序往往已经被程序员进行了各种优化,使得程序在代码大小和运行速度上都是最优的—>用户使用
二、VS调试快捷键
1.环境准备
把VS上设置为Deubg
,Release
模式有很多是无法调试的
2.调试快捷键(常用)
VS快捷键可能会和电脑系统快捷键冲突,这时候使用快捷键时可能会没有反应,大部分可以使用Fn+快捷键
解决
•F9(也可以鼠标左键点击灰色地方):创建断点和取消断点
断点:可以使程序运行到有断点的位置停下来,配合F10
、F11
等这些快捷键使用
条件断点:满足条件才会触发断点
•F5
:启动调试,经常用来直接跳到下一个断点处,一般配合F9使用
•F10
:逐过程,通常⽤来处理⼀个过程,⼀个过程可以是⼀次函数调⽤,或者是⼀条语句
•F11
:逐语句,就是每次都执⾏⼀条语句,但是这个快捷键可以使我们的执⾏逻辑进⼊函数内部。在函数调⽤的地⽅,想进⼊函数观察细节,必须使⽤F11
,如果使⽤F10
,直接完成函数调⽤
•Ctrl + F5
:开始执⾏不调试,让程序直接运⾏起来⽽不调试
3.VS大部分调试快捷键
有逗号的情况:
表示分步操作,先按第一个组合键,松开后再按第二个组合键
3.1 基础编辑操作
功能 | 快捷键 |
---|---|
剪切 | Ctrl + X |
复制 | Ctrl + C |
粘贴 | Ctrl + V |
撤销 | Ctrl + Z |
重做 | Ctrl + Y |
删除行 | Ctrl + Shift + L 或 Ctrl + L |
注释/取消注释 | Ctrl + K, Ctrl + C / Ctrl + K, Ctrl + U |
3.2 代码导航与搜索
功能 | 快捷键 |
---|---|
跳转到定义 | F12 |
快速查找(快速查找文件、类、成员 ) | Ctrl + , |
查找所有引用 | Shift + F12 |
返回上一光标位置 | Ctrl + - |
进行到下一光标位置 | Ctrl + Shift + - |
跳转到指定行 | Ctrl + G |
3.3 调试与运行
功能 | 快捷键 |
---|---|
启动调试 | F5 |
无调试运行 | Ctrl + F5 |
停止调试 | Shift + F5 |
切换断点 | F9 |
删除所有断点 | Ctrl + Shift + F9 |
单步跳过 | F10 |
单步进入 | F11 |
单步跳出 | Shift + F11 |
运行到光标处 | Ctrl + F10 |
设置下一语句 | Ctrl + Shift + F10 |
3.4 代码格式化与重构
功能 | 快捷键 |
---|---|
格式化代码 | Ctrl + K, Ctrl + D |
格式化选中代码 | Ctrl + K, Ctrl + F |
重命名 | Ctrl + R, Ctrl + R |
快速操作提示(显示重构或修正建议) | Ctrl + . |
3.5 项目与生成
功能 | 快捷键 |
---|---|
生成解决方案 | Ctrl + Shift + B |
生成当前项目 | Ctrl + F7 |
添加新项目 | Ctrl + Shift + A |
添加新类 | Shift + Alt + C |
3.6 窗口与视图管理
功能 | 快捷键 |
---|---|
切换文档窗口 | Ctrl + Tab |
关闭文档窗口 | Ctrl + F4 |
关闭所有窗口 | Ctrl + Shift + W |
切换解决方案资源管理器 | Ctrl + W, S |
切换属性窗口 | Ctrl + W, P |
切换输出窗口 | Ctrl + Alt + O |
3.7 查找与命令
功能 | 快捷键 |
---|---|
在当前文档中查找 | Ctrl + F |
在当前文档中查找并替换 | Ctrl + H |
在整个解决方案中查找 | Ctrl + Shift + F |
在整个解决方案中替换 | Ctrl + Shift + H |
3.8 其他常用快捷键
功能 | 快捷键 |
---|---|
全选 | Ctrl + A |
全屏切换 | Shift + Alt + Enter |
显示智能感知 | Ctrl + 空格 |
切换书签 | Ctrl + K, Ctrl + K |
下一个书签 | Ctrl + K, Ctrl + N |
上一个书签 | Ctrl + K, Ctrl + P |
四、监视和内存观察
在调试过程中,如果想要观察代码执行过程中,上下文变量的值,可以使用监视以及观察内存
1.监视
开始调试后,在菜单栏中【调试】->【窗⼝】->【监视】,打开任意⼀个监视窗⼝,输⼊想要观察的对象
如何打开监视:
https://editor.youkuaiyun.com/md/?articleId=144123056
2.内存
调试】->【窗⼝】->【内存】
在打开内存窗⼝后,在地址栏输⼊想要观察的变量(要加&),即可观察到该变量的地址
五、举例
观察在VS2022、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("hehe\n");
}
return 0;
}
结果: 死循环
此时i
和arr[i]都
等于12,因为for
循环的条件是i<=12
,也就是说i
不会进行下一次循环(按理说i
会变成13
)
但是调试后发现i
从12
变成了0
,最后导致无限循环
但查询i
和arr[12]
的地址发现,&i
和&arr[12]
一模一样,所以当让arr[12]=0
时,i
也被改成了0
- 栈区内存的使⽤习惯是从⾼地址向低地址使⽤的,所以变量
i
的地址是较⼤的。arr
数组的地址整体是⼩于i
的地址。 - 数组在内存中的存放是:随着下标的增⻓,地址是由低到⾼变化的。 所以根据代码,就能理解为什么是左边的代码布局了。 如果是左边的内存布局,那随着数组下标的增⻓,往后越界就有可能覆盖到
i
,这样就可能造成死循环的。 - 为什么
i
和arr
数组之间恰好空出来2个整型的空间呢?这⾥是巧合,在不同的编器下可能中间的空出的空间⼤⼩是不⼀样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以的不同的编译器之间就有差异了。所以这个题⽬是和环境相关的。