C语言入门小白学习笔记(VS环境和调试技巧)

Debug和Release的区别:

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

Release称为发布版本,进行了优化,使程序在代码大小和运行速度上都是最优的,以便客户使用。

调试技巧:

优秀的代码:

1、代码运行正常

2、bug很少

3、效率高

4、可读性高

5、可维护性高

6、注释清晰

7、文档齐全

常见的coding技巧

1、使用assert

2、尽量使用const

3、养成良好的编码风格

4、添加必要的注释

5、避免代码的陷阱

优化代码举例(模拟实现strcpy)

以下代码模拟实现函数strcpy的功能,但是有优化空间(很矬,把’\0’和"bit"的拷贝分开来了)

初始代码

#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, char* str)
{

	while (*str!='\0')
	{
		*dest=*str;
		dest++;
		str++;
	}
	*dest = *str;//此时*str是'\0'
}
int main()
{
	//strcpy 字符串拷贝
	char arr1[] = "#######";
	char arr2[] = "love";
	my_strcpy(arr1,arr2);
	printf("%s\n",arr1);
	return 0;
}

优化第一次

void my_strcpy(char* dest, char* str)
{
	assert(dest != NULL);
	assert(str != NULL);//断言,如果括号里的式子判断为假就会报错并且提示到行
	while (*dest++ = *str++)
	{
		;
	}
}
int main()
{
	//strcpy 字符串拷贝
	char arr1[] = "#######";
	char arr2[] = "love";
	my_strcpy(arr1,arr2);
	printf("%s\n",arr1);
	return 0;
}

如果dest和str搞反了,在某些情况下运行成功之后只能通过调试找到问题

优化第二次

优化:在调用的源值(str)类型前面加上const修饰,str如果被修改就会报错,就可以避免dest和str写反导致功能实现反了。

#include<stdio.h>
#include<string.h>
#include<assert.h>
void my_strcpy(char* dest, const char* str)//加上const
{
	assert(dest != NULL);
	assert(str != NULL);//断言,如果括号里的式子判断为假就会报错并且提示到行
	while (*dest++ = *str++)
	{
		;
	}
}
int main()
{
	//strcpy 字符串拷贝
	char arr1[] = "#######";
	char arr2[] = "love";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

拓展 const:

const int *p//const int *p 修饰的是*p,也就是不能通过p改变*p的值
int* const p//int * const p 修饰的是p,就是不能改变指针变量p的地址

优化第三次

再次优化: 给函数设置返回类型char* ,然后返回dest的首地址(用指针ret指向),这样my_strcpy也可以用作别的函数的参数。

#include<stdio.h>
#include<string.h>
#include<assert.h>
char * my_strcpy(char* dest, const char* str)//加上const
{	
	char* ret = dest;//通过ret指向dest,最后可以通过返回ret来直接返回dest的首地址
	assert(dest != NULL);
	assert(str != NULL);//断言,如果括号里的式子判断为假就会报错并且提示到行
	while (*dest++ = *str++)//把str的字符串拷贝到dest指向的空间,包含'\0'
	{
		;
	}
	return ret;
}
int main()
{
	//strcpy 字符串拷贝
	char arr1[] = "#######";
	char arr2[] = "love";
	printf("%s\n", my_strcpy(arr1, arr2));
	return 0;
}

死循环(堆栈、越界访问)

该代码在某些编译器中运行结果为死循环,一直打印"hehe"(vs2019直接走不了)

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;
    }
    system("pause");
        return 0;
}

图解(图片引自 B站比特鹏哥) 很详细

在这里插入图片描述

当i=10的时候,就越界访问(非法)了,但是可以为arr[10]赋值为0

当i=12时刚好访问到i的地址(内存布局不同结果不同),这样i就等于0了,然后就会造成死循环。

注:本篇笔记是在B站比特鹏哥视频学习后结合个人理解写下的笔记,视频知识点远多于笔记内容,如有错误请指出,谢谢!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值