首页 > 解决方案 > Lego Mindstorms NXT, NXC: Error in replacing elements in an array (no matter the dimension)

问题描述

I tried to write a simple fifteen puzzle for the Lego Mindstorms NXT block using Bricx Command Center. But there's always the same problem. The elements of the array (no matter the dimension) won't change the second time.

Here's the code that simulates the error. In case you don't have an NXC block to check it out, the program outputs a 4x4 grid of zeroes (and it's ok) and then the program exits with "File error!" on the LCD screen, presumably while trying to change the first zero element of the array with 1.

If you have any thoughts please let me know. I presume that NXC language wasn't developed to work with arrays in that particular way though I find it odd and strange..

P.S. I also tried to use the built in function ArrayReplace() though with no success.

Here's the code example:

int count;
int numMatrix[] = {1, 2 ,3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 69};
const int xcoord[] = {12, 37, 62, 87};
const int ycoord[] = {56, 40, 24, 8};

void fillGrid(){
     int j, k;
     for (int i = 0; i < 16; i++){
         numMatrix[i] = count;
         if (k == 4){
            k = 0;
            j++;
         }
         NumOut(xcoord[j], ycoord[k], numMatrix[i]);
         Wait(50);
         k++;
         }
     Wait(2000);
     ClearScreen();
}

task main(){
     while (true){
           fillGrid();
           count++;
     }
}

Okay, that was clearly my bad, I should have initialized the j and k local variables and equal them to 0. Now take a look at this situation where I try to do the same with 2 dimensional array.

#define NROWS    4
#define NCOLUMNS 4

int count;
int numMatrix[NROWS][NCOLUMNS] = {
    { 1,  2,  3,  4},
    { 5,  6,  7,  8},
    { 9, 10, 11, 12},
    {13, 14, 15, 69} };
const int xcoord[] = {12, 37, 62, 87};
const int ycoord[] = {56, 40, 24, 8};

void fillGrid(){
     for (int i = 0; i < NROWS; i++){
         for (int j = 0; j < NCOLUMNS; j++){
             numMatrix[j][i] = count;
             NumOut(xcoord[i], ycoord[j], numMatrix[j][i]);
             Wait(50);
         }
     }
     Wait(2000);
     ClearScreen();
}

task main(){
     while (true){
           fillGrid();
           count++;
     }
}

Nothing will change all of the elements of the array will remain the same as they were initialized (1, 2, 3...). Now it's getting more interesting..

标签: carrayslegomindstormsnxc

解决方案


问题是:在 C 中,局部变量是在堆栈上分配的,默认情况下不会为你初始化,你必须自己做。

int count;               // global: automatically initialized to zero

void fillGrid() {
     int j = 0, k = 0;   // local: NOT automatically initialize - you do it.

     for (int i = 0; i < 16; i++){
         numMatrix[i] = count;
         if (k == 4){
            k = 0;
            j++;
         }
         NumOut(xcoord[j], ycoord[k], numMatrix[i]);
         Wait(50);
         k++;
     }
    ...
}

如果你没有初始化它们,你会得到随机垃圾,无论堆栈上发生了什么:在我的系统上,j确实是零,但是k是 4195392。

我认为 NXC 语言不是为了以这种特定方式处理数组而开发的

这实际上与它没有任何关系:库代码(例如,NumOut)从不看到数组,只有从数组索引并单独传递给库的单个值。


推荐阅读