KEIL C51 库函数 疑问

2020-01-23 14:49发布

在此发出疑问,有两个作用:
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)

请各位老师帮助解答 上两则代码中注释的两栏有什么区别?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
mail2li
1楼-- · 2020-01-23 16:40
#define NULL ((void *)0)
你的问题有两个
1. 先搞清楚NULL空指针的含义 已经他和0的关系
2. C51对指针有一些特别的定义 我记得是根据类型会有一些特别的标记 具体你可以看看C51的自带的文档
csmjmcc
2楼-- · 2020-01-23 21:11
 精彩回答 2  元偷偷看……
sgj245609615
3楼-- · 2020-01-23 21:15
学习下                 
csmjmcc
4楼-- · 2020-01-24 01:18
本帖最后由 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是否亦隐藏如此问题??

鸣谢各位导师指导,指正!
csmjmcc
5楼-- · 2020-01-24 05:08
本帖最后由 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.

一周热门 更多>