data区范围
data区为内RAM低128字节,地址0x00~0x7F
idata区为内RAM全部256字节,地址0x00~0xFF
pdata区为外RAM低256字节,地址0x0000~0x00FF
xdata区为外RAM全部65536字节,地址0x0000~0xFFFF
code区为程序空间全部65536字节,地址0x0000~0xFFFF
指针变量的值
指针变量也是一个变量,相较普通变量存放的是数据值,指针变量存放的是其他变量的地址值。
#include "header.h"
//定义一个变量放在data区,并指定地址为0x33
data unsigned char var_data _at_ 0x33;
idata unsigned char var_idata _at_ 0x88;
pdata unsigned char var_pdata _at_ 0x0011;
xdata unsigned char var_xdata _at_ 0x0222;
code unsigned char var_code _at_ 0x4444;
//定义一个指针,该变量实际在内存中占3个字节:[指向类型][地址H][地址L]
//以下变量均可指向任何区域,为方便区分而命名
unsigned char * ptr_data;
unsigned char * ptr_idata;
unsigned char * ptr_pdata;
unsigned char * ptr_xdata;
unsigned char * ptr_code;
void main()
{
PowerInit();
ptr_data = &var_data;
//在内存中的值为: 00 00 33
ptr_idata = &var_idata;
//在内存中的值为: 00 00 88
ptr_pdata = &var_pdata;
//在内存中的值为: FE 00 11
ptr_xdata = &var_xdata;
//在内存中的值为: 01 02 22
ptr_code = &var_code;
//在内存中的值为: FF 44 44
while(1);
}
仿真结果如下:
固定指向区域的指针
#include "header.h"
//定义一个变量放在data区,并指定地址为0x31
data unsigned char var_data _at_ 0x33;
idata unsigned char var_idata _at_ 0x88;
pdata unsigned char var_pdata _at_ 0x0011;
xdata unsigned char var_xdata _at_ 0x0222;
code unsigned char var_code _at_ 0x4444;
//声明地址指向data区,在内存中占1个字节:[地址]
unsigned char data * ptr_data;
//声明地址指向idata区,在内存中占1个字节:[地址]
unsigned char idata * ptr_idata;
//声明地址指向pdata区,在内存中占1个字节:[地址]
unsigned char pdata * ptr_pdata;
//声明地址指向xdata区,在内存中占2个字节:[地址H][地址L]
unsigned char xdata * ptr_xdata;
//声明地址指向code区,在内存中占2个字节:[地址H][地址L]
unsigned char code * ptr_code;
void main()
{
PowerInit();
ptr_data = &var_data;
//在内存中的值为: 33
ptr_idata = &var_idata;
//在内存中的值为: 88
ptr_pdata = &var_pdata;
//在内存中的值为: 11
ptr_xdata = &var_xdata;
//在内存中的值为: 02 22
ptr_code = &var_code;
//在内存中的值为: 44 44
/**
* 注意:对于指针声明指向data区,同样可以用于指向idata高区;
* ptr_data = &var_idata;//该为合法赋值
* 以下等均为非法赋值,产生warning C259: '=': pointer: different mspace;
* ptr_idata = &var_pdata;
* ptr_pdata = &var_xdata;
* ptr_xdata = &var_code;
**/
while(1);
}
仿真结果如下:
声明指针的指向地址后可以减小指针变量所占用的空间,但此时必须注意只能指向声明的区域。
指针变量存放位置
以上均省略了指针变量的位置,编译器会根据实际情况放在idata区或xdata区。
在上面示例中,对于指向xdata区的指针,可以认为(unsigned char xdata *)为一个整体,如果要定义指针变量本身的存放区域,可以在 (unsigned char xdata *)前后添加区域关键词。例如
//声明地址指向xdata区,指针变量本身存放在data区,以下两种声明方式相同
data unsigned char xdata * ptr;//或
unsigned char xdata * data ptr;
//在上面基础上进一步指定ptr的存放位置为data区的0x70处
data unsigned char xdata * ptr _at_ 0x70;//或
unsigned char xdata * data ptr _at_ 0x70;
指针赋值
xdata unsigned char var _at_ 0x0000;
unsigned char * ptr;
unsigned char xdata * ptr1;
//ptr未声明指向区域只能以下两种方式赋值
ptr = &var;//或
ptr = (unsigned char xdata *)0x0000;
//ptr1已声明指向区域,除以上两种方式.还可以直接赋地址值
ptr1 = 0x0000;
指针指向的数据类型
#include "header.h"
//定义指针指向xdata区
unsigned char xdata * ptr1;
unsigned int xdata * ptr2;
unsigned long xdata * ptr3;
void main()
{
unsigned char i;
PowerInit();
//ptr1已声明指向区域,可以直接赋地址值
ptr1 = 0x0000;
for(i=0;i<4;i++){
*ptr1 = 1;//ptr1操作的是一个8位变量
ptr1++;
}
ptr2 = 0x0010;
for(i=0;i<4;i++){
*ptr2 = 2;//ptr2操作的是一个16位变量
ptr2++;
}
ptr3 = 0x0020;
for(i=0;i<4;i++){
*ptr3 = 3;//ptr3操作的是一个32位变量
ptr3++;
}
while(1);
}
仿真结果如下:
总结
最常见的指针声明就是
unsigend char *ptr;
该指针为通用指针,可以指向任何区域,如
ptr = &var_idata;
ptr = &var_xdata;
ptr = &var_code;
此时的ptr在内存中占三个字节,[指向类型][地址H][地址L]。
想节省内存空间并提高程序效率可以定义专用指针,如
unsigend char pdata *ptr;
unsigend char xdata *ptr;
此时ptr在内存中根据地址大小分配1或2个字节。
想进一步提高程序运行效率,可以定义先变在data区,在定义指针在data区,如
data unsigned char var;
data unsigned char data * ptr;
ptr = &var;
指针声明中的unsigned char等类型,表示指针指向的数据是什么类型,即指针操作的数据的类型,即(*ptr)的类型。
Over!