c语言与C51单片机的一些问题

C51中#define与sfr的定义有什么不同.主要想通过指针得到I/O口地址.下例为什么不行?

c51中用的是Keil uVision2软件

#include <89x51x.h> //89x51x.h中有定义sfr P0 =0x80
#define JAVE 0X81
main()
{
char *p;
p=P0; //不通过
P=JAVE; //能通过
}

请查看头文件名<89x51x.h>有没有输入错,好像没这个头文件。
当头文件名有错时,编译时,会有can't open fine '89x51x.h' 提示。请更正头文件名即可。
具体的头文件可在你安装的目录下查看,比如C:\Program Files\Keil\C51\INC\Atmel
或者用最常用的<reg52.h>或<at89x51.h>试试。追问

可以用的,头文件/reg52.h> 与基本相同.位定义的写法可能有点不同.这几个头文件都用过.主要想通过指针得到I/O口地址

追答

我查看了一下资料。
在c51中,sfr预定义的标识名与“绝对地址”联系起来。它是一个“特殊”功能寄存器。特殊在这个名称既代表着一个字节的首地址名,又代表一个字节的变量名。
所以80c51中规定:专用的特殊功能寄存器(包括bit、sbit、sfr和sfrl6数据类型),不能通过指针进行访问!!!
所以你这样操作,编译时就会报错。

sfr的寄存器名称必须大写,定义之后可以直接对这些寄存器赋值。
因为他有预定义的绝对地址,在实际工程中,这种操作也用不到。实在想知道,就到头文件中看一下就知道了。

关于宏定义#define,就是完全“替换”,所以#define后面不能有“;”,否则,将“;”也会一起带进去,这样就出现错误。这里无需多述,想你肯定明白。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-06-01
#define 定义相当于是替代,比如 #define jave 0x80;在编译的时候,等于是把所有jave都替换成了0x80;编译的时候是把0x80作为一个常数来用而不是地址,如 P=jave 等效于 P=0x80;
sfr 定义的是地址,如定义P0=0x80;在编译的时候P0是作为一个地址来使用,于是,P=P0 并不能等效于 P=0x80;
在你的程序中,p是作为一个指针用的,而P0作为地址,那P=P0就是把一个指针指向一个变量,由于变量里面的数据是不定的,所以这样的操作不成立。
简单的举个例子吧,你那个P=P0就等同于下面的例子:
unsigned char tmp;
char *p
p=tmp;
这样的写法就是错的,指针只能指向地址,不能指向变量。
相似回答