文章目录
- 前言
- 一、调试
- 二、debug和release
- 三、调试需要多用,多熟悉
- 四、栈区底层简单介绍
- 五、优秀的代码:
- 常见的coding技巧:
- 六、const 修饰指针变量
- 1. const 出现在 * 左边
- 2. const 出现在 * 右边
- 七、strcpy函数的仿写
- 1.版本1
- 2. 版本2
- 3. 版本3
- 4. 版本4
- 总结
前言
VS调试、debug,release、栈区底层简单介绍,好的代码,以及const修饰指针变量以及strcpy函数的仿写
一、调试
调试的快捷键
- F5 启动调试,经常用来直接跳转到断点。
- F9 创建和取消断点。
- F10 一次执行一个过程,比如一个语句,一次函数的调用
- F11 一次执行一句话,会进入函数内部执行语句。
二、debug和release
- debug 通常是指调试版本。
- release 通常是发布版本,无法调试。
三、调试需要多用,多熟悉
- 调试很重要
- 据说,初学者80%写程序,20%调试(修bug),程序员20%写程序,80%调试.
四、栈区底层简单介绍
- 先看一个例子
- 这是在VS2019环境下的代码
- 此代码的结果是死循环,重复打印“hehe”。
#include <stdio.h>int main()
{int i = 0;int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };for (i = 1; i <= 12; i++){arr[i] = 0;printf("hehe\n");}// i 与 arr 都是局部数据,都会放到栈区// 栈区的使用习惯是先高地址,再低地址// 所以,i 是 高地址, arr 是低地址// 但是 arr 数组的下标是由低地址到高地址// 所以给一定情况的越界,会导致 arr 和 i 的是同一个地址// 所以 i 会不断地重置为0 ,会陷入死循环。return 0;
}
- 内存分为 栈区,堆区,静态区
-
- 栈区内存的使用习惯是,先使用高地址空间,再使用低地址处的空间。
-
- 数组随着下标的增长地址是由低到高变化的。
-
- 如果i 和 arr之间由适当的空间,利用数组的越界操作就可能会覆盖到i,就可能会导致死循环出现的。
五、优秀的代码:
- 代码运行正常
- bug少
- 效率高
- 可读性高
- 可维护性高
- 注释清晰
- 文档齐全
常见的coding技巧:
- 使用assert
- 尽量使用const
- 养成良好的编码风格
- 添加必要的注释
- 避免编码的陷阱
六、const 修饰指针变量
1. const 出现在 * 左边
int main(){int a = 0;int n = 0;const int* p = &a;//*p = 0; // errp = &n; // rightreutrn 0;
}
- 如上代码
- const 出现在 * 左边,表示指针变量p所指向的对象不能通过变量p被修改。
- 但是,指针变量p可以重新取地址,不可以被修改。
2. const 出现在 * 右边
int main(){int a = 0;int n = 0;int* const p = &a;*p = 0; // right//p = &n; // errreutrn 0;
}
- 如上代码
- const 出现在 * 右边,表示指针变量p所指向的对象可以通过变量p被修改。
- 但是,指针变量p不可以重新取地址,可以被修改。
七、strcpy函数的仿写
- strcpy库函数是会把字符串的**\0字符**也拷贝上的。
1.版本1
#include <stdio.h>
// strcpy函数的仿写
void my_strcpy(char* dect, char* ret)
{while (*ret != '\0')// ret中若找到\0则跳出循环,此时*ret已经时\0,再次赋值就可以将\0也拷贝到dect中{*dect = *ret;dect++;ret++;}*dect = *ret;
}int main()
{char arr1[20] = "XXXXXXXXXXXXXX";char arr2[] = "hello bit";my_strcpy(arr1, arr2);printf("%s", arr1);return 0;
}
2. 版本2
#include <stdio.h>
// strcpy函数的仿写
void my_strcpy(char* dect, char* ret)
{while (*ret != '\0'){*dect++ = *ret++;}*dect = *ret;
}int main()
{char arr1[20] = "XXXXXXXXXXXXXX";char arr2[] = "hello bit";my_strcpy(arr1, arr2);printf("%s", arr1);return 0;
}
3. 版本3
#include <stdio.h>
// strcpy函数的仿写
void my_strcpy(char* dect, char* ret)
{while (*dect++ = *ret++){;}
}int main()
{char arr1[20] = "XXXXXXXXXXXXXX";char arr2[] = "hello bit";my_strcpy(arr1, arr2);printf("%s", arr1);return 0;
}
4. 版本4
- 考虑到如果用户传过来的不是指针
- 如果传入数据写反了等情况
#include <stdio.h>
#include <assert.h>
// strcpy函数的仿写
void my_strcpy(char* dect, const char* ret)
{assert(dect != NULL);assert(ret != NULL);while (*dect++ = *ret++)// ret中若找到\0则跳出循环,此时*ret已经时\0,再次赋值就可以将\0也拷贝到dect中{;}
}int main()
{char arr1[20] = "XXXXXXXXXXXXXX";char arr2[] = "hello bit";char p = NULL;//my_strcpy(arr1, p); // 错误示例//my_strcpy(arr2, arr1); // 会报错my_strcpy(arr1, arr2); printf("%s", arr1);return 0;
}
总结
VS调试、debug,release、栈区底层简单介绍,好的代码,以及const修饰指针变量以及strcpy函数的仿写