为什么我的带有字符的代码弄乱了计数变量?

Why is my code with chars messing up a counting variable?

这是 Arduino 代码,但我感觉我的错误一般是 C++ 而不是特定于 Arduino。我是指针和字符串的新手,所以在这方面我可能做错了什么。

这是一个更大的程序,但我已将其缩减为尽可能少的代码,这样我仍然可以重现错误。

它应该只是遍历 text[] 的字母并将每个字母保存到 newText[0][0],以及打印 newText[0][0] 和计数器变量 i.

void setup() {
  Serial.begin(9600);
}

void loop() {
  const char text[] = "chunk";
  static char newText[][10] = {};

  static unsigned int i=0;
  static int code = 0;     

  if(code == 0){
    
      newText[0][0] = text[i]; //This
      Serial.print(i);
      Serial.println(newText[0][0]); //This
      
      i++;
      
      if(i>=strlen(text)){
        code=1;
      }
  }
}

但是因为我有代码,i 在第二次迭代时跳转到某个数字,例如 104,此时它应该等于 1。(确切的值因代码的外观而异。)如果我注释掉带有注释 //This 的任何一行,那么计数器工作正常。另外,如果我切换 Serial.print(i); 和它之前的行,那么它就可以了。

static char newText[][10] = {};

这将创建一个大小为零的数组(更准确地说是一个 0 行 10 列的矩阵)。这在 C++ 中是非法的,但 gcc 有一个扩展允许它。尽管如此,即使使用 gcc 的扩展名,当您访问超出数组大小的 newText[0][0] 时,它也是 UB。当你有 UB 时,任何事情都可能发生,程序可以像你预期的那样工作,它可以打印乱码,它可以崩溃等等,几乎任何事情。

因此您需要声明一个可容纳您所有访问的大小,例如:

static char newText[1][10] = {};

如果您只需要 1 行(但在这种情况下您不需要矩阵,一维数组就可以)。


提示:对字符串使用 String class 而不是原始数组。