4197|11

34

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

辛昕笔记请教 [复制链接]

复制内容到剪贴板
  • /*This is in xxx module.c*/
  • /*static global variable*/
  • static U8 Account[8];
  • static U32 Damn;
  • static U32 Full;
  • /*
  •      往往我们都有无可避免非得用全局变量或者静态变量的时候,事实上,很多时候这些变量是不好处理的。
  •      比如,我们也许会考虑这样一种最原始的办法:
  •      我们在每一个使用到的源文件里extern外部引用。
  • 但是,随之而来,我们会发现,当这样的全局变量越来越多起来,我们往往会对其失去掌控,当我们要修改或者删除时,搜索完毕和修改完毕是一件困难的事情。
  •    于是乎,我就萌生了一种把这些全局变量全部static在一个模块文件中的想法,这是因为,它仍然保留着全局的特性,方便多个函数一起引用,然而,因为它被我限制在同一个源文件,那么,修改时,我所需的修改,最多也就在一个源文件内,那么,无论是从搜索还是修改,这件事情都将变得容易许多。
  •     这样就剩下一个问题了。
  •    如何初始化它们?
  •     方法如下例所示,你应该一下就理解这种做法,它使用一个函数封装起来,这样,不管在任何一个源文件里,一般是主源文件里,你可以仅仅通过一个函数调用来完成,而无需担心全局变量的作用域。
  •     这样起来,事情就变得简单许多,也好控制许多。
  • */
  • /*
  •     这个函数,在我的理解里,其意义等同于这个StartUp()函数,只不过其作用只是为本模块源文件的全局变量做初始化用。
  • */
  • void InitialModule(void)
  • {
  •      U8 i;
  •       for(i = 0;i < 8;i++)
  •            Account = 0;
  •       Damn = 0;
  •       Full = 0;
  • }



版主兄弟,我对红色那段话不是很理解,,,全局变量为什么只在一个源文件中修改呢,,,在这么多地方都有引用了,,能否详细讲讲,,;最近写的程序很多全局变量不知怎么管理才好,,特此请教下???能有个列子就好了,,哈哈
此帖出自编程基础论坛

最新回复

就这儿聊吧~~ qq什么的,最近在戒  详情 回复 发表于 2012-10-24 21:19
点赞 关注
 

回复
举报

7815

帖子

57

TA的资源

裸片初长成(中级)

沙发
 
首先我要说的是。

把全局变量 的作用域限制在 一个源文件内部,即把它变成 源文件内的静态全局变量,其目的,正是为了应付 全局变量过多,难以管理 的 一种最重要的方法。


然后,你不妨按这样一种思路考虑一下:

你先回忆一下,你都怎么使用的全局变量,或者直接贴一段能说明问题的代码。

另外,按以下思路去思考:
1.这些全局变量,如果我就是不准你用全局变量,你会怎么办?
2.这些非全局变量的方案 和 全局变量的方案 差异何在?
   是操作麻烦了还是怎么了?
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

板凳
 
另外,你还可以考虑一个问题。

如果我有几个全局变量,它需要在好几个源文件中使用。
你是希望好几个地方都修改它呢? 还是 只有一个地方修改它?

我直觉,你感觉“最近写的程序全局变量很多,很难管理”——
十有八九 就是因为太多地方修改,又有太多地方引用 引发的。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

34

帖子

0

TA的资源

一粒金砂(中级)

4
 
原帖由 辛昕 于 2012-10-23 00:20 发表
另外,你还可以考虑一个问题。

如果我有几个全局变量,它需要在好几个源文件中使用。
你是希望好几个地方都修改它呢? 还是 只有一个地方修改它?

我直觉,你感觉“最近写的程序全局变量很多,很难管理”—— ...
你说得一点都没错阿,就是这点;我举个例子吧

//file a.c

uint8 g_curState;
.......

//file b.c

uint16 g_timeFlag
.......
//file main.c

uint8 g_curPC;
uint8 g_oldPC;

........

以上各个变量在很多文件中都要读取和修改,,,有时查找要修改真的很头痛,,,,不知道辛昕你是怎么做的??
还有就是,如果不用全局变量,我还真不知道怎么实现阿,,,还请指点下,,谢谢
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

5
 
我简单说说。

首先~~你命名变量名字的习惯非常好,比如 全局变量加个 g_ 前缀,哈哈~~  


你的情形,我刚开始也碰到过,我和你一样非常头疼。
这种情形最大的弊病正在于,多处修改,多处引用,因此,你总是不安的感觉

“这里修改了,会不会被其他处修改覆盖?这里引用的还是不是那里修改后的新状态呢.......”

事实上,你的这种直觉是对的——写程序写了一些时间后,你要开始相信自己的直觉,当你隐约觉得哪里不对劲,不管你当时能不能确切想到为什么,请你一定记住这种不对劲——
我自己就有这种感觉:
一个函数写好后,如果我总是感觉不自在,这个函数过后一般都会惹出点麻烦——不是潜藏着错误,就是让我接下去做的事情 做起来很费劲,而迫使我不得不修改。

说回正事。
你的这种感觉完全合理——如果你参考过 一些编程思想的书籍,如 代码大全,或者参考一些编程大牛的 编程箴言,你一定对这样的 教导 不陌生——

只在一处对全局变量做修改,至于引用,那是无所谓的,再多地方引用也不是太要命的事——事实上,如果不是有多处引用的需求,我才懒得用全局变量。

呵呵,罗嗦了一堆,下面我说说我是怎么做的。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

6
 
第一

在程序里,我们对于使用哪一种类型的变量,的原则一般是这样的。

可以的话,我一定首先用 局部变量,实在不行,我用 局部静态变量,要还是不行,那我就是使用 static 在 源文件内的 全局变量(我个人把它称为  文件域全局变量,或者叫 全局静态变量),我也不会首先动用 全局变量
——一句话,不到迫不得已我是绝对不会用 全局变量 的。

你应该可以看出
这个优先顺序  是 其 作用域 和 生存期 一步一步扩大的趋势。

局部变量 的 作用域 和 生存期 都只在 子函数内部;
局部静态变量,尽管其生存期一直存在,但它作用域只局限于 函数内部,在外部它是不可知的;
而 文件域全局变量,其生存期也一直存在,但作用域只是稍微广一些,可推广到 一个源文件;

而 全局变量 则已经 是 全能全知,它无处不在,无时不在。

为什么我们会优先选择 受限制最高的类型呢?

这正是为了方便管理变量。

说到底,我们之所以不把所有程序都写在main函数里,一个最重要的方面就是为了 一步一步抽象具体的动作。

我们只想知道 主函数都调用了什么函数,而不想马上就知道它的具体实现细节。
——这符合 自顶而下 的 原则。
如果没有子函数提供的这种 屏蔽细节功能,一个程序只要代码超过一千行,我们基本就会疯掉。

那么,既然我们用函数是为了屏蔽实现的具体细节,函数,可以认为是执行一种动作。程序的两个基本要素就是 数据 和 动作。
数据的载体 是 变量,它们或记录了程序运行的状态,或记录了某些最终,中间结果。

既然我们用函数屏蔽了具体实现的动作,那么,有什么理由不屏蔽具体的数据?

罗嗦了这么久。
这一个回复着重要解释的正是 为什么 限制变量的作用域和生存期。

也正是你的问题的核心。

全能全知的 全局变量 无处不在,说的形象点 就是 它随时随地在变,那么,对这样一个数据,你用起来当然是害怕的。

但是,全局变量的存在自有其理由。
那就是它会使一组共同数据,在一系列函数之间,甚至几个模块之间的通信变得异常简单。
这是一个矛盾。

所以,一个办法,就是折中,把这组共同数据 固定在 一个 源文件内部。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

7
 
这样干其实是很有效而且很合理的。

为什么?
我们经常以一组完成同类功能的函数 存放在一个源文件里作为一个独立的模块。
这种函数聚群的理由是,它们都共同完成一系列同类功能,因此成为一个独立模块;

那么,其实,全局变量 也可以作为一个 功能群聚 的 标志。

回想一下,在你使用的全局变量里,尽管它们各处被修改,各处被引用,但修改它们的,引用它们的,是不是其实都是 相关的一系列函数?它们之所以散落四方,只是因为这些功能在许多地方都被用到?

比如一个标志判断,是否允许某些动作执行。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

8
 

不好意思,罗嗦了一通,现在说说具体做法

如同你 红色 圈出来 的字体。

我的做法其实很简单。

鉴于全局变量的存在,基本上都是 基于 一系列类似功能的 判断,记录,于是,我把包含这些功能的 函数,变量(全局变量),全部封装为一个模块——这个模块可能是一个 用户语境 的 模块,比如说,,LED控制模块,比如 声音控制模块,也可能是一个程序内部的功能模块,它可能很细节很小,比如 内存检查模块,比如说 总功能使能/禁止 管理模块.......

我会把这些相关的全局变量的 操作的 函数 中,和 这个模块功能很贴切地全都放到这个小模块里。
当然,它肯定会存在一些地方需要直接 读写 这些变量,那也不要紧,我可以向外提供一个函数,让外部通过这个函数去操作这个 被 限制在 那个模块源文件里 的 全局变量。

比如说
  1. // file x.c
  2. static U8 DisableFlag = NO;

  3. void Set_DisableFlag(U8 Status)
  4. {
  5.        DisableFlag = Status;
  6. }

  7. //读也一样,类似的
复制代码
这样的好处是。

第一,查找起来容易——尽管可能各处都会 Set。。。。都会 Get();

但不管如何,它们共同设置的那个变量,都紧紧被我握在那个模块里。
它们操作的途径(那个具体的函数),也在那个模块里。

对于直接 读写 这种函数,你可能直接看不出好处。
但假设这不是一个简单的好处,但假设这是一个复杂,充满条件判断的操作函数,那就会进一步看到好处。

应该说,这是一种比较好的做法,具体的好处我现在也说不出来,不过我现在可以举一个例子。

我有一个全局状态
g_Status;
它的设置原则如下:

它的可能值为 0 1 2 3 4 5
程序中有5处可能设置它,哈哈,当然,这五处分别要吧它们设为 1 2 3 4 5
但是我们不能直接设置,而是要遵循一定原则:

比如最简单的一种是,每次设置都只能保证 大的值优先于小的值。
也就是说,每次设置以前,我都要查询,当前值是否小于我要设置的新值,如果是就值,否则就保留当前更大的值。

如果不集中成一个函数来共同操作。
那我势必每处修改之处,都要重复一次 检查。
如果我封装起来,那么,不管我要在哪里设置,也不管我要设置多少,我只要把想设置的新值作为参数传入,我就可以直接完成 判断 和 设置;

这个简单的例子体现了  减少 重复 的 好处。

  实在没想到更好的理由,不好意思~~
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

9
 
对了,关于我问到的那个 如果不使用 全局变量 怎么做?

其实还是有办法,那就是按地址传入函数。

这种办法,有时用效果奇好,但和所有办法一样,不能滥用,不能,它至少会造成 函数接口过于复杂 的 毛病
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

10
 
哥们真是对不住了,昨晚上匆匆回复完,睡下后,我回头想想觉得自己说的内容一团糟。

这么说吧。
这只能说明我自己对这一部分内容还属于 知其然 ,而不知其所以然 的 状态。

但是,全局变量 的存在是为了解决 变量 在 函数之间,在模块之间 的 通信问题。
这属于 数据耦合 的问题。
我建议你可以看看 代码大全 这本书 第五第六章,这两章说的是 子函数 和 模块 的 设计,它考虑的问题有一大半和 数据耦合 有关系。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

34

帖子

0

TA的资源

一粒金砂(中级)

11
 
首先,,狠是感谢辛昕这么及时答复,,你也没什么对不住咱,,,,哈哈
你说的我都会认真的思考的,并结合自己遇到的情况再理解;
你有QQ吗,,能否留个,,,
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

12
 

回复 11楼 intermec 的帖子

就这儿聊吧~~
qq什么的,最近在戒
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表