打印

unsigned char xdata *p;和xdata unsigned char *p区别

[复制链接]
13436|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zyboy|  楼主 | 2009-5-19 11:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
古道热肠| | 2009-5-19 12:04 | 只看该作者

当然有差别的呀!

unsigned char xdata *P说明指针指向的对象是一个处于Xdata的元素,比如数组.
xdata unsigned char *p表明指针本身位于Xdata,至于指向什么类型的地址,自由变换.

使用特权

评论回复
板凳
古道热肠| | 2009-5-19 12:06 | 只看该作者

(*P)++与(*P++)也是有差别的

指针是C语言的精华元素.

使用特权

评论回复
地板
HWM| | 2009-5-19 12:13 | 只看该作者

指针是C语言的“糟糕”元素,若处理不好的话,呵呵。

使用特权

评论回复
5
zyboy|  楼主 | 2009-5-19 12:17 | 只看该作者

回二楼,

那你意思是说 unsigned char * xdata p 和xdata unsigned char *p是一个意思吗?谢谢!

使用特权

评论回复
6
computer00| | 2009-5-19 12:42 | 只看该作者

晕...原来把xdata放前面是这个意思了...

使用特权

评论回复
7
刘前辈| | 2009-5-19 13:52 | 只看该作者

5楼正解。

C语言指针说明以 * 为分隔符,

“*” 前面的存储类型修饰—指针所指向的对象数据的存储位置;
“*” 后面的存储类型修饰—指针本身所分配的存储位置。

所以unsigned char xdata *p; 和xdata unsigned char *p   不一样。说明的是2回事。

而:
xdata unsigned char *p; 和 unsigned char  * xdata p; 完全一样。

因为C写法中允许“最前面的存储类型修饰符修饰最后面的对象。”

且看下面示例程序证明:

; unsigned char xdata * p0;

; xdata unsigned char * p1 ;   

; uchar  a=0x20; 
;
; void main()    
;{
;  p0=&a;
;  p1=&a;
;}



NAME    POINTER

?PR?main?POINTER     SEGMENT CODE 
?C_INITSEG           SEGMENT CODE 
?DT?POINTER          SEGMENT DATA 
?XD?POINTER          SEGMENT XDATA 
    EXTRN    CODE (?C_STARTUP)
    PUBLIC    a?
    PUBLIC    p1
    PUBLIC    p0
    PUBLIC    main

    RSEG  ?DT?POINTER
             p0:   DS   2       //p0指针被定义在data区。
             a?:   DS   1

    RSEG  ?XD?POINTER
             p1:   DS   3     //p1指针被定义到到xdata区。


    RSEG  ?C_INITSEG
    DB    001H
    DB    a?
    DB    020H

; #pragma  src

 

    RSEG  ?PR?main?POINTER
main:
            ; SOURCE LINE # 11
; {
            ; SOURCE LINE # 12

; p0=&a;
            ; SOURCE LINE # 14
    MOV      p0,#HIGH (a?)
    MOV      p0+01H,#LOW (a?)      //p0-2字节指针立即寻址
; p1=&a;
            ; SOURCE LINE # 15
    MOV      DPTR,#p1
    CLR      A
    MOVX     @DPTR,A
    INC      DPTR
    MOV      A,#HIGH (a?)
    MOVX     @DPTR,A
    INC      DPTR
    MOV      A,#LOW (a?)
    MOVX     @DPTR,A        //p1-3字节通用指针间接寻址。
;  
; }
            ; SOURCE LINE # 17
    RET      
; END OF main

    END

使用特权

评论回复
8
刘前辈| | 2009-5-19 13:56 | 只看该作者

xdata unsigned char * p0; 和unsigned char *xdata p0;一样

NAME    POINTER

?PR?main?POINTER     SEGMENT CODE 
?C_INITSEG           SEGMENT CODE 
?XD?POINTER          SEGMENT XDATA 
?DT?POINTER          SEGMENT DATA 
    EXTRN    CODE (?C_STARTUP)
    PUBLIC    a?
    PUBLIC    p1
    PUBLIC    p0
    PUBLIC    main

    RSEG  ?XD?POINTER
             p0:   DS   3
             p1:   DS   3      //p0、p1均定义到xdata区,3字节通用指针。

    RSEG  ?DT?POINTER
             a?:   DS   1

    RSEG  ?C_INITSEG
    DB    001H
    DB    a?
    DB    020H

; #pragma  src

; #define uchar unsigned char

; xdata unsigned char  * p0;

;  unsigned char * xdata p1 ;   

; uchar  a=0x20; 

; void main()    

    RSEG  ?PR?main?POINTER
main:
    USING    0
            ; SOURCE LINE # 11
; {
            ; SOURCE LINE # 12

; p0=&a;
            ; SOURCE LINE # 14
    MOV      DPTR,#p0
    CLR      A
    MOVX     @DPTR,A
    INC      DPTR
    MOV      A,#HIGH (a?)
    MOVX     @DPTR,A
    INC      DPTR
    MOV      A,#LOW (a?)
    MOVX     @DPTR,A
; p1=&a;
            ; SOURCE LINE # 15
    MOV      R1,A
    INC      DPTR
    CLR      A
    MOVX     @DPTR,A
    INC      DPTR
    MOV      A,#HIGH (a?)
    MOVX     @DPTR,A
    INC      DPTR
    MOV      A,R1
    MOVX     @DPTR,A          // p0、p1都是3字节通用指针间接寻址。完全一样。
;  
; }
            ; SOURCE LINE # 17
    RET      
; END OF main

    END

使用特权

评论回复
9
iciciu| | 2009-5-19 13:58 | 只看该作者

应该没区别

unsigned char xdata *p; 和xdata unsigned char *p 完全一样。



使用特权

评论回复
10
zyboy|  楼主 | 2009-5-19 17:17 | 只看该作者

谢谢“牛”前辈呀

unsigned char xdata * p0;     //P0指针放在data ,数据放在xdata
 
xdata unsigned char * p1 ;    //P1指针放在xdata ,数据放在???(是根据后面变量位置变化??) 


unsigned char  a=0x20;       //a(D:0x0A)=0x20
unsigned char b,c; 

void main()    
{
  p0=&a;   //KEIL提示警告:由于a变量是放在data中,p0指向数据放在xdata
  p1=&a;

  b =*p0;    //b不等于0x20,果然出错 原因程序跑到xdata去取数据了(尽管相对地址都是0x0A)
  c = *p1;     //C正确

  while(1);
}
是这样分析吗?谢谢古道热肠和牛前辈!!!

使用特权

评论回复
11
古道热肠| | 2009-5-21 16:07 | 只看该作者

回楼主,您的分析是对的

通常不要指定指针指向的对象的类型,想想,C51单片机有XDAT,有IDATA,有CODE,,指定变量指向的数据的位置是为了提高速度.
unsigned char Xdata *P,此时P是只能指向外部SRAM了,*P++从SRAM中取数或存数都能取得最高的效率.反编译一下就能看到效果的.

使用特权

评论回复
12
王紫豪| | 2009-5-21 16:19 | 只看该作者

支持!

使用特权

评论回复
13
badbird1234| | 2009-5-21 17:22 | 只看该作者

这也行呀

我一直认为是一个鸟样那
unsigned char * xdata p 和xdata unsigned char *p
为什么不unsigned char *xdata p
这样不好理解点吗

使用特权

评论回复
14
刘前辈| | 2009-5-21 21:37 | 只看该作者

不一定容易理解。

咱瞎侃:俺就觉得 * 指针符应该最靠近它说明的名字好理解。所以

unsigned char * xdata p ;  //就觉得后面拖泥带水。

如果:
 char * xdata p[100];     //是不是不如 :
 xdata  char *p[100];      //清晰?

本着“最前面的存储类型修饰最后面的变量”的原则。

当然2者都是正确的,也许个人习惯不同。

使用特权

评论回复
15
highgear| | 2009-5-21 21:58 | 只看该作者

一个简单的小技巧:一个中心,两个基本点,左右看

unsigned char xdata *p
一个中心:p 变量。
右看:没有了。
左看:*,p 是指针。
再左看 xdata :p是一个指向xdata 的指针 
再左看 unsigned char: 指针类型是 unsigned char.
unsigned char xdata *p 说明 p是一个指向xdata 的unsigned char指针

xdata unsigned char *p:
同理:xdata 修饰 unsigned char * :说明指针在xdata.


运用这种技巧,注意修饰对象,再长,再复杂的定义语句也不用害怕。

使用特权

评论回复
16
highgear| | 2009-5-21 22:18 | 只看该作者

同理:unsigned char * xdata p[100];

右看[100]:p 是一个有100元素的数组。
再右看: 没有了.

左看 xdata: p[100] 是 xdata, 说明p[100] 在 xdata
再左看*: 哦,指针,不是说 p 是指针,而是p[100]是指针,即100个指针的数组。 * 修饰 p[100]
再左看unsigned char: 这100个指针类型是unsigned char。

使用特权

评论回复
17
ayb_ice| | 2009-5-21 22:58 | 只看该作者

KEIL已经不推荐使用xdata unsigned char *p了

使用特权

评论回复
18
zyboy|  楼主 | 2009-5-22 08:36 | 只看该作者

const char *p 和char const *p是一样的吧

按16楼解释这个好像不行吧?反正搞晕了?看来只能用“最前面的存储类型修饰最后面的变量”原则了

使用特权

评论回复
19
highgear| | 2009-5-22 20:52 | 只看该作者

const char *p 和char const *p是一样的

那个小技巧,实际上就是编译器处理的过程,所以不会有错。

char 只是类型说明,实际上与代表一个地址的 * 无关,地址只是一个数,类型说明只有在地址被编译器使用时才有意义。

const char *p 与 const *p 中的const都是修饰 *。

使用特权

评论回复
20
crc_2013| | 2014-5-16 16:31 | 只看该作者
帖子很有帮助,谢谢各位大神!

使用特权

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

本版积分规则

101

主题

356

帖子

0

粉丝