鱼C论坛

 找回密码
 立即注册
查看: 1706|回复: 0

[技术交流] 【菜狗正在爬行】变量未初始化时输出乱码的原因

[复制链接]
发表于 2016-11-10 15:13:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
【声明:针对初学C语言的小伙伴,会使用 printf 的就不用看了】


昨天C语言时老师警告我们:变量定义时一定要赋值,否则直接使用时就会出现意想不到的后果。

  为啥呢?

今天我们就来看看未初始化的变量里边是什么东西。

测试程序:
  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int i;  
  6.     double d;  
  7.   
  8.     printf("%d\n%lf\n", i, d);  
  9.     printf("%0X\n", i);  
  10.     printf("%0X\n", d);  
  11.   
  12.     return 0;  
  13. }  
复制代码


VC++6.0下Debug的运行结果:

  1. -858993460

  2. -92559631349317831000000000000000000000000000000000000000000000.000000

  3. CCCCCCCC

  4. CCCCCCCC
复制代码


那么这个垃圾值到底是什么呢?如果你知道函数调用时的堆栈初始化,那就应该知道了。
没错!你没有看错!就是CC···哈哈,我这里跟不知道的同志们普及一下,知道的就绕过。

先看一下,函数被调用时的初始化:
  1. push    ebp      ;保存ebp寄存器的值  
  2. mov     ebp, esp ;堆栈已准备完毕,随时准备战斗  
  3. sub     esp, 4C  ;分配4C(76)大小空间  
  4. push    ebx      ;保护可能被伤害的寄存器  
  5. push    esi  
  6. push    edi  
  7. lea     edi, dword ptr [ebp-4C] ;开工了,准星瞄准初始化堆栈地址  
  8. mov     ecx, 13                 ;循环次数  
  9. mov     eax, CCCCCCCC           ;初始化数值(乱码的绰号)  
  10. rep     stos dword ptr es:[edi] ;循环初始化
复制代码



上边就是函数被调用时进行的堆栈区初始化代码,如果没有学过汇编,就这么理解:

其实很简单,就是想去一个游泳馆游泳(调用一个函数),人家游泳馆方面就把一些怕被你知道或者怕被你破坏的东西给先藏起来(保护寄存器),然后分配一个游泳池(内存区域),并且往游泳池里灌满水(0CH来填充),然后你就可以在里面任意游泳嬉戏了(使用分配的内存)。

乱码是什么意思呢?其实就是进制间的转换而已。

拿上边这个小例子来说:

int类型占4个字节,那么内存中i变量的区域内容就是0xCCCCCCCC 这8个十六进制数,转换成%d的十进制的输出格式也就是那个所谓的乱码了。

--- ---
当然,以上是Debug模式下的运行,VC6会自动初始化变量为0xCC;但是Release模式下,人家VC6就不管了,那就是变量空间原本的值就是初始值,那就说不准是啥了。



<由于水平限制,如果文中有错误或者有不同意的地方,请麻烦指出来,我一定及时纠正并学习>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 17:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表