rayrakey 发表于 2024-6-24 21:01:47

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:05:48

本帖最后由 xxxevery 于 2024-6-25 01:12 编辑

值得研究一下

lzl1okOK 发表于 2024-6-25 07:52:01

单片机动态分配内存一般用大数组的形式,如果是51的话还要考虑访问方式

health 发表于 2024-6-25 09:04:29

这程序绕来绕去的,玩的挺花呀。
你用啥编译的,这能编译通过?

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字节,传递参数应该能放入寄存器了,试试看能不能编译通过。

xxxevery 发表于 2024-6-25 10:00:38

学习了

rayrakey 发表于 2024-6-25 14:31:58

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;
}

rayrakey 发表于 2024-6-25 16:42:49

health 发表于 2024-6-25 09:04
这程序绕来绕去的,玩的挺花呀。
你用啥编译的,这能编译通过?



我的代码在KEILC51中能编译通过,程序都能正常运行,就是是函数指针间接调用的时候(num1->setnum(num1, "fdsfudsuifgsd\n"))这一句不能正常运行,通过它设置text的值后显示为乱码,我刚刚又去查了很多资料,说的是函数指针间接调用参数不能超过三个,但是我这里只有两个参数啊。另外num->text = *(str+i);我的源程序中是有中括号的,但是粘贴上来就没有了。固定内存地址传递这个怎么弄呢?谢谢

_奶咖君_ 发表于 2024-6-25 17:02:35

rayrakey 发表于 2024-6-25 16:42
我的代码在KEILC51中能编译通过,程序都能正常运行,就是是函数指针间接调用的时候(num1->setnum(num1,...

我觉得吧,,setnum之后用串口打印出来,,看看里面是不是你写的东西,,还不排除是不是后面的屏幕显示的问题呢

rayrakey 发表于 2024-6-25 17:12:09

_奶咖君_ 发表于 2024-6-25 17:02
我觉得吧,,setnum之后用串口打印出来,,看看里面是不是你写的东西,,还不排除是不是后面的屏幕显示的 ...

这段代码在VS上面没有问题没在单片机上面不能正常运行,运行 (num1->setnum(num1, "fdsfudsuifgsd\n");//通过setnum函数上设置text中的字符 )这段代码后,不能正常的把值传递给text,显示出来时乱码,如果直接调用   setnum(num1, "fdsfudsuifgsd\n"),就能正常显示出来。

_奶咖君_ 发表于 2024-6-25 17:29:39


0.0 我试着函数指针用的是可以的0.0动态分配内存的方式没用测,,
页: [1] 2 3
查看完整版本: 51单片机函数指针问题