这几条指令的意义是什么?

[复制链接]
613|16
手机看帖
扫描二维码
随时随地手机跟帖
yufe|  楼主 | 2018-6-5 11:00 | 显示全部楼层 |阅读模式
用C语言编写的单片机程序,含有多个C文件,多个h 文件,在含有main函数的C文件中,第一条指令是#define a,这里的a泛指一个变量,而在用户自定义的一个h文件中,与之对应的有这样几条指令:
#ifndef a   
    #define EXT extern
#else
      #define EXT
#endif
我知道这是条件编译,这样写结果是执行:  #define EXT
我要问的是,这几条指令的意义是什么?
llia| | 2018-6-5 11:06 | 显示全部楼层
这种用法应该是在h文件中定义各个C文件用到的变量,然后每个C文件都包含所有的h文件,对于有#define a的C文件来说,EXT被空字符串替换,EXT  int var1其实就是int var1,是定义一个变量,对于没有#define a的C文件来说,EXT被extern替换,EXT  int var1就是extern int var1,是声明一个外部变量。

使用特权

评论回复
langgq| | 2018-6-5 11:08 | 显示全部楼层
嗯,这样做的好处就是可以在各个h文件中定义相应C文件中使用的变量,然后每个C文件都包含所有的C文件。

使用特权

评论回复
wangzsa| | 2018-6-5 11:12 | 显示全部楼层


不过就是把 xxxx 的声明区分开来嘛,
EXT xxxx

使用特权

评论回复
zhuww| | 2018-6-5 11:15 | 显示全部楼层

一个是变量的“声明”,一个是变量的“定义”,搞清楚这两者的区别,这个问题也就清楚了

使用特权

评论回复
zhanglli| | 2018-6-5 11:20 | 显示全部楼层

具体点说,
int a; // 这是一个定义,在main文件中

extern int a; // 这是一个声明,在非main文件中

如果去掉extern,连接的时候会报错:变量重复定义

使用特权

评论回复
guoyt| | 2018-6-5 11:25 | 显示全部楼层

是不是:
这样做的好处就是可以在一个h文件中定义所有C文件中使用的变量说明,然后每个C文件都包含这个h文件。

使用特权

评论回复
hanwe| | 2018-6-5 11:29 | 显示全部楼层
二楼笔误了,应该是“可以在各个h文件中定义相应C文件中使用的变量,然后每个C文件都包含所有的h文件。”
比如在a.c中#define a;
在a.h中
#ifndef a   
    #define EXT extern
#else
      #define EXT
#endif

     EXT int var1;

在b.c中#define b;
在b.h中
#ifndef b   
    #define EXT extern
#else
      #define EXT
#endif

     EXT int var2;

在a.h中定义a.c用到的变量,在b.h中定义b.c用到的变量,然后a.c和b.c都包含a.h和b.h这两个头文件。

使用特权

评论回复
llia| | 2018-6-5 11:33 | 显示全部楼层
应该是:这样做的好处就是可以在各个h文件中定义所有C文件中使用的变量说明,然后每个C文件都包含所有的h文件。

使用特权

评论回复
langgq| | 2018-6-5 11:36 | 显示全部楼层
原来各位都遇到过类似的问题,我看了谭浩强c程序设计的外部变量部分,就全明白了,大家不妨也翻翻书,或许有新的认识。

使用特权

评论回复
wangpe| | 2018-6-5 14:49 | 显示全部楼层

#include "my.h"
#ifdef   GLOBAL
#define  INIT_EXT
    const unsigned char motor_TAB[]={0x1A,0x30,0x35,0x20,0x2A,0x00,0x05,0x10};
//=================================
#else
extern const unsigned char motor_TAB[];
#define  INIT_EXT extern
#endif
//===========================================================
//================        global variable      ==============
//===========================================================
INIT_EXT  unsigned char prin_status,delay_status;
INIT_EXT  unsigned char delay_status,delay_num;
INIT_EXT  unsigned char paper_out_num;
INIT_EXT  unsigned char normal_num,error_num,flash_num;
INIT_EXT  unsigned char new_motor_code,last_motor_code;
INIT_EXT  unsigned char  new_key_code,key_code,key_count;
INIT_EXT  unsigned char Y_motor_point,W_motor_point,V_motor_point;
INIT_EXT  unsigned char motor_Y_steps,motor_up_steps,motor_down_steps;
INIT_EXT  unsigned int num_J4,num_R4,num_R8,num_J8;
INIT_EXT  unsigned int pulse_num,wash_step;
INIT_EXT  unsigned int reset_step;

struct struc
{
          unsigned keyflag:           1;
          unsigned keyflag0:           1;
          unsigned in_flag:                1;
          unsigned out_flag:                1;
          //unsigned opt_F_flag:        1;                                                //back opt sensor
          unsigned flash_flag:        1;
          unsigned wash_flag:                1;
         
};
INIT_EXT struct struc struc_flag;  


//===========================================================
//===============       function declare       ==============
//===========================================================
INIT_EXT void init(void);
INIT_EXT void port_init(void);
INIT_EXT void timer0_init(void);
INIT_EXT void timer1_init(void);
INIT_EXT void uart0_init(void);
INIT_EXT void init_devices(void);
INIT_EXT void reset(void);


//=================                key                =================
INIT_EXT void key_scan(void);
INIT_EXT void key_process(void);
这样所有文件都只要包含同一个头文件,只在某一个C文件中#define GLOBAL
对做单片机文件管理十分方便

使用特权

评论回复
zhuww| | 2018-6-5 14:51 | 显示全部楼层

其实就是这样,在一个c文件中(一般是包含main()函数的文件)先定义所有的变量,然后对于其他的c文件,因为已经定义过了,所以就是声明外部变量了。声明和定义都是在文件开头包含同一个头文件。

使用特权

评论回复
llia| | 2018-6-5 14:53 | 显示全部楼层
参与讨论一下,看到这个结构,就看想到作者是怎么用了。如,
//-----------------------------------------
//在main.c中:
#include  a.h        //声明

//在a.c中
#define   a
#include  a.h        //定义
//-----------------------------------------

使用特权

评论回复
wangpe| | 2018-6-5 14:57 | 显示全部楼层
这样做的目的可以说是偷懒吧,我个人一般不这样做的,对于程序的掌控不利。同时也可以看出来,作者的.h文件会包含其他的东西,也就是说,模块化没有彻底的干净,模块之间没有关联的东西最后不要外露,这样做是便于移植程序,也可以减少一些Bug,一般说来.h文件只包含extern 函数(外部变量可以用函数方式提供)就可以了,这个和操作系统的Api函数一样的道理。

使用特权

评论回复
langgq| | 2018-6-5 15:01 | 显示全部楼层
这样做的好处就是可以在各个h文件中定义所有C文件中使用的变量说明,然后每个C文件都包含所有的h文件

使用特权

评论回复
wangzsa| | 2018-6-5 15:04 | 显示全部楼层
这用法是跟UCOS学的呢

使用特权

评论回复
yufe|  楼主 | 2018-6-5 15:08 | 显示全部楼层

结贴了,多谢大家讨论这么多哈,呵呵

使用特权

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

本版积分规则

983

主题

10170

帖子

1

粉丝