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

Arduino编程求助:如何在if语句内设置数组大小并解决作用域报错

解决Arduino中'timing'未声明的作用域问题

你的猜测完全正确——问题出在数组的作用域上:你在if代码块内部声明了timing数组,这个数组的生命周期和可见范围只限于那个if块,出了块之后编译器就找不到它了,所以才会报'timing' was not declared in this scope的错误。另外,你用的变长数组(int timing[inString.toInt()])是C99的特性,并非标准C++内容,Arduino的AVR-GCC编译器虽然允许使用,但这种写法本身就会带来作用域和内存管理的隐患,不推荐这么用。

下面给你几个实用的解决方案,按易用性和安全性排序:

方案一:使用std::vector(最省心)

如果你用的是Arduino IDE 1.6及以上版本,可以直接用标准库的vector容器,它会自动帮你管理动态内存,不用手动分配/释放,还能避免作用域问题:

#include <vector>

std::vector<int> timing;
bool timingExists = false;
int n = 0;
String inString = "";

void loop() {
  while (Serial.available()) {
    int inChar = Serial.read();
    if (isDigit(inChar)) {
      inString += (char)inChar;
    }
    
    // 初始化数组大小
    if (!isDigit(inChar) && !timingExists && inString.length() > 0) {
      int size = inString.toInt();
      timing.resize(size); // 设置vector的长度
      inString = "";
      timingExists = true;
      n = 0;
    }
    
    // 往数组里存数据
    if (!isDigit(inChar) && timingExists && inString.length() > 0) {
      if (n < timing.size()) { // 防止越界
        timing[n] = inString.toInt();
        inString = "";
        n++;
      }
    }
  }

  // 打印数组内容
  for (int value : timing) {
    Serial.println(value);
  }
  n = 0;
  
  // 可选:清空vector,准备下次接收数据
  // timing.clear();
  // timingExists = false;
}

方案二:静态数组(最安全,适合内存有限的设备)

如果你能提前确定timing数组的最大可能长度(比如最多不会超过100),可以预先定义一个足够大的静态数组,用变量记录实际使用的大小:

const int MAX_TIMING_SIZE = 100; // 根据你的需求调整最大值
int timing[MAX_TIMING_SIZE];
int timingSize = 0;
bool timingExists = false;
int n = 0;
String inString = "";

void loop() {
  while (Serial.available()) {
    int inChar = Serial.read();
    if (isDigit(inChar)) {
      inString += (char)inChar;
    }
    
    // 初始化数组大小
    if (!isDigit(inChar) && !timingExists && inString.length() > 0) {
      timingSize = inString.toInt();
      // 防止输入的大小超过预设最大值
      if (timingSize > MAX_TIMING_SIZE) {
        timingSize = MAX_TIMING_SIZE;
        Serial.println("警告:输入大小超过上限,已截断");
      }
      inString = "";
      timingExists = true;
      n = 0;
    }
    
    // 往数组里存数据
    if (!isDigit(inChar) && timingExists && inString.length() > 0) {
      if (n < timingSize) { // 防止越界
        timing[n] = inString.toInt();
        inString = "";
        n++;
      }
    }
  }

  // 打印数组内容
  for (int i = 0; i < timingSize ; i++) {
    Serial.println(timing[i]);
  }
  n = 0;
}

这种方式不需要动态分配内存,对内存紧张的Arduino设备更友好,只要你能合理设置最大长度就行。

方案三:动态内存分配(手动管理,需注意内存泄漏)

如果无法预先确定数组大小,可以用new手动分配内存,但一定要记得在合适的时机释放,避免内存泄漏:

int* timing = nullptr;
int timingSize = 0;
bool timingExists = false;
int n = 0;
String inString = "";

void loop() {
  while (Serial.available()) {
    int inChar = Serial.read();
    if (isDigit(inChar)) {
      inString += (char)inChar;
    }
    
    // 初始化数组大小
    if (!isDigit(inChar) && !timingExists && inString.length() > 0) {
      // 先释放之前的内存(如果有的话)
      if (timing != nullptr) {
        delete[] timing;
        timing = nullptr;
      }
      timingSize = inString.toInt();
      timing = new int[timingSize]; // 动态分配数组
      inString = "";
      timingExists = true;
      n = 0;
    }
    
    // 往数组里存数据
    if (!isDigit(inChar) && timingExists && inString.length() > 0) {
      if (n < timingSize) { // 防止越界
        timing[n] = inString.toInt();
        inString = "";
        n++;
      }
    }
  }

  // 打印数组内容
  if (timing != nullptr && timingSize > 0) {
    for (int i = 0; i < timingSize ; i++) {
      Serial.println(timing[i]);
    }
    // 用完记得释放内存,否则会造成内存泄漏
    delete[] timing;
    timing = nullptr;
    timingExists = false;
    timingSize = 0;
  }
  n = 0;
}

额外注意事项

  • 一定要加inString.length() > 0的判断,避免把空字符串转成整数(会得到0),导致逻辑错误。
  • 所有方案里都加了n < 数组大小的判断,防止数组越界——越界会导致内存乱码甚至设备崩溃,这在嵌入式设备里是致命的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:24:39