原文链接:http://www.cnblogs.com/liuameng/p/3707415.html

故事的起因是这样的

跟Lz争着争着就觉得,“非要跟他战个痛快!”于是就写了本文。。。

好吧,是因为我论文编不下去才写的


先看代码

# include <iostream> 
using namespace std; 
int main(void) 
{ 
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    char a[100]; 
    cout<<"请输入一个点分十进制IP地址:"<<endl; 
    cin.getline(a,99); 

    int sum=0,i=0; 
    while(*(a+i)!='.') 
    { 
        int n=*(a+i)-'0'; 
        sum*=10; 
        sum+=n; 
        i++; 
    } 
    int j=7; 
    char b[8]={'0','0','0','0','0','0','0','0'}; 
    cout<<b<<endl; 

    while(sum>=1) 
    { 
        int p=sum%2; 
        sum=sum/2; 
        char r=p+'0'; 
        b[j]=r; 
        j--; 
    } 
    cout<<b<<endl; 
    return 0; 
} 

我删除了最后一部分,因为它与我们的问题无关。增加了两行:

    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);

用途是使用现场的文件内容作为标准输入输出,这样就不用每次去敲char a[]了。本例中我使用的输入是"11.11.11.11"。

编译环境

Visual Studio 2010 (人艰不拆,恳请不要问我是否正版)

Windows 7

这样的环境确定了一点,程序中一般变量在栈空间是由3大向小生长的,变量自身是小端模式,但一个数组下标小者,地址值也小。

下面这个更重要一点:原文

在Debug 模式下:

VC 会把未初始化的栈内存全部填成0xcc,当字符串看就是 烫烫烫烫……

会把未初始化的堆内存全部填成0xcd,当字符串看就是 屯屯屯屯……

目的是可以让我们方便地看出那些内存没初始化。

但是Release 模式下不会有这种附加动作,原来那块内存里是什么就是什么。

我就在Debug模式下做一次演示,大家有兴趣可以试试Release下的情况。

要上图了,请注意观察:

第一次cout<<b<<endl前的截图

从一个例子看C++中的内存——我也是无聊才写这玩意儿教程

图可能有点大……

蓝色箭头划过的部分是 char b[] 的内存空间, 红色箭头划过的 char a[] 的内存空间。中间其他的变量:sum、i、j等等。主要变量p此时还有初始化,但是它跟我们的问题无关。真正需要注意的就是 b 和 j

&b = 0x004ff730
&j = 0x004ff740 //j在b的空间的后面

特别是j变量因为比较小(==7),所以在内存里是 07 00 00 00

第二次cout<<b<<endl前的截图

从一个例子看C++中的内存——我也是无聊才写这玩意儿教程

看到了么,“不是风动也不是旗动,也而不是心动”,而是变量j动了。所以最后输出的b也会不同。

因为b被“stack overflow”了,控制b如何结束的工作非常危险的交给了后面的变量,还好这里的j小,要是 j=-1 ,就只能靠 i 了……

总结

这个问题里面真正有意思的似乎还不是b输出的变化,而是为什么只有8个字符长的b变量,跟它前面紧挨的j变量相差了16个距离。

事实上所有的连续变量之间都空开了8个字节(用0xCC填充)

是为了对齐么?求指教~

最后,不知道happy同学满意了否,满意请点赞 :D

转载于:https://www.cnblogs.com/liuameng/p/3707415.html

标签: C++, 变量, 内存, char, cout, freopen

相关文章推荐

添加新评论,含*的栏目为必填