c语言,变量,疑惑

[复制链接]
 楼主| op2sql 发表于 2012-12-16 22:47 | 显示全部楼层 |阅读模式
同一个工程,有两个c文件uart.c和main.c.   uart.c主要是处理串口初始化,发送,接收等.main.c对串口接收的字符串进行判断,处理.
在uart.c定义了一个串口接收字符数组.char  xdata str[50].
然后在main函数也定义了一个相同的变量char xdata str[],都是全局变量.,编译器没有警告和错误,程序正常运行
为何两个变量重名编译器没有反应?
然而在main函数定义的变量里加上50;char xdata str[50];程序就提示变量多重定义;

在main.c定义char  xdata str[50].在uart.c里面声明extern char  xdata str[50].程序不能运行,keil 警告
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
什么原因?
logokfu 发表于 2012-12-16 23:20 | 显示全部楼层
没有报错,说明软件自动给你添加了extern吧。你声明了数组的长度,软件没有给你加exten就报错了。
POWTE 发表于 2012-12-16 23:37 | 显示全部楼层
在main.c定义char  xdata str[50].在uart.c里面声明extern char  xdata str[50].程序不能运行,keil 警告

改为:在uart.c里面声明extern char str[50],不要XDATA
ayb_ice 发表于 2012-12-17 08:03 | 显示全部楼层
没有外部声明,实际是两个不同变量,只是名字相同而已。。。
refee 发表于 2012-12-17 08:38 | 显示全部楼层
如果是两个不同变量 咋就不弄个不一样的名字呢 :L

评论

相同的变量  发表于 2012-12-17 18:43
uet_cache 发表于 2012-12-17 11:45 | 显示全部楼层
同意POWTE
W_Controller 发表于 2012-12-17 13:38 | 显示全部楼层
楼主,说明你应该是没有把uart.c添加到工程里面去

评论

加了啊,串口程序正常运行。  发表于 2012-12-17 18:44
zf_015820 发表于 2012-12-17 14:43 | 显示全部楼层
1、在uart.c定义了一个串口接收字符数组.char  xdata str[50].
然后在main函数也定义了一个相同的变量char xdata str[],都是全局变量.,编译器没有警告和错误,程序正常运行
-------》如同4楼所说:没有外部声明,而且,在两个不同C文件中声明,实际是两个不同变量,只是名字相同而已;还有一个就是:数组长度不一样;所以,KEIL 认为是不同的变量,不会警告,也不会出错; 如同,两个人,穿相同款式衣服(没有外部声明,如同衣服没有声明是谁的一样)一样的道理,都可以穿,也不会发生纠分;
2、在main.c定义char  xdata str[50].在uart.c里面声明extern char  xdata str[50].程序不能运行,keil 警告
---->要将uart.c文件饱含在main.c中;或者将uart.c做成一个*.H的文件饱含在main.c中,就不会出错了 ;建议:看下KEIL C51编译器的书,网上也有中文译出的,有403页,也是个热心人译的,非常不错的学习KEIL C51的资料;

评论

1 是同一个变量,main程序要处理uart程序接收字符 2 main.c包含了uart.h。  发表于 2012-12-17 18:49
yuankunli 发表于 2012-12-17 16:44 | 显示全部楼层
楼主 基本常识没弄明白吧。xdata是单片机中数据存储地点的类型,跟全局变量是两个概念。xdata有点像C语言中声明时设置静态,动态还是寄存器--以上统称为存储类型。全局extern,static局部,这些叫做作用域。请仔细搞清基本概念
lihaolongli 发表于 2012-12-17 16:59 | 显示全部楼层
你加了extern 之后就改变了数组的本来作用域,就像在同一个文件中你定义两个相同的变量,他不出重定义出什么?
 楼主| op2sql 发表于 2012-12-17 18:42 | 显示全部楼层
POWTE 发表于 2012-12-16 23:37
在main.c定义char  xdata str[50].在uart.c里面声明extern char  xdata str[50].程序不能运行,keil 警告

...

按你的方法,编译通过,无警告,无错误,明天去公司下载到板子里试试。
 楼主| op2sql 发表于 2012-12-17 18:42 | 显示全部楼层
ayb_ice 发表于 2012-12-17 08:03
没有外部声明,实际是两个不同变量,只是名字相同而已。。。

是同一个变量,如果两个不同的变量,程序不可能正常运行的。
W_Controller 发表于 2012-12-17 18:53 | 显示全部楼层
楼主还是再检查一下有没有把uart.c添加到工程里去。一般出现这种警告都是太粗心,或者是新手,忘了把.C文件添加到工程里面去的。如果你有添加进去,在不同的.C文件中声明同一类型的全局变量或者你所说的数组,keil是编译不过的。至于你说的uart.c文件用char  xdata str[50],而main用char  xdata str[ ],这个确实能编译过去,这点原因可能就是9楼所说的“长度不一样,keil认为变量不一样”。
吾要单片机 发表于 2012-12-17 19:02 | 显示全部楼层
英文打错了吧,EXTERN
明月小厨 发表于 2012-12-17 21:13 | 显示全部楼层
全局的意思并非从头到尾整个工程在什么地方都可以看的见,全局也的可见性的;
lzqxs89 发表于 2012-12-17 23:04 | 显示全部楼层
op2sql 发表于 2012-12-17 18:42
按你的方法,编译通过,无警告,无错误,明天去公司下载到板子里试试。 ...

支持三楼的解释。
lzqxs89 发表于 2012-12-17 23:06 | 显示全部楼层
op2sql 发表于 2012-12-17 18:42
是同一个变量,如果两个不同的变量,程序不可能正常运行的。

应该是两个不同的变量,除非编译器自动加了 extern;
你检查下你有没有在程序里面 把其中一个赋值到 另外一个;
zf_015820 发表于 2012-12-18 09:52 | 显示全部楼层
LZ运行了后,结果怎样?

评论

按三楼方法,成功运行。  发表于 2012-12-19 00:03
zf_015820 发表于 2012-12-19 10:00 | 显示全部楼层
呵,那变量的类型就会自动分配存储区了,我估计你是用SMALL模式,则自动将这个数组变量区分配在DATA区了,呵,这个,你可以查看下LST文件;如果你程序比较小,用的变量少,可以这样做;如果程序大,用的变量多,估计程序可能会运行出问题,因为,DATA区内的堆栈区,可能不够用;呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:活着就是为了电子

2

主题

209

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部