在几天前的一个项目里我用单片机做了一个小的音游系统(暂时还没发出来),在里面遇到了很诡异的事情,首先这是我的音符结构体(就是音游里面能击打的那种音符):
typedef struct note note;
struct note {
int notetype;//1为单键,0为长键
unsigned long create_time;//创建时间,单位为毫秒
unsigned int length;//音符长度,每次判定
unsigned int n_length;//现在音符剩余长度
};
然后我去网上毛(?)了一个c语言的队列文件,这里也附上链接:https://blog.csdn.net/qq_44785014/article/details/104089691
里面只需要把数据类型改一下就可以用了,我就习惯性地把数据类型改成了结构体指针
然后在主程序的全局变量中使用了队列结构体指针,想着他这个文件里的函数不都是调用的队列指针吗(比如查询是否为空就是void QueueEmpty(Queue* q)),那我设置个队列指针不就免得每次加个取值符了吗。
然后就出了一堆bug...
首先就是队列的操作函数用不了,找了很久的bug发现它如果参数是Queue*的,就得创建Queue结构体,然后传地址进去,比如:
Queue q;
QueueEmpty(&q);
虽然有调查过,但我一个基础不是很好的人确实不知道是不是单片机导致出这样的问题,但好了现在队列能用了,然后就遇到了我标题提到的bug,我明明什么结构体都没往队列里放,但是队列里就是自带一个奇怪的结构体。
简单来讲就是我初始化队列为NULL,但用QueueEmpty获得的结果是队列非空,取队列头还能取出来,值还是确定的(多次调试发现取出来的结构体的值完全一样),这就导致游戏一开始他就疯狂miss,因为队列里有音符而且不停超时。
略过好几个小时的bug调试,我终于想到我当时把结构体指针note*作为了队列的元素,而指针这东西在单片机里我感觉就是薛定谔的猫一样,有时能用有时不能用,于是我试着把队列元素换成结构体,又改了主函数里的一大堆红点
在把队列元素换成结构体note之后,再把主函数里一大堆红点全改完,再次在测试程序里调用一下QueueEmpty函数,唉,成了!队列是空的了!
激动地把在正常程序里调用,系统终于正常了。
具体为什么为出现这样的问题我最后也没能理解,如果从调试的顺序来讲的话,我是创建了一个队列结构体变量(Queue q),然后用文件里的初始化函数对其进行初始化(QueueInit(&q)),然后用查询队列空函数(QueueEmpty(&q))查询其是否为空,结果显示为非空,其文件内使用到的东西如下:
typedef struct note note;
struct note {
int notetype;//1为单键,0为长键
unsigned long create_time;//创建时间,单位为毫秒
unsigned int length;//音符长度,每次判定
unsigned int n_length;//现在音符剩余长度
};
typedef note* QuDataType;//这里使用结构体指针为队列元素
// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* _next;
QuDataType _data;
}QueueNode;
// 队列的结构
typedef struct Queue
{
QueueNode* _front;
QueueNode* _rear;
}Queue;
//初始化队列结构
void QueueInit(Queue* q)
{
q->_front = NULL;
q->_rear = NULL;
}
//判断队列是否为空
int QueueEmpty(Queue* q)
{
return (q->_front == NULL); //为空,返回1
}
也就是建立了一个带有结构体a的指针和结构体n的指针的结构体a,又用结构体b封装了两个结构体a的指针,初始化时将b的两个指针赋值为NULL,判断是否为空时查看其中一个指针是否为NULL,此时q->_front不是NULL,且里面的数据变量带有初值。
而如果把结构体n的指针换成结构体n,则q->_front是NULL,没有数据在里面。
上一篇:msp430 while语句的超自然现象
下一篇:MSP430F5529系统升压与时钟配置
推荐阅读最新更新时间:2024-11-01 19:12
设计资源 培训 开发板 精华推荐
- 使用基于 LTC4162EUFD-L40M USB PD(C 电缆)的电池充电器和电源路径的典型应用
- 使用 Richtek Technology Corporation 的 RT8016L 的参考设计
- KITDRIVER2EDN7524GTOBO1,用于 2EDN7524G EiceDRIVER 双通道非隔离栅极驱动器的评估套件
- LT6656BIS6-1.25、1.25V 升压输出电流电压基准的典型应用
- MCP1726 1A、低电压、低静态电流 LDO 固定输出稳压器的典型应用
- 具有 400kHz 外部同步降压转换器的 LTC3646HDE 12V 至 1.8V 输出的典型应用电路
- TWR-RF-SNAP: 无线射频网状网塔式系统模块
- 用于负电压的 48 伏热插拔控制器
- OP284FSZ-REEL7输出过载恢复运放测试电路典型应用
- LTC1709-9 的典型应用 - 2 相、5 位 VID、电流模式、高效率、同步降压型开关稳压器