【发布时间】:2017-03-07 15:37:24
【问题描述】:
嗨:我一直在学习 C,我有几个基于数组和指针的哲学问题,以及如何让事情变得简单、快速和小,或者至少平衡这三者,我想。
我想象一个 MCU 每隔一段时间对输入进行采样,并将样本存储在一个名为“val”的数组中,大小为“NUM_TAPS”。 'val' 的索引在当前之后的下一个样本中递减,例如,如果 val[0] 刚刚被存储,则下一个值需要进入 val[NUM_TAPS-1]。
最后,我希望能够将最新的样本称为 x[0],将最旧的样本称为 x[NUM_TAPS-1](或等效项)。
这个问题与许多人在这个论坛和其他论坛上解决的描述旋转、循环、队列等缓冲区的问题略有不同。我不需要(我认为)头尾指针,因为我总是有 NUM_TAPS 数据值。我只需要根据“头指针”重新映射索引。
下面是我想出的代码。它似乎运行良好,但它提出了一些我想向更广泛、更专业的社区提出的更多问题:
- 有没有比条件赋值更好的方法来分配索引 (包装索引 NUM_TAPS -1)?我想不出一种指向指针的方法 帮助,但是其他人对此有什么想法吗?
- 而不是像在 FIFO 中那样移动数据本身来组织 x 的值,我决定在这里旋转索引。我猜想 对于大小接近或小于指针的数据结构 他们自己认为数据移动可能是要走的路,但对于非常大的 数字(浮点数等)也许指针分配方法是 最有效。想法?
- 模数运算符通常被认为在速度上接近于 条件语句?例如,通常哪个更快?:
offset = (++offset)%N; *要么** 偏移++; if (NUM_TAPS == offset) { offset = 0; }
谢谢!
#include <stdio.h>
#define NUM_TAPS 10
#define STARTING_VAL 0
#define HALF_PERIOD 3
void main (void) {
register int sample_offset = 0;
int wrap_offset = 0;
int val[NUM_TAPS];
int * pval;
int * x[NUM_TAPS];
int live_sample = 1;
//START WITH 0 IN EVERY LOCATION
pval = val; /* 1st address of val[] */
for (int i = 0; i < NUM_TAPS; i++) { *(pval + i) = STARTING_VAL ; }
//EVENT LOOP (SAMPLE A SQUARE WAVE EVERY PASS)
for (int loop = 0; loop < 30; loop++) {
if (0 == loop%HALF_PERIOD && loop > 0) {live_sample *= -1;}
*(pval + sample_offset) = live_sample; //really stupid square wave generator
//assign pointers in 'x' based on the starting offset:
for (int i = 0; i < NUM_TAPS; i++) { x[i] = pval+(sample_offset + i)%NUM_TAPS; }
//METHOD #1: dump the samples using pval:
//for (int i = 0; i < NUM_TAPS; i++) { printf("%3d ",*(pval+(sample_offset + i)%NUM_TAPS)); }
//printf("\n");
//METHOD #2: dump the samples using x:
for (int i = 0; i < NUM_TAPS; i++) { printf("%3d ",*x[i]); }
printf("\n");
sample_offset = (sample_offset - 1)%NUM_TAPS; //represents the next location of the sample to be stored, relative to pval
sample_offset = (sample_offset < 0 ? NUM_TAPS -1 : sample_offset); //wrap around if the sample_offset goes negative
}
}
【问题讨论】:
标签: c rotation queue buffer circular-buffer