打印

不提倡使用全局变量,2k数据该怎么办啊?所长出出招!

[复制链接]
楼主: zhuhai2004
手机看帖
扫描二维码
随时随地手机跟帖
21
gyt| | 2007-12-21 09:50 | 只看该作者 回帖奖励 |倒序浏览

行啊行啊

使用特权

评论回复
22
fsaok| | 2007-12-21 13:53 | 只看该作者

全局变量不使用?

我还没有听说过这种事情。

倒是有一次用了太多的局部变量,keil 搞的没空间,然后把大量的函数都又改回全局变量才OK。

全局变量是模块之间的耦合基础,一个模块和别的模块链接,其中最简单的方法,就是用全局变量;而另一种方法是用函数的参数交换,但没全局变量方法简单高效。

使用特权

评论回复
23
huangqi412| | 2007-12-21 14:21 | 只看该作者

有时候还是适当可以用的,

使用特权

评论回复
24
赤铸| | 2007-12-21 14:52 | 只看该作者

不用全局变量是末,封装才是本

全局变量不雅观,就用全局对象
啥叫对象?不一定 C++ 才能有对象。数据和操作“捆绑”在一起就是对象,关键在于数据访问途径尽量集中。
要以数据的操作(相当于 C++ 的成员函数)为基本单元组织程序,避免随处直接访问变量,不用全局变量也是为了这个

说的更通俗些,全局变量有两种:static 和 extern
建立一个独立的 .c 文件,变量用 static 定义,所有访问都通过该 .c 文件中定义的函数

example.c:

#include "example.h"

typedef struct{ ... } BABY;
static BABY baby;

extern void 喂食(MILK milk) // “成员函数”
{
    baby.mouth = milk;
    ...
}
extern void 把尿(...) // “成员函数”
{
    baby.xiaojiji = work;
    ...
}

这就叫“封装”,封装了,接口和实现独立了,程序就上路子了

使用特权

评论回复
25
zhuhai2004|  楼主 | 2007-12-21 17:03 | 只看该作者

看来需要补充能量才行了。

用汇编写过几个小程序,后来接到一个任务,以前的前辈用汇编60K的程序,看到全部都是全局变量,表格(第一次见到还有几级的表格哦)。真不知道要怎么规划新程序;
大伙的意思是只传递需要引用变量的指针,以及回调操作这些数据的函数?;还有封装对象,可是在8位机子里面这些开销都有点大。

使用特权

评论回复
26
后学| | 2007-12-21 17:09 | 只看该作者

不要教条,

拿goto来类比,

使用特权

评论回复
27
zhuhai2004|  楼主 | 2007-12-21 17:17 | 只看该作者

没有教条之前希望灵活是困难的。

再问一句:RS485通讯,通讯协议在接收中断里面解析,如:比对地址、需要出来的长度、数据帧是否正确、...。在中断里面回调时间太长了。

使用特权

评论回复
28
fsaok| | 2007-12-21 17:43 | 只看该作者

通讯数据最好不要在中断中处理

接收时,中断只是做一种动作!接收到的数据放入缓存和修改缓存指针等。其它就别做了。

另一个函数在主控中做解析:什么比对地址、需要出来的长度、数据帧是否正确等。

再上一层的函数做解析后的数据处理,收到的命令和数据该如何处理。

这三部分最好是分别在不同的模块里,明白了没有?哦,“咚”,我掉陷阱了

使用特权

评论回复
29
mohanwei| | 2007-12-21 19:12 | 只看该作者

我习惯一上来就搞一个全局结构体Pa……

软件方面微软做得最NB吧?大家不防把MFC框架或者库函数打开看看……满屏幕都是全局变量……

推荐不等于强制。实际上对于单片机那种规模得代码而言,全局变量才能使程序结构更清晰。

使用特权

评论回复
30
龙飞天下| | 2007-12-21 19:24 | 只看该作者

不提倡使用全局变量,为什么?

不提倡使用全局变量,就像不提倡使用goto一样,我就喜欢使用goto.

使用特权

评论回复
31
dld2| | 2007-12-21 19:26 | 只看该作者

看来下一个热门是“goto好还是结构化好”

使用特权

评论回复
32
IceAge| | 2007-12-21 22:49 | 只看该作者

关于全局变量 和 goto

并非是不可以用,而是用之前必须知道潜在的危害性。小型的程序较难察觉,大型的程序,会带来很多不必要的风险。如果在用之前,头脑里有这样的概念:我知道自己在做什么,但我能确定这么做是最好的方法,而且不会造成潜在的风险。 ---- 那么完全可以用,怕的是胡乱随意的使用。

使用特权

评论回复
33
IceAge| | 2007-12-21 23:04 | 只看该作者

mcu 的程序量一般比较小,所以很多人难以

理解 全局变量 的风险

如果 “中断里面回调时间太长了", 那么可以确定 全局变量 或 设计思路 的讨论对于你的程序基本上没有意义。设计思想的重要性与程序规模成正比,或许是指数关系。设想一下,你领导几个程序员,共同完成一个软件项目,首先你得面对编译时命名冲突的问题,接下来的是调试时,你不知道你的全局变量在什么地方被修改时,这时候你的痛苦。

使用特权

评论回复
34
赤铸| | 2007-12-22 02:17 | 只看该作者

“你不知道你的全局变量在什么地方被修改”

精华就在这一句啊

使用特权

评论回复
35
dld2| | 2007-12-22 08:37 | 只看该作者

培养新兵自然要强调规范性

强调规范是为了养成良好习惯,避免显而易见的问题。
否则一开始路子就野了,以后要改会很难。

到了成为身经百战的高手,自然无可无不可。但这也是独行侠的作风。

使用特权

评论回复
36
ayb_ice| | 2007-12-22 09:29 | 只看该作者

只要方便维护,不冲突,访问权限控制好

使用全局变量优点多多。。。

使用特权

评论回复
37
农民讲习所| | 2007-12-22 09:43 | 只看该作者

下面这个程序也使用了全局变量

这是俺最新成果,标准库工作的一部分,呵呵,这是应用部分,对ST16C554四串口扩展的应用驱动程序。

//--------------------------------------------------------
//16C554
//使用中断0接收
//--------------------------------------------------------
#include <libRain_Base.h>
#include <libRain_Unsiversal.h>
#include <libRain_M162.h>

struct InST16c554Drv
{
    struct ST16C554 sST16C554[4];
};
struct InST16c554Drv sInST16c554Drv;
#define this sInST16c554Drv

//--------------------------------------------------------
//554注册
//--------------------------------------------------------
void ST16c554Drv_Register( struct ST16C554 *psST16C554, U16 mConfig )
{
    U8 i;
    
    for( i=0; i<4; i++ )
    {
        if( !this.sST16C554.psCommunicateQueue ){
            //空白
            this.sST16C554.mAddr_High = psST16C554->mAddr_High;
            this.sST16C554.psCommunicateQueue = psST16C554->psCommunicateQueue;
            
            ST16C554_Setup( psST16C554, mConfig );
            return;
        }
    }
}

//--------------------------------------------------------
//INT0中断:554接收数据
//--------------------------------------------------------
SIGNAL( SIG_INTERRUPT0 )
{
    U8 i;
    struct ST16C554 *psST16C554;
    
    psST16C554 = &this.sST16C554[0];
    for( i=0; i<4; i++ )
    {
        if( psST16C554->psCommunicateQueue ){
            //空白
            ST16C554_Interrupt( psST16C554 );
        }
        else {
            return;
        }
        psST16C554++;
    }
}

//--------------------------------------------------------
//初始化
//--------------------------------------------------------
void ST16c554Drv_Init( void )
{
    Memory_Memset( (U8 *)&this, 0, sizeof(struct InST16c554Drv) );
    
    //设置INT0为低电平中断
    GICR |= (1<<INT0);
}

//--------------------------------------------------------
//析构
//--------------------------------------------------------
void ST16c554Drv_Destory( void )
{
    GICR &= ~(1<<INT0);
}

全局变量被封装在内部,外部通过注册队列指针传递相关信息,外部模块只和本身的队列操作相关,所有接收和发送管理被这个封装了,这个封装模块又调用通用库中的函数,一层一层的。

使用特权

评论回复
38
qihao| | 2007-12-22 10:59 | 只看该作者

偶觉得应当大力使用全局变量

除了内部循环计数器 i 以外,全部用全局!

特别是PC上, 局部用多了,会要你小命的。

使用特权

评论回复
39
computer00| | 2007-12-22 12:34 | 只看该作者

怎么会不知道在哪被修改了?当然知道了。

如果是全局的不知道在哪被改了,那么即使你做成局部的,最后也还是同样的情况,也不知道在哪被改了。

通常这些全局变量被访问的也就那么几个函数,怎么可能会不知道。全局变量也有变量名,
也是专用的,又不是拿它来随便乱用。

使用特权

评论回复
40
zhuhai2004|  楼主 | 2007-12-22 16:23 | 只看该作者

暂时做法:大数据块用全局变量,其他的不要。

8位机的程序也就是几十K而已,如果非得分割清晰的,代价也很大。当然所长的消息的方法对于组织程序还是很不错的。所长你的通讯程序在接收过程中没有任何的处理,只是接收完成所有的数据,再做协议的解析,效率?(需要组网的时候,非本机数据会怎样处置?)ST16C554_Interrupt( psST16C554 )这个会有解析的用途吗?

使用特权

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

本版积分规则