visual studio 2022调试技巧介绍(2)

简介: 1.什么是bug?bug是计算机领域专业术语,bug原意是“臭虫”,现在用来指代计算机上存在的漏洞,原因是系统安全策略上存在的缺陷,有攻击者能够在未授权的情况下访问的危害。漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。2.调试是什么,如何调试?2.1 调试的概念调试简单来说就是调试是保证所提供的设备能够正常运行的必须程序。通过一些工具对代码进行检测,修复bug。

5.2 实例二

问这段代码在debug版本下x86平台下,为什么是死循环?

#include <stdio.h>
int main()
{
  int i = 0;
  int arr[10] = { 0 };
  for (i = 0; i <= 12; i++)
  {
    arr[i] = 0;
    printf("hehe\n");
  }
  return 0;
}

下面我们来通过调试来解释这个为什么?


ad9afffa06b2d3866bcf1a6470c54e76.png

真有这么巧吗?

其实并不是在VC6.0中arr[9]和i变量中间其实没有多余空间,在gcc编译器下arr[9]和i变量中间有一个整型的空间,visual studio 2022\2019\2013中的x86平台下arr[9]和i变量之间是由两个整型的空间。这些都不是巧合,而是编辑器本身规定的,不同的编译器有不同的规定。


6.如何写好优秀代码

6.1 优秀的代码

1.代码运行正常

2.bug很少

3.效率高

4.可维护性高

5.可读性高

6.注释清晰

7.文档齐全

6.2 用例题示范

模拟实现库函数:strcpy

6.2 用例题示范

模拟实现库函数:strcpy

6.2.1 方法一:按照思路实现

void my_strcpy(char* dest, char* src)
{
  while (*src != '\0')
  {
    *dest++ = *src++;
  }
  *dest = *src;
}
int main()
{
  char arr1[20] = "xxxxxxxxxx";
  //xxxxxxxxxx
  char arr2[] = "hello";
  my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

6.2.2 进一步优化

void my_strcpy(char* dest, char* src)
{
  //停止条件就是'\0','\0'对应的ASCII码值是0
  while (*dest++ = *src++)
  {
    ;
  }
}
int main()
{
  char arr1[20] = "xxxxxxxxxx";
  //xxxxxxxxxx
  char arr2[] = "hello";
  my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

6.2.3 用断言assert库函数进一步优化

对assert函数介绍:


image.png

简单来说,assert库函数就是为了保证指针的有效性。

void my_strcpy(char* dest, char* src)
{
  assert(dest != NULL);//断言
  assert(src != NULL);//断言
  //NULL是#define NULL ((void *)0)
  while (*dest++ = *src++)
  {
    ;
  }
}
int main()
{
  char arr1[20] = "xxxxxxxxxx";
  char arr2[] = "hello";
  my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

6.2.4 再一步优化

void my_strcpy(char* dest, char* src)
{
    assert(dest&&src);
    //NULL是#define NULL ((void *)0)
  while (*dest++ = *src++)
  {
    ;
  }
}
int main()
{
  char arr1[20] = "xxxxxxxxxx";
  char arr2[] = "hello";
  my_strcpy(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

6.2.5 最后一步完善优化

//strcpy有返回类型,源头数组不可变这些要求
char* my_strcpy(char* dest, const char* src)
{
  char* ret = dest;
  assert(dest && src);//断言
  while (*dest++ = *src++)
  {
    ;
  }
  return ret;
}
int main()
{
  char arr1[20] = "xxxxxxxxxx";
  char arr2[] = "hello";
  printf("%s\n", my_strcpy(arr1, arr2));
  return 0;
}

这就是调试后慢慢对细节的慢慢优化的过程。过程比结果重要,所以重在把握过程细节。

完善优化中const关键字再次理解

首先我们要知道const的作用:

告知程序员这里不能修改,具有“自描述”意思

告知编辑器这里不能修改,如果修复就会报错

1.const关键字修饰变量情景



2302f9fb964f328affe8b153eea413d2.png

这里的const修饰的是变量,所以这个变量是不能被修改的。但是可以用指针间接修改,如:


09daebe01bfd728c083a58bc3a68e775.png

为什么呢?

可以这样理解,因为const只是修饰了变量a,所以不能直接用a来修改,但是可以找到a的地址进行修改,不是直接修改a,而是间接修改,下面看const关键字修是指针的时候思路会更加清晰。

2.const关键字修饰数组操作数请景



7084d448df25016521e6ad183a3514d4.png

这里的const修饰变量有常属性,但是这个常属性的意思是不能被修改的意思,而非真正的把变量变成常量,这是不可能的。

3.const关键字修饰指针情景

再来聊聊指针,int * p,这里的p是指针变量用来存放地址,*是指针的标志,int是指针的类型(决定了指针访问时访问多少字节以及指针的步长问题)


3.1 const int *p

da3a432367eab9afeed01d015ec6d3bd.png


3.2 int const *p

这里int const *p和上述const int p是一样的,const都是修饰的p。

3.3 int* const p

17c21c4f05f5c48ec4edd594372e32e2.png

3.4 const int* const p


d63df23a58d47f47e5ae815e35b6639f.png

4.const关键字修饰函数返回值情景
const int* test()
{
  static int a = 10;
  return &a;
}
int main()
{
  int* p = test();
  return 0;
}

这里的const修饰函数返回值的意义就是提示程序员后期维护中,不要对其返回值进行更改。

6.3 实现模拟strlen库函数

int my_strlen(const char* str)
{
    //计数器
  int count = 0;
  //保证指针有效性
  assert(str != NULL);
  //判断条件再*str='\0'时停止
  while (*str)
  {
    count++;
    str++;
  }
  return count;
}
int main()
{
  const char* p = "abcdef";
  int len = my_strlen(p);
  printf("len = %d\n", len);
  return 0;
}

7.常见编程错误

编译型错误:直接看错提示信息

链接型错误:一般是标识符名不存在或者拼写错误

运行时错误;不容易发现的bug,一般调试才能解决

我们要做一个善于发现问题,解决问题的人,让脑袋高速飞转解决问题,这样才能成为一个厉害的人,还是要保持空杯心态,重复输入,高效输出。加油








相关文章
|
算法 安全 程序员
Visual Studio实用调试技巧---让你成为高端的程序员
Visual Studio实用调试技巧---让你成为高端的程序员
242 0
Visual Studio实用调试技巧---让你成为高端的程序员
|
存储 安全 NoSQL
Visual Studio 2022 你必须知道的实用调试技巧
大家好,前面我们讲了Visual Studio 2022的安装和使用以及scanf报错的解决方法 今天分享一些实用的 VS 技巧,而这些技巧很多人都不知道。当你以后在工作中遇到:我在同事电脑上解决问题,或在会议上演示代码示例时,使用了一些 VS “骚”操作,他们会好奇地问:你是怎么做到的?有时候你知道一些别人不知道的小技巧便可以让你显得更专业。 PS:本文所有示例演示均基于 Visual Studio 2022 版本。
273 0
|
NoSQL 编译器 程序员
Visual Studio2022编译器实用调试技巧
Visual Studio2022编译器实用调试技巧
|
C语言 C++
【五一创作】Visual Studio常用调试技巧的温习
【五一创作】Visual Studio常用调试技巧的温习
98 0
|
安全 程序员 编译器
visual studio 2022调试技巧介绍(1)
1.什么是bug? bug是计算机领域专业术语,bug原意是“臭虫”,现在用来指代计算机上存在的漏洞,原因是系统安全策略上存在的缺陷,有攻击者能够在未授权的情况下访问的危害。 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。 2.调试是什么,如何调试? 2.1 调试的概念 调试简单来说就是调试是保证所提供的设备能够正常运行的必须程序。 通过一些工具对代码进行检测,修复bug。
349 0
|
编译器 程序员 C语言
你是真的“C”——Visual Studio 2022(VS2022)编译器 -—实用调试技巧(下)
4.多多动手,尝试调试,才能有进步。🙌 5. 一道经典面试题目,这里用调试进行演示分析:🙌 6. 如何写出好(易于调试)的代码。🙌 6.1 优秀的代码: 6.2 典型栗子示范: 6.3 const的作用 7. 编程常见的错误🙌 7.1 编译型错误 7.2 链接型错误 7.3 运行时错误 总结撒花💞
288 0
|
算法 程序员 编译器
你是真的“C”——Visual Studio 2022(VS2022)编译器 -—实用调试技巧(上)
前言🙌 1. 什么是bug?🙌 2. 调试是什么?有多重要?🙌 2.1 调试是什么? 2.2 调试的基本步骤 2.3 Debug和Release的介绍。 3. Windows环境调试介绍🙌 3.1 调试环境的准备 3.2 学会快捷键 3.3 调试的时候查看程序当前信息 3.3.1 查看临时变量的值 3.3.2 查看内存信息 3.3.3 查看调用堆栈 3.3.4 查看汇编信息 3.3.5 查看寄存器信息
497 0
|
IDE 安全 JavaScript
Visual Studio调试技巧 -- Attach to Process
一般写完代码时,我们通常会启动调试运行一下看看是否正确,启动运行的方式无非是F5-- Start Debugging 或 Ctrl+F5-- Start Withour Debugging(注:不同版本或系统环境不同时,快捷键或有所变化),如下图1。不用说大家都能感觉到,使用Ctrl+F5调试时程序从启动到运行通常比使用F5快得多。使用Ctrl+F5时通常是想快速运行一遍,以便检查程序运行的结果是否符合预期。使用F5时通常是想查看代码内部的运行情况,以便检查到底是哪一步出了问题,或者所有参数是否都正确。
Visual Studio调试技巧 -- Attach to Process
|
C++
Visual Studio 原生开发的10个调试技巧(二)
原文:Visual Studio 原生开发的10个调试技巧(二)   我以前关于 Visual Studio 调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识。以下的列表中你可以看到写原生开发的调试技巧(接着以前的文章来编号)。
1178 0