VS环境实用调试技巧(c语言)与优化代码

发布于:2022-10-19 ⋅ 阅读:(404) ⋅ 点赞:(0)

debug和release的区别

 debug包含调试信息  文件通常都比release版本大

 

 

 

 调试代码快捷键

实例1:数组越界访问

 实例1代码在bebug版本下可能会死循环(不同编译器结果不同)

 

局部变量是在栈区上分配内存的

实例1中 i 和 arr 都是局部变量

1.栈区的默认使用:

先使用高地址处的空间 再使用低地址的空间

2.数组随着下标的增长 地址是由低到高的

根据这两条信息可以推断出 i 和 arr 在栈区上的相对位置

死循环解释:

1.i和数组arr都是局部变量  局部变量都是在栈区上使用的

且栈区是先使用高地址再使用低地址的空间  所以i会创建在比arr高的地址上

循环开始的时候  随着数组下标的增长 地址由低到高

在数组越界访问的时候 就有可能访问到i的地址 改变i的值 从而进入死循环

但在release版本下  此代码不会报错

原因:在debug模式下,变量的分配空间顺序与变量的声明顺序一致。先声明就先分配空间。

 在release版本下,对数组进行了优化,会先分配数组的空间 也就是arr在高地址 i在低地址

也就不会发生数组越界访问到i的情况

解决方法:可以先声明数组然后再声明变量i

实例2:调用堆栈的使用

 如图代码 main 函数 调用 test1函数  test1函数 调用test2函数

函数的调用也是在栈上开辟空间的

 调用堆栈:像栈一样的形式来展示函数调用的逻辑

从顶上放元素 也先从顶上出元素

 调用完函数后 从顶上开始结束函数 最后来到main函数这里

 

 

调用堆栈很好的反映了函数是如何一步一步的调用的

实例3:计算阶乘1!+2!+3!+...+n!

此代码有错  当输入n = 3时 结果本应该时 1!+2!+3! =9 但程序结果却是15

 通过F10一步一步调试  原因如下:

 发现当计算2!的时候 ret 的变成了2  也就是说ret的累乘效果没有取消, ret == 2的结果一直在往后的循环中累计使用,导致ret一直在变大 结果也跟着变大。

想要计算的是1!+2!+...+n!

但是此代码算成了1!+1!*2!+1!*2!*3!+...+1!*2!*...*n!

计算阶乘的原理: 输出1-n的数字 然后乘到一个变量(ret)上去 也就是说 影响结果因素只有输入的n的大小,变量ret只是用来接收乘积结果的。

错误的原因就在这里:ret变量的值没有重复初始化为1

通过一步步调试 很快就找到了错误的原因

 此代码还有可以进行优化 :利用 ret 的累乘效果 原理:n!=(n-1)!*n

 在每一次for循环结束前 及时把ret加到sum上去

实例4:模拟字符串拷贝函数strcpy()

 strcpy函数功能 拷贝source(源头)字符串到 Destination(目的地)  拷贝的字符包括'\0'

模拟strcpy函数 my_strcpy

原理:把要拷贝的数组传参之后 解引用对被覆盖的数组进行赋值  判断条件为*str != '\0'

最后再把'\0'字符拷贝

 由于把'\0'字符也一并拷贝过去了 printf打印的时候 遇到\0停止打印 打印结果相同

 此代码有四个地方可以优化

 1.

 while循环条件可以改成复合赋值符的形式

2.

 给非被覆盖数组const修饰

原因:用const修饰 防止数组传参的时候不小心写反了 这时候 src就是被覆盖数组 程序就会报错 因为const修饰的常变量 无法被修改

3.

assert断言

防止dest和src传过来的时候是空指针 影响拷贝

4.

返回值

拷贝完成后,将dest的首元素地址返回

完整代码如下:

 最后用相同的思路模拟求字符串长度的函数strlen()

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到