打印

全局变量 局部变量引发的问题

[复制链接]
楼主: xyp749192072
手机看帖
扫描二维码
随时随地手机跟帖
41
xyp749192072|  楼主 | 2010-5-6 21:57 | 只看该作者 回帖奖励 |倒序浏览
LZ可能要把问题重新阐述清楚一下:LZ在顶楼说的是:第一种情况:使用全局变量获得结果正确,第二种情况:使用局部变量获得结果剧烈变化,不正确。

可是LZ在11楼说的情况又正相反!使用局部变量正确,使用全局变量 ...
冷漠 发表于 2010-5-6 14:34



你说的对,给你分的时候,以为你没找到根源,只是感激你的帮助,后来重看我的程序,发现你说的对,特再次感谢

使用特权

评论回复
42
xyp749192072|  楼主 | 2010-5-6 21:59 | 只看该作者
LZ可能要把问题重新阐述清楚一下:LZ在顶楼说的是:第一种情况:使用全局变量获得结果正确,第二种情况:使用局部变量获得结果剧烈变化,不正确。

可是LZ在11楼说的情况又正相反!使用局部变量正确,使用全局变量 ...
冷漠 发表于 2010-5-6 14:34

你解决了我的问题!!!感谢

使用特权

评论回复
43
xuyiyi| | 2010-5-7 06:30 | 只看该作者
谢谢 xyp749192072 解答,xyp749192072 的C语言功底很深厚,深不可测,老许又学习了一点小本事,再次感谢!

使用特权

评论回复
44
xuyiyi| | 2010-5-7 06:35 | 只看该作者
谢谢 jerkoh 解答,老许又学会了一点,
uchar ret[4]=0;  
如果是在keil环境下这可不是给 ret[4] 赋初值0 啊!
而是给ret[0] 赋初值0
请楼上几位大师别见笑,老许平时不搞技术,不开发产品,真的不懂C语言,
只想提着菜篮子在后面捡菜,跟着学点知识。

使用特权

评论回复
45
xuyiyi| | 2010-5-7 07:09 | 只看该作者
我刚验证了一下,确实看不出使用全局还是局部有什么差别。唯一的区别就是,局部变量在函数每次被调用时,ret[4]数组都被初始化为0,而全局变量只能在编译阶段被初始化一次!以后每次 read_byte(); 被调用时,ret[4]数组初值都不为0。
...
冷漠 发表于 2010-5-6 14:34


冷漠大师的这一条要点好极了,又学会了一招。谢谢!

使用特权

评论回复
46
冷漠| | 2010-5-7 09:28 | 只看该作者
本帖最后由 冷漠 于 2010-5-7 09:35 编辑
22#  
      我刚验证了一下,确实看不出使用全局还是局部有什么差别。唯一的区别就是,局部变量在函数每次被调用时,ret[4]数组都被初始化为0,而全局变量只能在编译阶段被初始化一次!以后每次 read_byte(); 被调用时,ret[4]数组初值都不为0。

31#
      所以,根据22楼,使用全局变量时,下面的ret[0]+mid 初值并不等于 0+mid !正如26楼所说,ret[0]里面是上一次的结果数值。
......
   for(j=0;j<4;j++)
      (
               mid=back[j] <<i;
                ret[j]=ret[j]+mid;                   
        }
........



知道原因,只要修改第一种情况,在函数中添加一句全局变量赋初值0即可:

uchar read_byte()
{
    uchar i,j;
    uchar mid;


ret[0]=0;  ret[1]=0; ......

    for(i=0;i<8;i++)
     {
            read_bit();
            for(j=0;j<4;j++)
                    {
               mid=back[j] <<i;
                ret[j]=ret[j]+mid;
                  
             }
      
     }
return ret[0];

}


冷漠 发表于 2010-5-6 17:24



正确答案应该是31楼。

使用特权

评论回复
47
xuyiyi| | 2010-5-7 10:08 | 只看该作者
冷漠大师正解!
其核心还是冷漠大师的 使用全局变量和局部变量的唯一区别,局部变量在函数每次被调用时,ret[4]数组都被初始化为0,而全局变量只能在编译阶段被初始化一次!以后每次 read_byte(); 被调用时,ret[4]数组初值都不为0。

使用特权

评论回复
48
程序匠人| | 2010-5-7 11:01 | 只看该作者
给冷漠加裤子一条,见31楼。

其实我发现“冷漠”是外冷内热。

使用特权

评论回复
49
程序匠人| | 2010-5-7 11:04 | 只看该作者
另外建议楼主改一个有意义的标题。便于后来人检索

使用特权

评论回复
50
冷漠| | 2010-5-7 14:12 | 只看该作者
本帖最后由 冷漠 于 2010-5-7 14:34 编辑

让匠人和老许一夸,冷漠快不知道自己是谁了。以前是懒得打字,现在再多写点:

关于全局变量和局部变量的初始化规则(见《实用C语言详解》)
    “如果一个纯量类型的静态对象(即全局变量——冷漠注)在说明时未包含初始化部分,那么它就被缺省初始化为零(或空字符)。
     类似地,如果一个静态指针对象的说明中不包含初始化部分,那么它就被缺省初始化为NULL。
    如果一个具有自动存储持续期的对象(即局部变量)在说明时未包含初始化部分,那么编译程序不会对它做隐式初始化,从而其初值是不确定的。”

冷漠添加内容:
1、全局变量分配在静态存储区,因而都是在都是在编译阶段(程序运行之前)进行初始化,显然只能初始化一次。static 局部全局变量也是同样。
2、自动变量分配在动态存储区,——被所有函数的局部变量以覆盖技术所共享,该变量存储单元在程序执行期间自动分配,——不是在程序开始执行之前分配,而是在进入其所在的分程序时进行的;每进入一次(被调用一次),就重新初始化一次。因此,自动变量的初始化工作与存储分配工作是同时进行的。
3、C51全局变量是在编译阶段由 INI.ASM 初始化程序赋值的。——编译完成后,INI.ASM 程序和STARTUP.ASM 一样不再有效。因此所有全局变量只能被初始化一次。
4、而自动变量是在程序运行阶段由程序表达式计算赋初值的。程序每被调用一次,局部变量就被重新初始化赋值一次。

使用特权

评论回复
51
Simon21ic| | 2010-5-7 14:18 | 只看该作者
呵呵,真正的牛人,是在屏幕前看着帖子,一笑而过的人。

使用特权

评论回复
52
xyp749192072|  楼主 | 2010-5-7 15:51 | 只看该作者
另外建议楼主改一个有意义的标题。便于后来人检索
程序匠人 发表于 2010-5-7 11:04

写这个标题 只是为了吸引人过来解答 有点炒作嫌疑 呵呵 下次不了,晕,给我这顿批·

使用特权

评论回复
53
xyp749192072|  楼主 | 2010-5-7 15:53 | 只看该作者
采用全局变量的时候,ret[0] 是上一次的结果,里面是有值的。
采用局部变量的时候,ret[0]被初始化为0。
全局变量和局部变量加起来的结果肯定不一致。 ...
yuyixuanta 发表于 2010-5-6 15:34


呵呵 没给你加分 有点冤

使用特权

评论回复
54
踢球老越位| | 2010-7-6 11:26 | 只看该作者
本帖最后由 踢球老越位 于 2010-7-6 11:30 编辑

向冷漠大侠提个问哈:
对于局部变量定义,是在定义的时候直接赋值,还是把赋值分开写好呢?
int i=0,定义并赋值;
int i;先定义
i=0;再赋值
两者没区别,但是从程序规范性讲,哪种比较合适点?

使用特权

评论回复
55
冷漠| | 2010-7-6 16:29 | 只看该作者
本帖最后由 冷漠 于 2010-7-6 16:38 编辑

且看两者的不一样:
1、static int i=1;
2、static int  i;
   i=1;
显然不一样。这时推哪种合适?1、是在编译阶段赋值的;2、是在运行阶段赋值的。教材上只有一种写法:1、。(当然和你说的动态变量不是一回事)

你说的,——教材上也只有一种写法:int i=0;
危险: int  i;先定义
上式不叫定义吧?

使用特权

评论回复
56
xuyiyi| | 2010-7-6 16:34 | 只看该作者
匠人说的对,“冷漠”是外冷内热。

使用特权

评论回复
57
冷漠| | 2010-7-6 17:50 | 只看该作者
本帖最后由 冷漠 于 2010-7-6 17:52 编辑

变量只有说明(没有定义概念?);局部变量的初始化只能在变量说明时显式进行。在程序执行前已有初值的变量叫做初始化变量。所以:
1、int i=0;     // 是标准写法,i 在说明时赋值,i 是初始化变量。
2、int i;        //  i 不是初始化变量,它的初始内容是随机的。

C51中的初始化变量是由编译程序生成了赋初值指令的变量。有些编译器可能不一样,它把初始化变量视为静态变量,——程序执行前已赋了初值。静态变量和动态局部变量显然不分配在一个区,那时 1、和2、就大不一样了。

使用特权

评论回复
58
zsyf0918| | 2010-7-7 08:03 | 只看该作者
你用软调一下 试试

使用特权

评论回复
59
pentral0311| | 2010-7-15 16:01 | 只看该作者
本帖最后由 pentral0311 于 2010-7-15 16:02 编辑

LZ我觉得你如果单步调试,慢慢看,还有记得一定要看汇编代码,你会发现问题的所在,虽然群里的大牛已经给出了答案,局部变量是临时的内存,当离开作用域后,这块地方是随时有可以被其他堆栈等信息占用的。就出现了你观察到的跳变现象

使用特权

评论回复
60
wzl-xx@163.com| | 2010-7-15 18:46 | 只看该作者
路过!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则