栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言1.调试使用技巧 + strcpy()实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言1.调试使用技巧 + strcpy()实现

快捷键

F11 细粒度 也会进入函数逐行
F10 把函数当作一条语句,略过
F5+断点,只在断点停

  1. 查看临时变量:
// 创建全部a10个,全部为0
int a[10] = {0};

局部变量和自动窗口:自动显示上下文临时变量
自动窗口和局部变量作用差不多

按F10打开局部变量窗口会显示该行附近变量

  • 监视:想看谁看谁:
    监视在名称下面输入要查的变量得到值
  • 内存:打开后可能显示不完全,拉长,输入格式:&i
  • 反汇编:打开汇编文件,在运行主文件时两边文件同时在运行
  • 寄存器也有
  1. 查看函数调用关系(堆栈,技术术语:栈==堆栈):
    F10后打开调用堆栈,随着不断调用函数,新函数名显示在上层,像栈一样,且左边箭头指在上面的现在处于的函数中,且随着程序运行,函数新进去的在上面,最后出函数的时候,新进去的在最上层也先出,栈结构符合实际。
    main()函数也是被其它函数调用的
  2. 特别的死循环代码:招聘题
    死循环

    表明原因:
    结果是死循环:发现arr[12]=12,而之前arr[11]已经越界,但会执行,arr[11]是内存中特别大的随机值,而arr[12]=12,很奇怪,查地址发现arr[12]地址和i是一样的,所以因为把i变成了0,所以i=12后又置0了,造成死循环。

解释:
内存中有三部分:
栈区(局部变量、函数参数)
堆区(动态内存分配)、
静态区(静态变量、全局变量)
内存中大的编号叫高地址、小的编号叫低地址

图示:如数组,先开辟一片空间,从低到高使用,即下标小的在下面先赋值,比如a[0]、a[1]

因为都是临时变量,存在栈区,所以因为栈区先使用高地址再用低。
先定义了i变量在高地址,而再创建数组使用的低地址,开辟的数组和临时变量i之间留着位置,往后a[11],a[12]正好撞到了了i,结果就把i给改了,变量之间的预留空间看编译器

如图:

这道题出自:《C陷进与缺陷》

C/C++对数组越界不做检查,不同编译器在内存预留给的不同,VC6.0和linux下给预留一个大小,visual studio预留了两个位置

良好编码风格:(高质量c-c++编程)

  1. 使用assert
  2. 尽量使用const
strcpy()实现


预知识:char a[10] = “hello”;
利用string的""做数组赋值时,自动给尾加
库函数strcpy也会拷贝

被复制对象有:const
****最差写法:解引用str_dest,*desst=*src,且循环外单独赋值 ****:
****好写法:解引用str_dest,*desst=*src ****:

void my_strcpy(char* dest, char* src)
{
	// 赋值表达式也有值,最后是while的值,使得while不成立
	while(*dest++ = *src++)
	{
	}
}

如果main()传入my_strcpy(dest, src):中dest是NULL,my_strcpy不会执行,所以在my_strcpy中加入:assert(dest!=NULL),会把错误直接提示,条件为假会提示
assert是宏(断言),需要《assert.h》
*解释原始的src前是 char src
如果我在str的while中写反了,运行起的时候会报错,而对src加const会使得while中直接报错,

解释const:

//加上const不能直接改变
const int num = 10;
num = 20; // const使得num不能改变,但利用指针能改掉,但这样不好,因为cosnt就希望永远不能变
如何使得指针也不能改变const变量
const int *p = #
给指针加上const,*p也不能改变num
但p的指向可改变,即:指针可改变指向谁,但不能改变内存
p = &n; 可执行
*p = 30; 不可执行
const如果放在int后面
int *const p = #
这样限制的是p,即p不能改变指向对象;

**const放在左边,表示指针指向变量的值不能改变, p=x,不可,但是p的指向可以改变
const在右边,指针指向的内容不能改变
而上面strcpy实现中,使用 const char
src:*在右边,即 cosnt(不变) *src:即内容不可以改变,所以dest和src写反就会报错,因为 *Src是违法操作

const:加上变量不能再通过赋值改变,但是指针可以,可是实际加const不希望变量改变,所以有了cosnt加在指针上

my_strlen(char* str)

每次解引用,都应该害怕指针为空

// 只是求长度不能改变它的内容,所以保护起来 const char* str
int my_strlen(const char* str)
{
	int count = 0;
	assert(str!=NULL);  //  所以加断言程序更加健壮,这样空了直接报错 不会往下执行,更好判断在哪里出错
	while(str!=NULL)    // ↑↑↑↑每次有指针循环遍历,就应该害怕有NULL  ↑↑↑↑
	{
		count++;
		str++;
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/893138.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号