搜索
bottom↓
回复: 25

今天尝试着C语言模块化编程,每个功能.c.h,缺点变量传递不便

[复制链接]

出0入0汤圆

发表于 2012-9-25 23:18:51 | 显示全部楼层 |阅读模式
试着C语言模块化编程,每个功能.c.h
但是发现一个缺点就是变量传递不便,特别是
C51的位变量
uchar bdata alarm=0;
sbit OVER = alarm^0;
这样写  那个alarm变量就不能extern了。

请教下谁有好的办法 使变量传递方便呢???

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-9-25 23:18:52 | 显示全部楼层
本帖最后由 surken 于 2012-9-26 13:15 编辑
3050311118 发表于 2012-9-26 11:57
sbit 如果直接 定义引脚编译是没有问题的

关键是uchar bdata alarm=0;


sbit 直接 定义引脚 和 bdata是一样的
使用extern关键字是都用 bit

uchar bdata alarm=0;
sbit over=alarm^0;


extern bit over;

出0入162汤圆

发表于 2012-9-25 23:26:59 | 显示全部楼层

变量在.c文件里定义、初始化
在.h里面用extern 申明

要用到这个变量,包含这个.h 文件即可

出0入0汤圆

 楼主| 发表于 2012-9-25 23:34:52 | 显示全部楼层
AWEN2000 发表于 2012-9-25 23:26
变量在.c文件里定义、初始化
在.h里面用extern 申明

关键是
bdata类型的
下面加个sbit .....
就不能extern了

出0入22汤圆

发表于 2012-9-25 23:57:14 | 显示全部楼层
那是非标准的用法,只能在keil里面用,建议用比较通用的bit操作方式
比如&=和|=

出0入0汤圆

发表于 2012-9-26 00:59:07 来自手机 | 显示全部楼层
[Quote]一个缺点就是变量传递不便[quote]

That's called "scoping" and is a big advantage for C.

出0入0汤圆

发表于 2012-9-26 08:01:25 | 显示全部楼层
本帖最后由 hamipeter 于 2012-9-26 08:18 编辑

建议楼主用传统方法,这样写就可以了。

在.C的文件 中定义全局变量:uchar alarm=0;

在.h的文件中 做如下声明:
extern uchar alarm;
#defnie  OVER  0

在调用想使用该全局变量alarm的OVER位修改的C文件中可以这样使用:
alarm |= 1<<OVER  ;     // OVER位  =1
alarm &= ~(1<<OVER)  ;  // OVER位  =0

出0入0汤圆

发表于 2012-9-26 08:29:21 | 显示全部楼层
模块化编程通常是不共享变量的,而是通过get和set方式,一个模块的接口尽量通过函数的方式对外提供接口,为了提高效率可以弄成inline的。
模块化肯定是能行的,至于觉得不可行,可能是总体结构没有架构好。

出0入4汤圆

发表于 2012-9-26 08:35:47 | 显示全部楼层
第一,你没搞清楚什么是模块化编程。
第二,51(沿伸至所有8位机)不大适合离散性(类、派生、事件)的模块化,只适合紧凑型(或说变量关联型)的模块化。
第三,8位机的情况下,尽量多使用寄存器做为全局变量。

出0入0汤圆

发表于 2012-9-26 08:39:15 | 显示全部楼层
变量传递不便  不是缺点,如果楼主学到面向对象,会了解一个说法,叫做 “封装”, 就是把不希望被外界访问的变量给封到里面,这样做的好处是不被外界干扰,开发一个模块只关注模块本身即可,即方便也安全

需要的话,要么在头文件里使用extern,注意,是模块自己的头文件,别的模块要用到变量时,inlcude这个头文件。要么用函数包装一下,把直接对变量操作变成函数调用。要么写一个global.h,把全局变量声明放里面

还有,bit不是常用变量,不建议使用,使用unsigned char代替就行。担心空间不够用,就用6楼的方法,效率有一点损耗,不过很小不值得关注。而且两种方法都方便移植。

出0入0汤圆

发表于 2012-9-26 08:47:12 | 显示全部楼层
sbit不应该算作定义 只能算作声明,放头文件就行

出0入162汤圆

发表于 2012-9-26 08:57:07 | 显示全部楼层
3050311118 发表于 2012-9-25 23:34
关键是
bdata类型的
下面加个sbit .....

不要用sbit,不是标准c语法,可移植性差。

用宏处理位变量

出0入0汤圆

发表于 2012-9-26 08:58:15 | 显示全部楼层
我感觉是不太方便。。。    也许水平还不够

出0入0汤圆

发表于 2012-9-26 09:26:59 | 显示全部楼层
本帖最后由 surken 于 2012-9-26 09:30 编辑

对于这个问题,坛子里有很多高手老早就有讨论,楼主可以搜搜。我也是借鉴了他们的做法。
我是这样做的:
1.建立一个Header.h的头文件,在这个文件里使用#include命令引用所有的用户头文件(*.h)。
2.每个*.c文件对应一个同名的*.h文件,c文件里是函数的定义,h文件里是变量和函数的定义或声明。
3.在每个*.c文件的开头处使用#define命令定义一个独特符号,比如Key.c文件开头 #define __KEY__。
4.在每个*.h文件中这样处理(此处以Key.h为例):
#ifdef __KEY__
    #define __KEXT__
    //如有变量需初始化可放在此处
    __KEXT__    变量定义(带初值)
#else
    #define __KEXT__ extern
    //如有外部文件需使用Key.c文件中已初始化的变量可在此处声明为外部变量
   __KEXT__    变量定义(不能带初值)
#endif
//以下为变量和函数的定义(针对于Key.c文件)或声明(针对于其他外部文件),注意以下变量定义中不能对变量初始化。
__KEXT__    变量定义
__KEXT__    函数声明
5.在所有的c文件中使用#include命令引用Header.h文件即可。

对于楼主所考虑的sbit定义的符号应该是与硬件有关系的,可以直接建立一个Config.h的头文件来配置单片机的I/O口,然后在Header.h文件中引用Config.h文件即可。

以上是本人参考论坛其它同道的做法而得出的一种适合于自己的方法,欢迎大家指正或提出更好的意见,谢谢!

出0入0汤圆

发表于 2012-9-26 10:15:31 | 显示全部楼层
关键是
bdata类型的
下面加个sbit .....
就不能extern了

.c文件用 sbit申明;
在.h文件里 不用sbit 直接用bit就行了
如 : sbit    key1=P3^5;
extern  bit  key1

出0入0汤圆

 楼主| 发表于 2012-9-26 11:47:28 | 显示全部楼层
aleyn 发表于 2012-9-26 08:35
第一,你没搞清楚什么是模块化编程。
第二,51(沿伸至所有8位机)不大适合离散性(类、派生、事件)的模块 ...

寄存器作为全局变量?不懂

uchar a;  不是这样?
还是
sfr  b=0xfe;这样????

出0入0汤圆

 楼主| 发表于 2012-9-26 11:53:58 | 显示全部楼层
surken 发表于 2012-9-26 09:26
对于这个问题,坛子里有很多高手老早就有讨论,楼主可以搜搜。我也是借鉴了他们的做法。
我是这样做的:
1. ...

uchar bdata temp=0;
sbit .......

这样操作的好处是能省好多事情,C51的位操作比较方便,但是位标志位不能方便extern传递的话,是个麻烦事

这个定义在config.H里  
如果只uchar bdata temp=0; 编译器不会报错
但是sbit之后    编译器报错

但是我想要用这种方式来做吧标志位,效率比较高,省事省代码省ram

出0入0汤圆

 楼主| 发表于 2012-9-26 11:57:45 | 显示全部楼层
lihw2@ 发表于 2012-9-26 10:15
关键是
bdata类型的
下面加个sbit .....

sbit 如果直接 定义引脚编译是没有问题的

关键是uchar bdata alarm=0;
sbit over=alarm^0;
alarm是变量就不行

出0入0汤圆

发表于 2012-9-26 12:45:36 | 显示全部楼层
结构体,位域。。。。

出0入4汤圆

发表于 2012-9-26 13:00:12 | 显示全部楼层
模块化的东东,建议还是要符合Standard C
不要在里面带有体系相关的西西
检验方法是:移植到任何体系任何编译平台都不会出错,仅修改体系相关的文件即可

出0入0汤圆

发表于 2012-9-26 15:21:03 | 显示全部楼层
变量定为静态的 , 其他C文件要读取,需要通过接口函数来读写。

出0入0汤圆

发表于 2012-9-27 09:26:11 | 显示全部楼层
surken说得对,在
uchar bdata alarm=0;
sbit over=alarm^0;
之后,要使用
extern bit over;
不能用:
extern sbit over;

出0入213汤圆

发表于 2012-9-27 11:02:46 | 显示全部楼层
我支持8楼的说法.

出0入0汤圆

发表于 2012-9-30 20:46:27 | 显示全部楼层
标记一下。

出0入0汤圆

发表于 2012-9-30 21:19:36 来自手机 | 显示全部楼层
建议用函数而不是全局变量。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 22:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表