举例概述C语言知识点(‘\0‘、strcpy()函数缓冲区溢出问题、字符数组、struct结构体类型变量申请的地址空间特点)

‘\0’

'\0’表示ASCII码值为0的字符(即null、"")
在这里插入图片描述

strcpy()函数及缓冲区溢出问题

strcpy() 百度百科https://baike.baidu.com/item/strcpy/5494519?fr=aladdin
可以从代码strcpy函数的代码中知道,strcpy函数结束运行的条件是遇到’\0’ ,如果遇不到那就一直执行下去。(将会在下面的例子中详细讲)
在这里插入图片描述

举例说明(细讲文章标题内的所有知识点)

下面以(实验室成员管理系统)的片段代码为例子简单解释一下文章标题所提到的一系列知识点,总结写在了最后。相信了解strcpy函数、struct结构体类型变量地址分配的人会一看就会知道为什么。

定义了一个struct结构体类型,如下:
在这里插入图片描述

给M_array[0]赋值如图所示:
在这里插入图片描述

然后按照赋值的顺序输出一下结果发现非常的amazing啊!如图所示:
在这里插入图片描述

咋还多输出个name数组的内容bdrh呢?于是带着疑问与好奇输出了一下M_array[0].sno,结果输出是这样的:
在这里插入图片描述

啥玩意儿?这就很离谱了,按理说就输出个20182103744就OK,怎么就把name的内容也给连着输出了呢?

感觉在strcpy函数出了问题。换一下两个strcpy函数的位置看看:
在这里插入图片描述

再用Print_Info函数输出(输出都用了这个函数):
在这里插入图片描述

输出如下:
在这里插入图片描述

Emm…名字bdrh咋没了?

两个数组sno和name都是char类型的,仅仅是大小不一样,换了一下strcpy的位置怎么就有两种不同的结果呢?所以我就最后把sno数组的大小从原来的11改成了20:
在这里插入图片描述

结果居然输出对了
在这里插入图片描述

再输出一下M_array[0].sno发现还是对的:
在这里插入图片描述

总结上面的修改情况:加大了sno数组的大小并先给name字符数组赋值然后给sno字符数组赋值就可以了;

后来我发现:其实跟strcpy的执行顺序也没太大的关系,只要把sno字符数组的大小加一,从原来的sno[11]改成sno[12]就可以解决这一系列玄乎的问题了。中间的这些情况往下研究了一下是为什么。
在这里插入图片描述

能把别的数组的内容输出出来肯定是访问到了那个数组的地址,所以看一下这个结构体类型的M_array[0]的各个成员变量地址都是什么样的:
在这里插入图片描述

可以发现它们的地址都是相邻的。

其实只要稍微细心可以发现,学号20182103744是11位数,而我给的sno的数组大小也是11位,又用了strcpy这个处理字符串的函数。所以就出现了错误。原因就是因为sno数组末尾没有’\0’即没有空字符;

看一下strcpy函数的代码吧:strcpy_百度百科https://baike.baidu.com/item/strcpy/5494519?fr=aladdin
在这里插入图片描述

从代码中可知,函数会一个个遍历赋值直到遇见‘\0‘才会停止运行。又因为struct结构体类型的各个结构体成员变量的地址是连续的一片空间,而且两个成员数组的数据类型均为char类型。所以当执行了strcpy函数时在sno数组末尾未能找到’\0‘所以会一直进行下去,直至遍历到相邻的name数组遇见了’\0’才结束了操作。这便是 Strcpy函数中的缓冲区溢出问题

当把sno数组大小调大的时候strcpy函数就能结束且不出差错。也就是因为sno数组下标为0到10的数组均已赋值,但是之后的因为没有进行赋值所以是空的,即NULL;也就符合了strcpy函数遇到’\0’结束执行的条件。

关于strcpy函数的缓冲区溢出问题可以参考一下strcpy_百度百科的Strcpy函数中的缓冲区溢出问题和防范的内容。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值