当前位置: 首页 > news >正文

中国建设人才服务信息网是正规网站网络营销总结

中国建设人才服务信息网是正规网站,网络营销总结,php网站的部署,装修公司的选择方法目录: 1.什么是bug? 2.调试是什么?有多重要? 3.debug和release的介绍 4.Windows环境调试介绍 5.一些调试的实例 6.如何写出好(易于调试)的代码 7.编程常见的错误 1.什么是bug? bug--->臭虫、虫子。 为什么含…

目录:

1.什么是bug?

2.调试是什么?有多重要?

3.debug和release的介绍

4.Windows环境调试介绍

5.一些调试的实例

6.如何写出好(易于调试)的代码

7.编程常见的错误


1.什么是bug?

bug--->臭虫、虫子。

为什么含义是臭虫、虫子呢?

答案是:第一次被发现的导致计算机错误的是一只飞蛾,也是第一个计算机程序的错误。

2.调试是什么?有多重要?

前言:

        所有发生的事情都一定有迹可循,如果问心无愧,就不需要掩盖也就没有迹象了,如果问心有愧,就必然需要掩盖,那就一定会有迹象,迹象越多就越容易顺藤而上,这就是推理的途径。

        顺着这条途径顺流而下就是犯罪,逆流而上就是真相。

        一名优秀的程序员都是一名出色的侦探。

        每一次调试都是尝试破案的过程。

2.1调试是什么?

调试(英语:Debugging/Debug),又称除错,是发现和减少计算机或电子仪器设备中程序错误的一个过程。

2.2调试的基本步骤

①发现程序错误的存在

②以隔离、消除等方式对错误进行定位

③确定错误产生的原因

④提出纠正错误的解决办法

⑤对程序错误予以改正,重新测试

2.3Debeg和Release的介绍

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

Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 

(1)在VS2019中如何转换?

(2)Release对代码大小上是最优的:

代码:

#include<stdio.h>//自定义函数——实现对整数数组的冒泡排序
void bubble_sort(int* str, int sz)
{//趟数int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序的过程int j = 0;for (j = 0; j < sz - 1 - i; j++){//升序if (str[j] > str[j + 1]){int tmp = str[j];str[j] = str[j + 1];str[j + 1] = tmp;}}}
}int main()
{int arr[] = { 10,9,8,7,5,6,4,1,2,3 };//定义整形数组,并初始化int sz = sizeof(arr) / sizeof(arr[0]);//计算数组的大小//调用函数,实现升序bubble_sort(arr, sz);//输出升序后的数组int i = 0;//循环变量for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");return 0;
}

观察分别在Debeg和Release环境下生成的可执行程序的大小:

(3)Release对代码运行速度上是最优的

代码:

#include <stdio.h>
int main()
{int i = 0;//数组下标界限0~9int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };for (i = 0; i <= 12; i++){//数组下标为10~12时数组越界arr[i] = 0;printf("hehe\n");}return 0;
}

在Debeg和环境下该代码死循环,解释在调试的实例二。

在Release环境下该代码打印13次hehe,不死循环,因为编译器优化把i的地址放在数组arr地址的下面了。

3.Windows环境调试介绍

 3.1调试环境的准备

在环境中选择debug选项,才能使代码正常调试。

3.2学会快捷键

最常使用的几个快捷键:

F5

启动调试,经常用来直接跳到下一个断点处。 

 F9

创建断点和取消断点。

断点的重要作用,可以在程序的任意位置设置断点。这样就可以使得程序在想要的位置停止执行,继而一步步执行下来。

F5和F9常配合使用,F5一般不会单独使用的。断点再多文件、多代码中常用。

F10

逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。

F11

逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最常用的)。

ctrl + F5

开始执行不调试。如果你想让程序直接运行起来而不调试就可以直接使用。

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

注意:只有先F10开始调试,才能看到程序当前信息。

3.3.1查看临时变量的值

在调试开始之后,用于观察变量的值。

3.3.2查看内存信息

在F10调试开始之后,用于观察内存信息。

3.3.3查看汇编信息

在F10调试开始之后,有两种方式转到汇编。

(1)第一种方式:右击鼠标,选择[转到汇编]:

(2)第二种方式:

可以切换到汇编。

3.3.4查看寄存器信息

在F10调试起来之后,有两种方式观察寄存器信息。

(1)第一种方式:

 (2)知道寄存器的名字,可以在监视中观察寄存器信息

可以查看当前运行环境的寄存器的使用信息。

3.3.5查看调用堆栈

在F10调试之后,可以观察调用堆栈。

通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用所处的位置。 

 4.多多动手,尝试调试,才能有进步

①一定要熟练掌握调试技巧;

②初学者可能80%的时间在写代码,20%的时间在调试。但是一个程序员可能20%的时间在写代码,但是80%的时间在调试。

③我们现在所讲的都是一些简单的调试,以后可能会出现很复杂的调试场景:多线程程序的调试等。

④多多使用快捷键,提升效率。

5.一些调试的实例

实例一:

实现代码:求 1!+2!+3! ...+ n! ;不考虑溢出。

代码1:实现阶乘

#include<stdio.h>int main()
{//输入求几的阶乘int n = 0;scanf("%d", &n);//实现求n!  n!=n*(n-1)int ret = 0;int i = 0;for (i = 1; i <= n; i++){ret *= i;}//输出结果printf("%d\n", ret);return 0;
}

 如果我们输入3,想输出6,但实际输出的是0.

why?

这里我们就得找我们的问题:

①首先通过经验推测问题出现的原因,初步确定问题可能的原因最好。

②实际上手调试很有必要。

③调试的时候我们要心里有数。

通过初步推测ret变量有问题,我们在在for循环打断点调试观察变量ret具体有什么问题。

代码2: 求 1!+2!+3! ...+ n!

#include<stdio.h>int main()
{//输入有n个阶乘int n = 0;scanf("%d", &n);//循环 求 1!+2!+3! ...+ n! int ret = 1;int i = 0;int sum = 0;//存放阶乘的累加和for (i = 1; i <= n; i++){int j = 0;//实现求i的阶乘for (j = 1; j <= i; j++){ret *= j;}sum += ret;}//输出结果printf("%d\n", sum);return 0;
}

如果我们输入3,想输出9,但实际输出15。

why?

分析:推测循环出错了,第一次调试在第二个循环处打断点,一步步调试监视变量的变化

但是没有发现是哪里错了,第二次调试在断点处右击设置断点条件快速调试到错误处,符合断点条件就停止,再F10观察具体原因。

 实例二:

#include <stdio.h>
int main()
{int i = 0;//数组下标界限0~9int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };for (i = 0; i <= 12; i++){//数组下标为10~12时数组越界arr[i] = 0;printf("hehe\n");}return 0;
}

数组越界应该是程序错误,不执行但是我们运行后发现程序死循环了。

why?

我们F10调试起来观察变量。

在调试的时候,我们发现每一次i的值都和arr[12]的值一样,当arr[12]=0时,i也变成0了,所以死循环。

那arr[12]和i是不是地址一样?我们调试观察之后确实是一样的。 

图解:

在i和arr数组中间恰好就是2个整形吗?

答:不一定,该代码只是在VS2019 X86环境下实验的结果。

        如果是VC6.0——i和arr之间没有多余的空间,gcc——i和arr之间有一个整形空间。 

        所以说平时我们写代码要注意不数组越界了

6.如何写出好(易于调试)的代码

6.1优秀的代码:

①代码运行正常

②bug很少

③效率高

④可读性高(如良好的代码风格,函数名、变量名见名知意等)

⑤可维护性高

⑥注释清晰

⑦文档齐全

常见的coding技巧:

①使用assert

②尽量使用const

③养成良好的编码风格

④添加必要的注释

⑤避免编码的陷阱

6.2示范

模拟实现库函数strcpy:

strcpy:

1.函数原型

2.函数功能:

3.函数参数: 

 4.函数的返回类型:

代码1:模拟实现strcpy

分析:

#include<stdio.h>
#include<string.h>//自定义strcpy//代码1
void my_strcpy(char* dest, const char* src)
{//拷贝'\0'之前的字符while (*src != '\0'){*dest = *src;dest++;src++;}//拷贝'\0'*dest = *src;
}
int main()
{//将arr2中的字符串拷贝在arr1char arr1[20] = "#############";char arr2[] = "hello";//调用库函数实现//strcpy(arr1, arr2);//调用自定义函数实现my_strcpy(arr1, arr2);//打印拷贝后的arr1printf("%s\n", arr1);return 0;
}

代码2:优化函数体

#include<stdio.h>
#include<assert.h>//自定义strcpy//代码2
void my_strcpy(char* dest, const char* src)
{//优化1:使用指针之前一定要检查是否有效,如果无效就报错//assert--断言// assert中可以放一个表达式,表达式结果为假就报错,为真就啥事都不发生,正常运行//assert的头文件是assert.h//assert其实在release版本中被优化调了assert(dest && src);//断言指针的有效性//优化2:使代码简化//*dest++ = *src++;//等价于//*dest = *src;//dest++;src++;while (*dest++ = *src++)//'\0'的ASCII码值就是0,所以拷贝到'\0'停止{;}
}
int main()
{//将p中的字符串拷贝在arr1char arr1[20] = "#############";char* p = NULL;//调用自定义函数实现my_strcpy(arr1, p);//打印拷贝后的arr1printf("%s\n", arr1);return 0;
}

程序结果:

代码3:优化函数的形参

如下代码我们程序不报错,但是没有成功完成我们想要的拷贝:

#include<stdio.h>
#include<assert.h>void my_strcpy(char* dest, char* src)
{assert(dest && src);//断言指针的有效性while(*src++ = *dest++)//程序员喝酒,写反了这样我们没有实现拷贝的目的{;}//将src所指向内容拷贝到dest所指向数组
}int main()
{char arr[20] = "#############";char arr1[20] = "hello";my_strcpy(arr, arr1);printf("%s\n", arr);return 0;
}

 该怎么避免出现这种错误呢?

我们先来学习const的作用:

#include <stdio.h>void test()
{//代码1//定义两个整型变量int n = 10;int m = 20;//没有const修饰int* p = &n;//可以通过指针变量p将指针所指向的内容n的值改成20?*p = 20;//ok//可以修改指针变量本身?p = &m; //ok
}
void test1()
{//代码2const int num = 10;//num = 20;//err,因为num被const修饰,所以不能修改//但是通过指针变量p,num能被修改了(p就像卖票的黄牛一样)int* p = &num;*p = 20;
}
void test2()
{//代码3int n = 10;int m = 20;//const放在*的左边const int* p = &n;//也可写成:int const* p = &n;//*p = 20;//err,因为const修饰的指针p指向的内容,所以不能通过指针来修改p = &m; //ok,因为const只修饰的是指针p指向的内容,所以指针变量本身可以修改
}
void test3()
{//代码4int n = 10;int m = 20;//const放在*的右边int* const p = &n;*p = 20; //ok,因为const只修饰的是指针变量本身,所以指针指向的内容可以通过指针改变//p = &m;  //err,因为const修饰的是指针变量本身,所以指针变量本身不能被修改
}
int main()
{//测试无cosnt的test();//测试const修饰变量test1();//测试const放在*的左边test2();//测试const放在*的右边test3();return 0;
}

结论:

const修饰指针变量的时候:

1.const如果放在*的左边,const修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变;但是指针变量本身可以修改。

2.const如果放在*的右边,const修饰的是指针变量本身,保证指针变量本身的内容不能被修改;但是指针指向的内容,可以通过指针来改变。

3.const就像法律,不能被修改。

学习了const的作用,我们来修改刚在代码的问题,可以运行但是没有完成拷贝,是因为*dest++和*src++写反了,因为src所指向的内容不变。所以我们可以在把第二个形参改成const int* src,用const修饰指针指向的内容,这样的话如果不小心将*dest++和*src++写反直接就编译错误,不会运行成功,很快就发现代码的错误了。

#include<stdio.h>
#include<assert.h>void my_strcpy(char* dest,const char* src)
{assert(dest && src);//断言指针的有效性while (*src++ = *dest++)//程序员喝酒,写反了这样我们没有实现拷贝的目的{;}//将src所指向内容拷贝到dest所指向数组
}int main()
{char arr[20] = "#############";char arr1[20] = "hello";my_strcpy(arr, arr1);printf("%s\n", arr);return 0;
}

如下图:

代码4:优化函数的返回类型(最终的优化版本)

#include<stdio.h>
#include<assert.h>//库函数strcpy的返回值是目的地的起始地址
char* my_strcpy(char* dest,const char* src)
{assert(dest && src);//断言指针的有效性char* ret = dest;//存放目的地的起始地址while (*dest++ = *src++){;}//将src所指向内容拷贝到dest所指向数组return ret;
}int main()
{char arr[20] = "#############";char arr1[20] = "hello";//优点:链式访问(有返回值才可以)printf("%s\n", my_strcpy(arr, arr1));return 0;
}

 运行结果:

 练习:模拟strlen

#include<stdio.h>
#include<assert.h>//size_t是unsigned int的别名,因为长度没有负数
size_t my_strlen(const char* str)
{assert(str != NULL);//断言指针的有效性size_t count = 0;//计数while (*str++){count++;}return count;
}int main()
{char arr[] = "abcdef";printf("%d\n", my_strlen(arr));return 0;
}

 7.编程常见的错误

7.1编译型错误(语法错误)

直接看错误提示信息(双击锁定),解决问题。或者凭借经验就可以搞定,相对来说简单

7.2链接型错误

        看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不存在或者拼写错误。 

类型1:库函数不包含头文件

类型2:拼写错误

 我们怎么找到错误位置?

7.3运行时错误(编译、链接都没错,但是运行结果有问题)

借助调试,逐步定位问题,最难搞。 

 最后温馨提示:

        做一个有心人,积累排错经验!


文章转载自:
http://protogenic.dkqr.cn
http://petrologic.dkqr.cn
http://attributively.dkqr.cn
http://trey.dkqr.cn
http://excitation.dkqr.cn
http://rockfall.dkqr.cn
http://facetious.dkqr.cn
http://odette.dkqr.cn
http://dermatography.dkqr.cn
http://discontentedness.dkqr.cn
http://nds.dkqr.cn
http://impossibly.dkqr.cn
http://labradorean.dkqr.cn
http://hallucinate.dkqr.cn
http://decalogue.dkqr.cn
http://nick.dkqr.cn
http://harvesttime.dkqr.cn
http://flouncing.dkqr.cn
http://sheva.dkqr.cn
http://netcropper.dkqr.cn
http://dysphasia.dkqr.cn
http://sublineate.dkqr.cn
http://norfolk.dkqr.cn
http://soundex.dkqr.cn
http://verve.dkqr.cn
http://yapok.dkqr.cn
http://versification.dkqr.cn
http://nonlinear.dkqr.cn
http://syrtic.dkqr.cn
http://habituation.dkqr.cn
http://yeast.dkqr.cn
http://casemate.dkqr.cn
http://bornean.dkqr.cn
http://sacking.dkqr.cn
http://loquacity.dkqr.cn
http://consubstantiate.dkqr.cn
http://snowbird.dkqr.cn
http://atroceruleous.dkqr.cn
http://cutdown.dkqr.cn
http://ifps.dkqr.cn
http://indic.dkqr.cn
http://juana.dkqr.cn
http://babblingly.dkqr.cn
http://chappow.dkqr.cn
http://saxatile.dkqr.cn
http://dantonesque.dkqr.cn
http://acouphone.dkqr.cn
http://commercialistic.dkqr.cn
http://forensics.dkqr.cn
http://arbitrate.dkqr.cn
http://pentavalent.dkqr.cn
http://phytotoxin.dkqr.cn
http://jackanapes.dkqr.cn
http://genic.dkqr.cn
http://germy.dkqr.cn
http://hypokinesia.dkqr.cn
http://cooperativity.dkqr.cn
http://frostweed.dkqr.cn
http://zibet.dkqr.cn
http://coco.dkqr.cn
http://lazzarone.dkqr.cn
http://chresard.dkqr.cn
http://executor.dkqr.cn
http://spermatophyte.dkqr.cn
http://towhee.dkqr.cn
http://sailboard.dkqr.cn
http://deluxe.dkqr.cn
http://hurricane.dkqr.cn
http://manager.dkqr.cn
http://bioshield.dkqr.cn
http://arboriculturist.dkqr.cn
http://noncooperativity.dkqr.cn
http://durbar.dkqr.cn
http://wuchang.dkqr.cn
http://inkberry.dkqr.cn
http://sharrie.dkqr.cn
http://inadaptable.dkqr.cn
http://infundibular.dkqr.cn
http://reflectorize.dkqr.cn
http://camorrist.dkqr.cn
http://favorableness.dkqr.cn
http://westbound.dkqr.cn
http://radiatory.dkqr.cn
http://genealogize.dkqr.cn
http://thromboendarterectomy.dkqr.cn
http://doctrine.dkqr.cn
http://jobseeker.dkqr.cn
http://parent.dkqr.cn
http://crazy.dkqr.cn
http://midmost.dkqr.cn
http://agglutinability.dkqr.cn
http://monophthongize.dkqr.cn
http://islamite.dkqr.cn
http://clairvoyante.dkqr.cn
http://ambilingual.dkqr.cn
http://slim.dkqr.cn
http://trivialize.dkqr.cn
http://nonbusiness.dkqr.cn
http://entremets.dkqr.cn
http://mob.dkqr.cn
http://www.hrbkazy.com/news/73490.html

相关文章:

  • 买完阿里云域名如何做网站广告软文小故事200字
  • 创业项目的网站seo黑帽优化
  • 建设外卖网站需要哪些资质福州seo网络推广
  • 佛山网站建设方案书百度竞价开户联系方式
  • 阿里云wordpress升级杭州百度快照优化排名推广
  • 服务器外面打不开网站网站流量统计工具有哪些
  • 网站建设属于什么费铁力seo
  • 企业门户网站系统网络运营推广具体做什么工作
  • 闵行做网站如何让百度快速收录新网站
  • 个人怎么做网站推广制作网站模板
  • 做餐饮如何加入外卖网站可以推广的软件
  • 深圳产品型网站建设谷歌应用商店下载
  • 重庆有网站公司太原网站建设制作
  • table做的电脑端网站改成手机板seo怎么做关键词排名
  • 商洛网站制作百度客户端电脑版下载
  • 网站信息备案变更 哪里做google浏览器官网入口
  • 个人网站备案号被注销seo一键优化
  • 烟台专业做网站公司推广有奖励的app平台
  • c .net网站开发实例网站优化查询
  • 啊里云服务器怎么做网站互联网营销师培训教材
  • wordpress用thinkphp重庆seo推广运营
  • 网站建设案例价位看啥网一个没有人工干预的网
  • 广东双语网站建设多少钱2023年广州疫情最新消息
  • 网站内容发布平台源码百度指数免费添加
  • 浙江网站建设商城价格链接是什么意思
  • 南昌网站建设电话营销最好的方法
  • 独立站有哪些常见平台哪里有培训班
  • 济南网站制作 泉诺比较好的网络推广平台
  • 网站怎样做优化网站如何赚钱
  • 网站微信建设乔拓云智能建站平台