【问题标题】:How to make what function I use in c be controlled by a variable如何使我在c中使用的函数由变量控制
【发布时间】:2026-01-21 13:30:02
【问题描述】:

这是我在vex. 的第一年,我正在担任程序员的角色。 我有快速自主创建的想法,记录驱动程序。我没有使用通常的阵列/调试器转储功率级别的原始流,而是想到了从驱动程序移动中提取函数的想法。 细节我就不说了,我自己写代码,但我需要一些帮助。

由于缺乏编码经验,我无法完成一件事。

我想创建一个 for 循环,逐个检查每个操纵杆按钮。

例如:

struct button
{
    bool pressed;
}

for(int i = 0; i>12; i++) //12 is number of buttons on the joystick
{
    struct button button<cycle through buttons>;
}

我希望在那里:

struct button button6U;
struct button button6D;
struct button button6R;
etc.

那么,我想要这个:

for(int i = 0; i>12; i++) // 12 is number of buttons on the joystick
{
    if(VexRT[<currentButton>])
    {
        button<currentButton>.pressed = true;
    }
}

我不知道该怎么做,用通配符修改我正在写入的实际变量名称。

几个想法: for 语句不知道如何提高操纵杆按钮的顺序。所以我认为我可能需要的是:

orderOfButtons
{
    VexRT[6U];
    VexRT[6D];
    VexRT[6R];
    // etc.
}

我似乎无法弄清楚如何使用一个变量来定义我正在读取的 VexRT[]button 的内容。

任何帮助将不胜感激! 谢谢。

【问题讨论】:

  • i&gt;12 ...咳咳,也许是i &lt; 12
  • 如果您无法轻松构建 [无论这些东西是什么] 的数组以进行索引,然后使用大小写开关(并修复循环控制,正如 @WeatherVane 所指出的那样)。

标签: c variables robotics robotc


【解决方案1】:

那么,您想要的是对用户输入进行采样(以某个指定的速率),然后将其记录到一个数组中,然后稍后再播放?如果你有驱动 VEX 的函数(我不熟悉),每个函数都与一个输入相关联,你可以使用一个函数指针数组来创建你的输出。

#define MAX_ACTION 12
#define MAX_RECORDED 200

// Declare your array of function pointers
int (*action[MAX_ACTION])(void);
// Declare your stored array of recorded actions
int recorded[MAX_RECORDED];
...

// Assign function pointers to associated functions
action[0] = go_forward;
action[1] = turn_right;
...

// Record your actions into some array
while (...)
{
    // Record the action
    recorded[i++] = get_action();
    // Sample delay
}
...

// Playback the actions
for (i=0;i<RECORDED;i++)
{
    (*action[recorded[i]])();
    // delay here
}

附:您的 for 循环是向后的(i12)。

【讨论】:

    【解决方案2】:

    听起来你想要一个数组:

    #define NUMBER_OF_BUTTONS 12
    ...
    struct button VexRT[NUMBER_OF_BUTTONS];
    

    如果要使用符号常量来引用数组中的特定按钮,可以使用枚举:

    enum btn_id { BTN_6U, // maps to 0
                  BTN_6D, // maps to 1
                  BTN_6R, // maps to 2
                  ...
                }
    

    枚举常量表示为整数,默认情况下它们从 0 开始并递增 1。如果需要,可以将它们初始化为不同的值,多​​个枚举常量可以映射到同一个值。当我想为循环识别“第一个”和“最后一个”枚举时,我会利用这一点,如下所示:

    enum btn_id {
      BTN_6U,
      BTN_FIRST = BTN_6U, // both BTN_FIRST and BTN_6U will map to 0
      BTN_6D,
      BTN_6R,
      ...
      BTN_whatever,
      BTN_LAST        
    };
    

    因此,VexRT[BTN_6U] 映射到 VexRT[0]VexRT[BTN_6D] 映射到 VexRT[1],等等。

    请注意,这样一来,您不必为了设置一个按钮而遍历所有按钮:

    enum btn_id currentButton = BTN_6D;
    ...
    VexRT[currentButton].pressed = true;
    

    如果你确实想遍历整个集合,你可以使用

    for ( enum btn_id i = BTN_FIRST; i < BTN_LAST; i++ )
    {
      VexRT[i].pressed = false;
    }
    

    【讨论】:

      【解决方案3】:

      我认为您正在尝试访问来自操纵杆的事件。您可以遍历值数组并记录它们。我认为操纵杆上的通道可以简单地访问: vexRT[x] 其中 x 是 1-12。如果您只想存储每个通道的最新值,您可以这样做:

      int value[12];
      for(i=0; i<12; i++)
      {
          value[i] = vexRT[i];
      }
      

      如果您想存储所有值以便映射或回放它们或其他东西,那么您将需要更复杂的数据结构来存储它们,例如值数组的列表。

      我还发现文档说这些值是通过类似 vexRT[Chx] 访问的,其中 x 为 1-12,因此您也可以创建一个字符串并使用它来访问循环内的操纵杆通道:

      string *s = (char *)malloc(5*sizeof(char)); //5 is the max length of the null terminated string
      for() . . . {
          sprintf(s,"Ch%d", i);
          value[i] = vertRT[s];
      }
      

      【讨论】: