C语言,关于printf()输出字符串(数组)出现乱码的解释,求给个比较专业、略微详细的解释?

追我想追 2015-09-12 11:07:10
#include <stdio.h>
#include <stdlib.h>

int main()
{
char str[7]="abcdefg";
printf("%s\n",str); //方式一:数组分配空间不够,导致没地方存放‘\0’,输出乱码
int i;
char str1[100];
for(i=0;i<7;i++)
{
str1[i]=str[i];
}
printf("%s\n",str1); //方式二:数组copy过程中,没有copy到'\0',导致输出乱码

char str2[]="hjisajnaiji\0huisajhisaji"; //方式三,printf()和puts()的比较
printf("%s\n",str2);
puts(str2);

return 0;
}
代码中有方式一和方式二两种情况,最后都会输出乱码,原因我大概知道,但为了更方便地理解这个知识点,希望更加专业的解释……
(1)方式一是空间不够存储'\0',相反方式二是空间足够、但是最后'\0'没有copy过来
请问,方式一和方式二的区别与联系是什么?
(2)方式三比较了printf()和puts()的输出情况,应该是一样的
问题是:printf()和puts()都是遇到结束字符'\0'就停止输入,那么是否只要没有遇到结束字符,不管什么原因、空间不够还好、没有拷贝还好
只要没看到结束字符,就会随机给个乱码输出吗?

希望能有个专业、详细点的解释,非常感谢!!!
...全文
7944 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-09-14
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
  • 打赏
  • 举报
回复
引用 4 楼 weishen2011 的回复:
[quote=引用 2 楼 q3733353520 的回复:] 方式一:在数组str[7]后的内存区域中也是有值的,虽然你没有赋值,那些你打印的乱码就是那些区域里的值,直到遇到'\0' 方式二:同方式一 方式三; 也一样
也就是说跟定义时分配的空间大小毫无关系了? 不管空间小于字符串长度,还是大于字符串长度,总之只要最后printf()和puts()没有获取到‘\0’ 这两个函数就会继续读取给定空间之外的变量,因为这个变量是随机的,不可预知的,所以很多时候就会是乱码? 是这个意思么?[/quote] 是的
ri_aje 2015-09-12
  • 打赏
  • 举报
回复
1. 都是一直往后遍历,直到遇到内存中第一个 0 为止,在之前输出的就都是乱码。 2. 和上面一样。
苏叔叔 2015-09-12
  • 打赏
  • 举报
回复
建议,下断点,查看内存
追我想追 2015-09-12
  • 打赏
  • 举报
回复
引用 2 楼 q3733353520 的回复:
方式一:在数组str[7]后的内存区域中也是有值的,虽然你没有赋值,那些你打印的乱码就是那些区域里的值,直到遇到'\0' 方式二:同方式一 方式三; 也一样
也就是说跟定义时分配的空间大小毫无关系了? 不管空间小于字符串长度,还是大于字符串长度,总之只要最后printf()和puts()没有获取到‘\0’ 这两个函数就会继续读取给定空间之外的变量,因为这个变量是随机的,不可预知的,所以很多时候就会是乱码? 是这个意思么?
dtlxszj001 2015-09-12
  • 打赏
  • 举报
回复
声明时初始化,输出时限定输出长度,可以有效的减少输出溢出问题。
  • 打赏
  • 举报
回复
方式一:在数组str[7]后的内存区域中也是有值的,虽然你没有赋值,那些你打印的乱码就是那些区域里的值,直到遇到'\0' 方式二:同方式一 方式三; 也一样

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧