搜索
bottom↓
回复: 5

KEIL C51 库函数 疑问

[复制链接]

出0入0汤圆

发表于 2014-4-22 15:54:34 | 显示全部楼层 |阅读模式
在此发出疑问,有两个作用:
1、帮助本人解答问题。
2、也给菜鸟们提个醒,别走弯路。
问题是:
        错误代码如下:

        char *head, *tail;
       
        head = strstr(dat_ptr, "{TER,G1,");
        if(head == 0) return FALSE;              //这里总是返回 实际dat_ptr中数据是有涵盖“{TER,G1,”的

        正确代码如下:

        char *head, *tail;
       
        head = strstr(dat_ptr, "{TER,G1,");
        if(head == NULL) return FALSE;        //库函数中定义 #define NULL ((void *) 0L)

请各位老师帮助解答 上两则代码中注释的两栏有什么区别?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2014-4-23 10:59:16 | 显示全部楼层
#define NULL ((void *)0)
你的问题有两个
1. 先搞清楚NULL空指针的含义 已经他和0的关系
2. C51对指针有一些特别的定义 我记得是根据类型会有一些特别的标记 具体你可以看看C51的自带的文档

出0入0汤圆

 楼主| 发表于 2014-4-23 15:09:51 | 显示全部楼层
谢谢回复!
1、先前,在ARMCC  及GCC 同是如此:if(head == 0) return FALSE; 没啥问题。 于是乎,直接搬移到C51,结果程序跟踪发现在C51中出问题了。
2、试图探个究竟,查看编译代码,因难以读懂,故而弃之。将NULL与当前的指针值打印出来,结果如下: NULL为 i:0000 head为 x:0000.  这两项结果表示啥意思,搞不懂!
3、或许不同系统NULL有不同的值,但我们仅从C51系统下看问题,NULL 指向是否为0?

出0入0汤圆

发表于 2014-4-23 15:57:35 | 显示全部楼层
学习下                 

出0入0汤圆

 楼主| 发表于 2014-4-24 09:18:51 | 显示全部楼层
本帖最后由 csmjmcc 于 2014-4-24 10:01 编辑

探究一番,陈述如下,以求看官批评指正:
1、我们知道,C51函数返回一般指针时,为R3,R2,R1.其中R3-存放的是存储类型值。存储类型值有DATA/IDATA=0X00、XDATA=0X01...(其他不在此赘述)。

2、且看编译代码:  
385: static bit rec_deal(const Uchar *dat_ptr)
   386: {
   387:         int  len;
   388:         char *head, *tail;
   389:         
   390:         head = strstr(dat_ptr, "{TER,G1,");
C:0x038A    7543FF   MOV      0x43,#0xFF
C:0x038D    75440E   MOV      0x44,#0x0E
C:0x0390    75454A   MOV      0x45,#0x4A
C:0x0393    1208DF   LCALL    strstr(C:08DF)
C:0x0396    8B3A     MOV      0x3A,R3
C:0x0398    8A3B     MOV      0x3B,R2
C:0x039A    893C     MOV      0x3C,R1
   391:         if(head == NULL) return FALSE;
   392:  
C:0x039C    E9       MOV      A,R1       //这里R3,R2,R1均参与运算,查看返回是否为0.        
C:0x039D    4A       ORL      A,R2
C:0x039E    4B       ORL      A,R3
C:0x039F    7002     JNZ      C:03A3
C:0x03A1    C3       CLR      C
C:0x03A2    22       RET      

385: static bit rec_deal(const Uchar *dat_ptr)
   386: {
   387:         int  len;
   388:         char *head, *tail;
   389:         
   390:         head = strstr(dat_ptr, "{TER,G1,");
C:0x038A    7543FF   MOV      0x43,#0xFF
C:0x038D    75440E   MOV      0x44,#0x0E
C:0x0390    75454D   MOV      0x45,#0x4D
C:0x0393    1208E2   LCALL    strstr(C:08E2)
C:0x0396    8B3A     MOV      0x3A,R3
C:0x0398    8A3B     MOV      0x3B,R2
C:0x039A    893C     MOV      0x3C,R1
   391:         if(head == 0) return FALSE;
   392:  
C:0x039C    AE02     MOV      R6,0x02  //0x02亦即0区 R2
C:0x039E    AF01     MOV      R7,0x01  //0x01亦即0区 R1      而在这里仅 R2 R1参与运算 查看返回是否为0.
C:0x03A0    EF       MOV      A,R7
C:0x03A1    4E       ORL      A,R6
C:0x03A2    7002     JNZ      C:03A6
C:0x03A4    C3       CLR      C
C:0x03A5    22       RET      

3、结论:当 if(head == 0) 时,R3-存储类型将忽略它,本语句视为存储类型为data/idata.
              当if(head == NULL)时,R3-存储类型不可忽略,因NULL已明确定义为void*型。
              故 if(head == 0)与 if(head == NULL)两语句在C51中是不同的含义,不可轻视之。

4、留下的疑虑: ARMCC是否亦隐藏如此问题??

鸣谢各位导师指导,指正!

出0入0汤圆

 楼主| 发表于 2014-4-24 09:26:41 | 显示全部楼层
本帖最后由 csmjmcc 于 2014-4-24 10:03 编辑
csmjmcc 发表于 2014-4-23 15:09
谢谢回复!
1、先前,在ARMCC  及GCC 同是如此:if(head == 0) return FALSE; 没啥问题。 于是乎,直接搬移 ...


这里补充:
          打印用 printf("HEAD: %p", head); 语句
         现在明白打印的结果:X:0000 -----指的是 在XDATA区 指针值为 0000.  i:0000 ------指的是 在 DATA/IDATA区 指针值为 0000.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:38

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表