C语言从入门到精通——初阶8 VS环境-C语言实用调试技巧

 调试debug:除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。

调试的基本步骤:

1.发现错误

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

3.确定错误产生的原因

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

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

Debug版本:调试版本。包含调试信息,且不做任何优化,便于程序员调试程序。

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

启动调试F5  (搭配使用:切换断点F9

F5跳到的是执行逻辑上的下一个断点

开始执行不调试ctrl+F5

逐过程F10

逐语句F11(可以进入函数内部中)

ctrl+F5开始执行不调试

//一个死循环程序

int main()
{
	int i = 0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (i = 0; i <= 12; i++)
	{
		printf("hehe\n");
		arr[i] = 0;
	}

	return 0;
}

 死循环原因:arr[12]和i的地址一样,每次i=12时,arr[12]=0;又将i调整回0,进入死循环

arr[12]和i的地址一样的原因:

因为main函数内部创建了i和arr数组,都是局部变量,而局部变量是放在栈上的,栈空间的默认使用习惯是先高后低以及数组是随着下标的增长由低到高变化,所以数组往后越界就有可能在越界的过程中遇到i,改变数组元素时误将i进行了改变,造成死循环。

常见的coding技巧:

  • 1.使用assert
  • 2.尽量使用const
  • 3.养成良好的编码风格
  • 4.添加必要的注释
  • 5.避免编码的陷阱 

//模拟实现库函数strcpy

void my_strcpy(char* dest, char* src)
{
	while (*src != '\0')
	{
		*dest++ = *src++;
	}
	*dest = *src;//  '/0'拷贝
}

优化1: 

void my_strcpy(char* dest, char* src)
{
	while (*dest++ = *src++)//拷贝过去了\0,同时又让循环停了下来
	{
		;
	}
}

 优化2.1:

void my_strcpy(char* dest, char* src)
{
	if (dest != = NULL && src != NULL)//程序更健壮,可排除传参出错的情况
	{
		while (*dest++ = *src++)
		{
			;
		}
	}
}

优化2.2:

#include <assert.h>

void my_strcpy(char* dest, char* src)
{
	assert(dest!=NULL);//断言,头文件<assert.h>,表达式为真时无事发生,表达式为假时报错
	assert(src != NULL);
	while (*dest++ = *src++)
	{
		;
	}

}

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

	return 0;
}

 优化3:

#include <assert.h>

char* my_strcpy(char* dest,const char* src)//不希望源头数据修改
{
	char* ret = dest;//记录起始地址
	assert(dest!=NULL);//断言,头文件<assert.h>,表达式为真时无事发生,表达式为假时报错
	assert(src != NULL);
   //把src指向的字符串拷贝到dest指向的空间,包含'\0'字符
	while (*dest++ = *src++)
	{
		;
	}
	return ret;//返回目标字符串的起始地址
}

int main()
{
	//strcpy字符串拷贝
	char arr1[] = "###########";
	char arr2[] = "bit";
	printf("%s\n", my_strcpy(arr1, arr2);//可以进行链式访问

	return 0;
}

 //const int* p  = &num; 

const放在指针变量*左边时,修饰的是*p,也就是说:不能通过p改变*p(num)的值

 //int* const p  = &num;

const放在指针变量*右边时,修饰的是指针变量p本身,p不能被改变

//模拟实现strlen

#include <assert.h>

int my_strlen(const char* arr)
{
	int count = 0;
	assert(str != NULL);//断言,保证指针的有效性
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

错误类型:

编译型错误:双击可跳到位置,一般是语法错误

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

运行时错误:借助调试,逐步定位

95 C初阶考试讲解

//输入两个整数A和B,输出最小公倍数

	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);

	int min = a > b ? a : b;//表示两个数的最小公倍数,最小也要是两个数中间的较大数
	while (1)
	{
		if (min % a == 0 && min % b == 0)
		{
			printf("%d\n", min);
			break;
		}
		min++;
	}
	int i = 1;
	for (i = 1;; i++)
	{
		if (a * i % b == 0)
		{
			printf("%d\n", a * i);
			break;
		}
	}

 //将一句话的单词进行倒置,标点不倒置。比如I like Beijing. 经过函数后变为:Beijing. like I

#include<string.h>

void reverse(char* left, char* right)
{
    while (left < right)
    {
        char tmp = 0;
        tmp = *left;
        *left = *right;
        *right = tmp;

        left++;
        right--;
    }
}

int main()
{
    char arr[100] = { 0 };
    //输入进来,不能使用scanf(到空格处就不读取了)
    gets(arr);//输入进来 char * gets(char* str)
    //三步翻转法
    //1.字符串整体翻转
  
    int len = strlen(arr);
    reverse(arr, arr+len-1);//传入字符串起始和结束位置

    //2.单词逐个翻转
    char* start = arr;
    char* end = arr + len - 1;
    while (*start)
    {
        char* end = start;
        while (*end != ' ' && *end != '\0')
        {
            end++;
        }
        reverse(start, end - 1);
        if (*end == ' ')
            start = end + 1;
        else
            start = end;
    }
    printf("%s\n", arr);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值