You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VEX编程求助:如何用变量控制C语言函数调用及遍历摇杆按键

嘿,作为第一年当VEX程序员就能想出“记录驾驶员操作生成自主程序”的思路,真的挺厉害的!我来帮你搞定“用变量控制函数”和“循环检查摇杆按键”这两个问题~

一、用变量控制函数:C语言的函数指针

在C里要让变量“指向”不同的函数,核心就是用函数指针——它就像一个“函数的地址标签”,变量存的是哪个函数的地址,调用这个变量就相当于调用对应的函数。

举个VEX里的实际例子,比如你有几个不同的驾驶动作函数:

// 前进动作
void driveForward() {
  motor[leftDrive] = 127;
  motor[rightDrive] = 127;
}

// 后退动作
void driveBackward() {
  motor[leftDrive] = -127;
  motor[rightDrive] = -127;
}

// 停止动作
void stopDrive() {
  motor[leftDrive] = 0;
  motor[rightDrive] = 0;
}

接下来定义一个函数指针类型,用来统一这些动作函数的“格式”(因为这些函数都是无参数、无返回值的):

// 定义一个函数指针类型:无参数、返回值为void的函数
typedef void (*DriveAction)();

然后就可以声明一个变量,用它来切换要调用的函数了:

// 初始时让变量指向停止函数
DriveAction currentAction = stopDrive;

之后在主循环里,你可以根据摇杆输入或者其他条件,随时切换这个变量指向的函数,调用的时候直接用变量名就行:

while(true) {
  // 根据左摇杆的输入切换动作
  if(vexRT[Ch3] > 10) { // 忽略小数值的死区
    currentAction = driveForward;
  } else if(vexRT[Ch3] < -10) {
    currentAction = driveBackward;
  } else {
    currentAction = stopDrive;
  }

  // 调用当前变量指向的函数
  currentAction();
  wait1Msec(20); // 给系统留一点处理时间
}

如果你的动作函数需要参数(比如自定义速度),只要调整函数指针的类型就行,比如:

// 带速度参数的动作函数
void driveForwardWithSpeed(int speed) {
  motor[leftDrive] = speed;
  motor[rightDrive] = speed;
}

// 对应的函数指针类型
typedef void (*DriveActionWithSpeed)(int);

// 变量声明
DriveActionWithSpeed currentAction = driveForwardWithSpeed;

// 调用时传入参数
currentAction(80);
二、用for循环批量检查摇杆/按键

VEX的摇杆通道(比如Ch1-Ch4)和按键(比如Btn5U、Btn6D)都是可以用标识符表示的整数,你可以把要检查的通道/按键放到一个数组里,然后用for循环遍历这个数组,批量处理。

比如批量检查摇杆通道的例子:

// 把要检查的摇杆通道放到数组里
int targetChannels[] = {Ch1, Ch2, Ch3, Ch4};
// 计算数组里的元素个数
int channelCount = sizeof(targetChannels) / sizeof(targetChannels[0]);

while(true) {
  for(int i = 0; i < channelCount; i++) {
    int channelVal = vexRT[targetChannels[i]];
    // 忽略死区,只处理有效输入
    if(abs(channelVal) > 10) {
      // 这里可以根据通道做不同的处理,比如记录操作
      switch(targetChannels[i]) {
        case Ch3:
          // 处理左摇杆的前后输入,比如记录前进/后退动作
          break;
        case Ch4:
          // 处理右摇杆的前后输入,比如记录转向动作
          break;
        // 其他通道同理
      }
    }
  }
  wait1Msec(20);
}

如果是检查按键,逻辑也是一样的:

int targetButtons[] = {Btn5U, Btn5D, Btn6U, Btn6D};
int buttonCount = sizeof(targetButtons) / sizeof(targetButtons[0]);

while(true) {
  for(int i = 0; i < buttonCount; i++) {
    if(vexRT[targetButtons[i]] == 1) { // 按键被按下
      // 处理按键对应的动作,比如记录抬升臂/放下臂的函数
      switch(targetButtons[i]) {
        case Btn5U:
          // 调用抬升臂函数,或者记录这个动作
          break;
        // 其他按键同理
      }
    }
  }
  wait1Msec(20);
}
小提示
  • 函数指针的类型一定要和目标函数完全匹配:参数数量、类型,返回值类型都要一致,不然会出问题。
  • VEX编程里记得加wait1Msec(20)这类延迟,避免循环跑太快占用过多系统资源。
  • 记录操作的时候,你可以把函数指针和对应的参数(比如速度、时间)一起存到数组里,回放的时候依次调用这些函数就行,这就是你构想的“提取函数式自主程序”的核心啦~

内容的提问来源于stack exchange,提问作者Theol0403

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:00:10