Chinaunix首页 | 论坛 | 博客
  • 博客访问: 54411
  • 博文数量: 29
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 300
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-30 13:50
文章分类

全部博文(29)

文章存档

2011年(1)

2009年(28)

我的朋友

分类:

2009-05-15 16:07:08

一.  指针变量的定义

指针变量定义与一般变量的定义类似,其形式如下:

数据类型 [存储器类型1] * [存储器类型2] 标识符;

[存储器类型1] 表示被定义为基于存储器的指针,无此选项时,被定义为一般指针。这两种指针的区别在于它们的存储字节不同。一般指针在内存中占用三个字节,第一个字节存放该指针存储器类型的编码(由编译时由编译模式的默认值确定),第二和第三字节分别存放该指针的高位和低位地址偏移量。存储器类型的编码值如下:

 

存储类型I

Idata/data/bdata

xdata

pdata

Code

编码值

0x00

0x01

0xFE

0xFF

 

[存储类型2]用于指定指针本身的存储器空间。

1.  char * c_ptr;  int * i_ptr;  long * l_ptr;

上述定义的是一般指针,c_ptr指向的是一个char型变量,那么这个char型变量位于哪里呢?这和编译时由编译模式的默认值有关,

如果Menory ModelVariableLarge:XDATA,那么这个char型变量位于xdata区:

如果Menory ModelVariableCompact:PDATA, 那么这个char型变量位于pdata 区:

如果Menory Model——Variable——Small:DATA,那么这个char型变量位于data区。

而指针c_ptr i_ptr l_ptr变量本身位于片内数据存储区中。

2.    char *  data c_ptr;  int *  idata i_ptr;  long * xdata l_ptr;

上述定义,c_ptr i_ptr l_ptr变量本身分别位于data idataxdata区。

3.    char data * c_ptr;  //表示指向的是data区中的char型变量,c_ptr在片内存储区中;

int  xdata * i_ptr;  //表示指向的是xdata区中的int型变量,i_ptr在片内存储区中;

long code * l_ptr;  //表示指向的是code区中的long型变量,l_ptr在片内存储区中;

4.    char data * data c_ptr;  //表示指向的是data区中的char型变量,c_ptr在片内存储区data中;

Int  xdata * idata i_ptr; //表示指向的是xdata区中的int型变量,i_ptr在片外存储区xdata中;

long  code * xdata  l_ptr; //表示指向的是code区中的long型变量,l_ptr在片内存储区xdata中;

二.  指针应用

1.      int x, j;

int * px, *py;

px=&x;  py=&y;

2.      *px=0;  py=px;

3.      *px++<=>*(px++)

4.      (*px)++<=>x++

5.      unsigned char xdata * x;

unsinged char xdata * y;

x=0x0456;  

*x=0x34   //等价于 mov dptr,#456h ; mov a,#34h; movx @dptr,a

6.      unsigned char pdata * x;

x=0x045;  

*x=0x34   //等价于 mov r0,#45h ; mov a,#34h; movx @r0,a

7.      unsigned char data * x;

x=0x30;  

*x=0x34   //等价于 mov a,#34h; mov 30h ,a

8.      int *px;

        px=(int xdata *)0x4000;   // xdata 型指针 0x4000 赋给 px,也就是将0x4000强制转换为指向xdata区中的int型变量的指针,将其赋给px

9.      int x

x=*((char xdata *)0x4000); //0x4000强制转换为指向xdata区中的int型变量的指针,从这个地址中取出值赋给变量x

10.  px=*((int xdata * xdata *)0x4000); //如何分析?

11.     px=*((int xdata * xdata *)0x4000);将阴影部分遮盖,这个意思就是将0x4000强制转换为指向xdata区中的X型变量的指针,这个X型变量就是阴影“int xdata *,也就是0x4000指向的变量类型是一个指向xdata区中的int型变量的指针,即0x4000中放的是另外一个指针,这个指针指向的是xdata区中的int型变量。Px值放的是0x4000中放的那个指针。比如【0x4000】—【0x2000】-0x34Px0x2000

12.  x=**((int xdata * xdata *)0x4000);  x中放着0x4000中放的那个指针所指向的值。比如【0x4000】—【0x2000】-0x34

二.  指针与数组

1.      int arr[10];

int * pr;

pr=arr;     //  等价于pr&arr[0];

              这样的话,*(pr+1)==arr[1]; *(pr+2)==arr[2]; *(arr+3)==arr[3]; *(arr+4)==arr[4];

              或者  pr[0],pr[1]….代表 arr[0],arr[1]…..

可以*pr++ (等价于*(pr++)),来访问所有数组元素,而*arr++是不行的。因为arr是常量,不能++运算

2.      char * s1

char code str[]=”abcdefg”

s1=str;

       3.  char *s1=”abcdefg”;

三.  指针与结构体

1.typedef struct _data_str {

        unsigned int DATA1[10];
        unsigned int DATA2[10];
        unsigned int DATA3[10];
        unsigned int DATA4[10];
        unsigned int DATA5[10];
        unsigned int DATA6[10];
        unsigned int DATA7[10];
        unsigned int DATA8[10];
}DATA_STR;
 
//开辟一个外RAM空间,确保这个空间够装你所需要的
xdata uchar my_data[MAX_STR] _at_ 0x0000;     
DATA_STR *My_Str;
My_Str=(DATA_STR*)my_data;    //把你的结构体指针指向这个数组的开头
 
以后的操作就这样:
My_Str->DATA1[0]=xxx;
My_Str->DATA1[1]=xxx;
那么你的变量就自然放到XDATA中去了.
注意定义的my_data[MAX_STR],不能随便被操作,它只是开始的时候用来开辟内存用的.

       2.   struct student

              {

                     char name[20];

                     int num

}stu1,stu2;

       3.   struct student

              {

                     char name[20];

                     int num

};

struct student stu1,stu2;

struct student *p;

p=&stu1;

访问成员方法:

A.          stu1.num

B.           (*p).num;    //因为“.”的优先级高于“*”所以要加括号。

C.          P->num;

4.  struct student stu[10];

   struct student * p;

   p=stu;

四.  指针与函数

指向函数的指针

定义方法: 类型说明符  * 指针变量名)(形参列表)

A .     int max(int x,int y);

    int (*fun) (int ,int )

    则可以这样调用 funmax

B .     int add(int x,int y)

    { return x+y;}

    int sub(int x,int y)

    { return x-y;}

    Main()

    {

        int x,y,c; char z

        int (*p)(int,int);

        while(1)

        {

           print(“intput the first \n”);

           scanf(“d%”,&x);

           print(“intput the second \n”);

           scanf(“d%”,&y);

           print(“choice operation: 1: +;2:- \n”);

           scanf(“d%”,&z);

           switch(z)

           {

                  case:1: p=add;break;

                  case:2: p=sub;break;

}

}

}

C. #define ubyte unsigned char

#define uint unsigned int

#define ulong unsigned long

ubyte kbCode; // 按键编码纪录

ubyte kbStatus; // 键盘当前状态,可以理解为菜单层次
//
按键的四种不同工作状态对应的函数指针对照表,每三字节对应一个按键

// 每一项包含三个字节,分别代表按键码,键盘状态,对应处理程序编号

// 本表对应于日常操作,不是修改状态

ubyte code TAB0[46]={
0x11,0x00,0x01, //
按键'1' func1

0x12,0x00,0x01, // 按键'2' func1

0x14,0x00,0x01, // 按键'3' func1

0x1a,0x00,0x01, // 按键'4' func1

0x2a,0x00,0x01, // 按键'5' func1

0x4a,0x00,0x01, // 按键'6' func1

0x01,0x00,0x01, // 按键'7' func1

0x02,0x00,0x01, // 按键'8' func1

0x04,0x00,0x01, // 按键'9' func1

0x10,0x00,0x01, // 按键'0' func1

0x20,0x00,0x01, // 按键'.' func1

0x08,0x00,0x02, // 按键'Clear' func2

0x18,0x00,0x03, // 按键'U/D' func3

0x8a,0x01,0x04, // 按键'shift' func4

0x40,0x02,0x05, // 按键'last' func5

0x00}; // 本表结束标志

 

ubyte code TAB1[40]={

0x12,0x03,0x06, // 按键'2' func6

0x14,0x03,0x07, // 按键'3' func7

0x2a,0x03,0x08, // 按键'5' func8

0x4a,0x03,0x09, // 按键'6' func9

0x01,0x03,0x12, // 按键'7' func18

0x8a,0x03,0x14, // 按键'shift' func20

0x11,0x01,0x0a, // 按键'1' func10

0x1a,0x01,0x0b, // 按键'4' func11

0x04,0x01,0x0c, // 按键'9' func12

0x10,0x01,0x0d, // 按键'0' func13

0x80,0x01,0x0e, // 按键'Enter' func14

0x08,0x00,0x02, // 按键'Clear' func2

0x20,0x03,0x13, // 按键'.' func19

0x00}; // 本表结束标志

 

ubyte code TAB2[7]={

0x40,0x02,0x0f, // 按键'last' func15

0x08,0x00,0x02, // 按键'Clear' func2

0x00}; // 本表结束标志

 

ubyte code TAB3[40]={

0x11,0x03,0x10, // 按键'1' func16

0x12,0x03,0x10, // 按键'2' func16

0x14,0x03,0x10, // 按键'3' func16

0x1a,0x03,0x10, // 按键'4' func16

0x2a,0x03,0x10, // 按键'5' func16

0x4a,0x03,0x10, // 按键'6' func16

0x01,0x03,0x10, // 按键'7' func16

0x02,0x03,0x10, // 按键'8' func16

0x04,0x03,0x10, // 按键'9' func16

0x10,0x03,0x10, // 按键'0' func16

0x20,0x03,0x10, // 按键'.' func16

0x08,0x00,0x02, // 按键'clear' func2

0x80,0x01,0x11, // 按键'Enter' func17

0x00}; // 本表结束标志

 

ubyte code *TAB[4]={TAB0,TAB1,TAB2,TAB3}; // 总指针表

 

// 指针函数列表

code void(code *KeyProcTab[])()={

NoKey, /*0# (00H)#*/

func1, /*1# (01H)#*/

func2, /*2# (02H)#*/

func3, /*3# (03H)#*/

func4, /*4# (04H)#*/

func5, /*5# (05H)#*/

func6, /*6# (06H)#*/

func7, /*7# (07H)#*/

func8, /*8# (08H)#*/

func9, /*9# (09H)#*/

func10, /*10# (0AH)#*/

func11, /*11# (0BH)#*/

func12, /*12# (0CH)#*/

func13, /*13# (0DH)#*/

func14, /*14# (0EH)#*/

func15, /*15# (0FH)#*/

func15, /*15# (0FH)#*/

func16, /*16# (10H)#*/

func17, /*17# (11H)#*/

func18, /*18# (12H)#*/

func19, /*19# (13H)#*/

func20 /*20# (14H)#*/

};

 

void NoKey()

{

return;

}

 

void func0()

{

;

}

void func1()

{

;

}

....................

void func20()

{

;

}

//////////////////////////////////////////////////////////////////////

// 键盘监控,根据当前状态特征指向不同的指针表,并调用相应的函数 //

//////////////////////////////////////////////////////////////////////

void mon(ubyte key)

{

ubyte code *data pTab;

kbCode=key;

pTab=*(TAB+kbStatus); // 根据当前状态特征指向分指针表

while(*pTab != key && *pTab != 0) // 按照按键代码查表

{

pTab += 3; // 查表

}

if(*pTab!=0){

pTab++;

kbStatus=*pTab; // 取状态特征字节

pTab++; // 指向执行函数

(*KeyProcTab[*pTab])(); // 指针函数调用

}

}

 

转自:

http://www.mcublog.com/blog/user1/3547/archives/2006/15756.html

阅读(542) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~