KEIL C51 库函数 疑问
在此发出疑问,有两个作用: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)
请各位老师帮助解答 上两则代码中注释的两栏有什么区别? #define NULL ((void *)0)
你的问题有两个
1. 先搞清楚NULL空指针的含义 已经他和0的关系
2. C51对指针有一些特别的定义 我记得是根据类型会有一些特别的标记 具体你可以看看C51的自带的文档
谢谢回复!
1、先前,在ARMCC及GCC 同是如此:if(head == 0) return FALSE; 没啥问题。 于是乎,直接搬移到C51,结果程序跟踪发现在C51中出问题了。
2、试图探个究竟,查看编译代码,因难以读懂,故而弃之。将NULL与当前的指针值打印出来,结果如下: NULL为 i:0000 head为 x:0000.这两项结果表示啥意思,搞不懂!
3、或许不同系统NULL有不同的值,但我们仅从C51系统下看问题,NULL 指向是否为0?
学习下 本帖最后由 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: intlen;
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: intlen;
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 于 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.
页:
[1]