一、什么是bug?

是指在软件运行中因为程序本身有错误而造成的功能不正常、死机、数据丢失、非正常中断等现象

二、调试的基本步骤

1.发现程序错误的存在

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

3.确定错误产生的原因

4.提出纠正错误的解决办法

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

release和debug的介绍

debug版本是调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序。

 

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

release版本可能会优化内存位置,例如改变i的位置在数组前面。需要注意

三、如何写出好(易于调试)的代码

优秀的代码:

1.代码运行正常

2.bug很少

3.效率高

4.可读性高

5.可维护性高

6.注释清晰

7.文档齐全

常见的coding技巧:

1.尽量使用assert(断言)

2.尽量使用const

3.养成良好的编码风格

4.添加必要的注释

5.避免编码的陷阱

模拟实现strcpy

版本1

void my_strcpy(char* dest, char* src)
{
  while(*src != '\0')
  {
    *dest = *src;
    src++;
    dest++;
  }
   *dest = *src;//赋给'\0'
	//把src指向的字符串拷贝到dest指向的空间,包含'\0'	
}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
	my_strcpy(arr1, arr2); 
	printf("%s\n", arr1);
	return 0;
}

优化1:使用双目操作符

void my_strcpy(char* dest, char* src)
{
	while(*src != '\0')
  {
			*dest++ = *src++;//优化1,直接使用双目操作符
	}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
	my_strcpy(arr1, arr2); 
	printf("%s\n", arr1);
	return 0;
}

优化2:在while语句中直接进行计算

void my_strcpy(char* dest, char* src)
{

		while(*dest++ = *src++)//优化2,在while语句里直接进行判断
		{
			;
		}
}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
	my_strcpy(arr1, arr2); 
	printf("%s\n", arr2);
	return 0;
}

优化3:判断是不是野指针

void my_strcpy(char* dest, char* src)
{	
	if(dest != NULL && src != NULL)//优化3,判断是不是野指针
	{
		while(*dest++ = *src++)
		{
			;
		}
	}
}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
	my_strcpy(arr1, arr2); 
	printf("%s\n", arr2);
	return 0;
}

优化4:加入断言

void my_strcpy(char* dest, char* src)
{
	assert(dest != NULL);//加入断言,优化4
	assert(src != NULL);	
	
		while(*dest++ = *src++)
		{
			;
		}
}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
	my_strcpy(arr1, arr2); 
	printf("%s\n", arr2);
	return 0;
}

优化5:加入const

const 在不同位置对指针的修饰作用不一样

void my_strcpy(char* dest, const char* src)//优化5,加入const
{
	assert(dest != NULL);
	assert(src != NULL);	
	
		while(*dest++ = *src++)
		{
			;
		}
}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
	my_strcpy(arr1, arr2); 
	printf("%s\n", arr2);
	return 0;
}

优化6:优化6,改变void为char*,返回地址

char* my_strcpy(char* dest, const char* src)//优化5,加入const
{
  
	assert(dest != NULL);
	assert(src != NULL);	
	
  char* ret = dest;
		while(*dest++ = *src++)
		{
			;
		}
	return ret;
}

int main()
{
	//strcpy
	//字符串拷贝
	char arr1[] = "#############";
	char arr2[] = "kevin";
  printf("%s\n", my_strcpy(arr1, arr2));
	return 0;
}

四、编程的常见错误

常见错误的分类:

编译型错误

直接看错误提示信息,解决问题。

链接型错误

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

运行时错误

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