51单片机函数指针问题
#include <stc8h.h>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char xdata mempool; //声明一个512字节的数组
typedef struct _num {
char text;
void (*setnum)(void*, char*);
}_num;
_num *num1;
void setnum(_num *num,char*str)
{
int i;
for(i = 0; i <100; i++)
{
num->text = *(str+i);
if (*(str + i) == '\0')
break;
}
}
_num* Creat_num()
{
_num* num = (_num*)malloc(sizeof(_num));
num->setnum = setnum;
return num;
}
voidmain()
{
init_mempool (&mempool, sizeof(mempool)); //初始化动态内存分配空间
num1 = Creat_num();//创建一个对象num1
num1->setnum(num1, "fdsfudsuifgsd\n");//通过setnum函数上设置text中的字符
printf("%s", num1->text); //在单片机上面用TFT显示屏显示
num1->setnum(num1, "wo shi rao ling yun o!!!\n");
printf("%s", num1->text);
}
这段代码在VS上运行是可以的,但是在51单片机上面就不能用,在单片机上不能通过num1->setnum(num1, "fdsfudsuifgsd\n")这种方式改变text[]的值,通过该函数过后text中的字符是乱码的,如果不通过指针去调用(num1->setnum(_num *num,char*str))的话单片机就可以正常运行(直接调用setnum(_num *num,char*str)字符显示正常)。在网上也查询了相应的资料,看得云里雾里的,还是没能解决,请各位坛友帮我解决一下,已经卡在这里半个多月了,麻烦大家了。另外51单片机是可以用动态内存分配的哦 通过这个函数init_mempool (&mempool, sizeof(mempool)); 就可以进行动态内存分配。
小弟先在这里谢谢大家。
本帖最后由 xxxevery 于 2024-6-25 01:12 编辑
值得研究一下 单片机动态分配内存一般用大数组的形式,如果是51的话还要考虑访问方式 这程序绕来绕去的,玩的挺花呀。
你用啥编译的,这能编译通过?
num->text = *(str+i);
是否应该为
num->text = *(str+i);
另外,C51尽量不要用函数指针,和标准C相比,有很多限制。
1. 不要使用函数指针;
2. 如果用函数指针,不要传递参数,参数可以使用全局变量啥的代替;
3. 使用函数指针还想传递参数,必须使用寄存器传递,参数的类型和数量有限制。
num1->setnum(num1, "fdsfudsuifgsd\n");
这句用函数指针间接调用,并且参数还是两个通用指针,超出寄存器所能传递参数限制,编译会出错的。
寄存器传递参数,char型最多3个,如果双字节类型最多也是3个,long或float类型最多一个,通用指针(占3字节)最多一个。
改成直接调用函数,就没有参数数量限制了,除了可以用寄存器传递,还可以使用固定内存地址传递。
如果你用C51开发,我建议程序里不要搞这么多招式,老老实实用C的基本功能就好。
这段程序,如果一定要这么写,把所有用到的指针都改为指定存储类型的指针,这样指针变量占2字节,传递参数应该能放入寄存器了,试试看能不能编译通过。
学习了 health 发表于 2024-6-25 09:04
这程序绕来绕去的,玩的挺花呀。
你用啥编译的,这能编译通过?
谢谢你的解答,我的目的是想用面向对象的思想写一个用于51单片机的GUI库,这要写起来比较简单点儿,结果就卡在这个地方了,你还有没有更好的方式来解决这个问题呢?num->text = *(str+i);是该这样的,不知道为啥粘贴上去后面的中括号就没有了。我根据你的思路我重新写了一下。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _obj {
char id;
char x;
char y;
}_obj;
typedef struct _num {
_obj *obj;
char text;
void (*setnum)(void*, char*);
}_num;
void setnum(_num *num,char*str)
{
int i;
for(i = 0; i <100; i++)
{
num->text = *(str+i);
if (*(str + i) == '\0')
break;
}
}
voidCreat_num(_num *num)
{
//_num* num = (_num*)malloc(sizeof(_num));
num->setnum = setnum;
}
_obj *obj;
int main()
{
_num num1;
_num num2;
_num num3;
Creat_num(&num1);
setnum(&num1, "woshiraolingyun");
Creat_num(&num2);
setnum(&num2, "woshiliukun");
Creat_num(&num3);
setnum(&num3, "woshirakey");
obj = &num1;
obj = &num2;
obj = &num3;
for (int i = 0; i < 3; i++)
{
printf("%s\n",((_num*)(obj))->text);
}
return 0;
} health 发表于 2024-6-25 09:04
这程序绕来绕去的,玩的挺花呀。
你用啥编译的,这能编译通过?
我的代码在KEILC51中能编译通过,程序都能正常运行,就是是函数指针间接调用的时候(num1->setnum(num1, "fdsfudsuifgsd\n"))这一句不能正常运行,通过它设置text的值后显示为乱码,我刚刚又去查了很多资料,说的是函数指针间接调用参数不能超过三个,但是我这里只有两个参数啊。另外num->text = *(str+i);我的源程序中是有中括号的,但是粘贴上来就没有了。固定内存地址传递这个怎么弄呢?谢谢 rayrakey 发表于 2024-6-25 16:42
我的代码在KEILC51中能编译通过,程序都能正常运行,就是是函数指针间接调用的时候(num1->setnum(num1,...
我觉得吧,,setnum之后用串口打印出来,,看看里面是不是你写的东西,,还不排除是不是后面的屏幕显示的问题呢 _奶咖君_ 发表于 2024-6-25 17:02
我觉得吧,,setnum之后用串口打印出来,,看看里面是不是你写的东西,,还不排除是不是后面的屏幕显示的 ...
这段代码在VS上面没有问题没在单片机上面不能正常运行,运行 (num1->setnum(num1, "fdsfudsuifgsd\n");//通过setnum函数上设置text中的字符 )这段代码后,不能正常的把值传递给text,显示出来时乱码,如果直接调用 setnum(num1, "fdsfudsuifgsd\n"),就能正常显示出来。
0.0 我试着函数指针用的是可以的0.0动态分配内存的方式没用测,,