| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1663 人关注过本帖, 1 人收藏
标题:有点疑问,请教大家。小女子谢谢
只看楼主 加入收藏
wang8114020
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2007-12-12
收藏(1)
 问题点数:0 回复次数:16 
有点疑问,请教大家。小女子谢谢
1、
int main()
{
    const int a=0;
    int *p=(int*)&a;

    *p=3;
    printf("a=%d,*p=%d\n",a,*p);

    return 0;
}
输出结果:a=0,*p=3   
2、
int main()
{
     int a=0;
    const int *p=&a;

    a=3;
    printf("a=%d,*p=%d\n",a,*p);

    return 0;
}
输出结果:a=3,*p=3
1)为什么前面的a不是等于3,我认为a所在的内存地址里的值已经改为3了,按道理a对应的值也应该 是3.或许你们会认为因为a是const变量,那好看下面
2)按照第一题的输出结果,那为什么第二题*p的值又改变为3了呢??它指向的值不也是const的。
请教高手解释下,这个两个结果我认为有矛盾之处。
搜索更多相关主题的帖子: int 小女子 疑问 内存 const 
2008-05-05 11:41
qhscqb
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2007-2-3
收藏
得分:0 
编译系统的问题吧
我用win-tc运行后a=3,*p=3

编程快乐,快乐编程! 没有最好,只有更好!
2008-05-05 12:32
死了都要C
Rank: 4
来 自:四川成都
等 级:贵宾
威 望:13
帖 子:1582
专家分:116
注 册:2006-12-7
收藏
得分:0 
恩``我运行2个程序都和LS一样``结果都是3

女施主``我给你``送茶来了```师太``你就从了老衲吧``
代码本天成~~~妙头偶得之```
2008-05-05 12:52
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
这个问题应该这么看。首先通过指针去掉变量的const属性的行为是未定义的,讨论起来其实没什么意义。然后我们分析一下这个结果是怎么来的。
下面是一段GCC编译过后的代码:
    movl    $3, -4(%ebp)
    leal    -4(%ebp), %eax
    movl    $3, %edx
    movl    %eax, 16(%esp)
    movl    %eax, 12(%esp)
    xorl    %eax, %eax
    movl    %edx, 8(%esp)
    movl    %eax, 4(%esp)
    movl    $LC0, (%esp)
    call    _printf

可以明显看出,因为a是常数,因此在使用a的时候,编译器直接使用了a的值,而不是从a的内存地址读取a的值。
但在VC编译的时候,因为过度优化,编译器直接写0,3两个数字进去了。所以我给a加了一个属性,如下:
volatile const int a=3;
强迫编译器,每次都要读a的值。于是在VC下,第一个程序的输出变成了a=3,p=3
但是在GCC下无效。观察源代码发现,编译器对a的值的改变在printf语句的后面(ft……)可能是编译器认为既然使用a的值的时候,a的值并没有改变。所以两条语句的顺序可以随意改变吧……反正这么写
    volatile const int a=0;
    int *p=(int*)&a;

    *p=3;
    printf("a=%d,*p=%d\n",a,*p);
    printf("a=%d",a);
输出的结果是a=0,*p=3,a=3………………这个么,这个应该不算编译器Bug,因为编译器不必为这种行为负责:改变常量的行为本身就是未定义的……

第二个问题很简单。p的确是指向常量的指针。但是a不是常量啊,a的值是可以改变的。所以a改变以后,p的值也跟着改变咯……

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-05-05 14:36
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:0 
翅膀还可以把汇编注释下啊?-4(%ebp)?是什么?

学习需要安静。。海盗要重新来过。。
2008-05-05 14:41
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
Orz……大家都不懂汇编么?
首先,ebp-4是a的地址。然后要调用printf对吧?下面的代码推入了几个值。

    movl    $3, -4(%ebp);3移入a
    leal    -4(%ebp), %eax;a的地址移入eax
    movl    $3, %edx;3移入edx
    movl    %eax, 16(%esp);这两行其实可以无视掉,主要是我确定
    movl    %eax, 12(%esp);p的值和a的地址是不是一样的,答案……可以看出来了……
    xorl    %eax, %eax;eax清0,注意a的初始值等于0,这里明显使用了a的原值(而不是现在a的值,注意a已经被改成3了……)
    movl    %edx, 8(%esp);还记得edx么?是3
    movl    %eax, 4(%esp);eax是0
    movl    $LC0, (%esp);字符串"a=%d,*p=%d"
    call    _printf;调用printf

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-05-05 14:48
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
上面是没有加volatile的版本。下面是加了volatile的版本……Orz……已经对GCC编译器无语了……
源代码:
#include <stdio.h>

int main()
{
    volatile const int a=0;
    int *p=(int*)&a;

    *p=3;
    printf("a=%d,*p=%d\n",a,*p);

    return 0;
}

汇编代码:
    movl    $0, -4(%ebp);a赋初值
    movl    $3, %eax;eax赋3
    movl    %eax, 8(%esp);eax的值入栈
    movl    -4(%ebp), %eax;a的值存入eax,我的天哪,3这个值还没有写入a……服了GCC了……
    movl    $3, -4(%ebp);这个时候把3写进a,是不是晚了点……
    movl    $LC0, (%esp);字符串入栈
    movl    %eax, 4(%esp);写a,Orz,eax这个时候是0……
    call    _printf;调用……

看完汇编代码,对GCC完全FT了……

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-05-05 14:55
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
去掉了const修饰符以后,代码如下:
    movl    $0, -4(%ebp)
    movl    $3, %eax
    movl    $3, -4(%ebp)
    movl    %eax, 8(%esp)
    movl    -4(%ebp), %eax
    movl    $LC0, (%esp)
    movl    %eax, 4(%esp)
    call    _printf

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-05-05 14:58
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:0 
我大三得时候学的汇编现在指令忘得差不多了...有时间还是要看看

学习需要安静。。海盗要重新来过。。
2008-05-05 14:58
wang8114020
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2007-12-12
收藏
得分:0 
回复 6# 的帖子
谢谢!
2008-05-05 15:59
快速回复:有点疑问,请教大家。小女子谢谢
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020102 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved