двумерный массив и переменные

Тема в разделе "Arduino & Shields", создана пользователем Braun, 28 сен 2017.

  1. Braun

    Braun Нуб

    Всем привет. Есть массив m[4][4] и две переменные, значения которых берем с аналоговых входов, на которых 'висят' переменные резисторы. Нужно сравнить переменные с элементами нулевой строки и нулевого столбца и найти элемент на пересечении, с последующим выводом его на дисплей. Например x=50, z=800 искомое значение 7.
    Код (C++):
    int m[4][4]= {0, 50, 200, 600};
    {350, 1, 2, 3};
    {500, 4, 5, 6};
    {800, 7, 8, 9};
    int x=0;
    int z=2;
    int a,b,f;
    .......
    void loop (){
    analogRead(x);
    for (I=0; I<3; I=I+1)
    {
    if (x>=m[I][0])
    {
    a=I;
    }
    }
    analogRead(z);
    for (k=0; k<3; k=k+1)
    {
    If (z>=m[0][k])
    {
    b=k;
    }
    }
    f=m[a][b];
    lcd.print(f);
    }
    Я пробовал и по другому.
    Код (C++):
    ......
    for (I=0; m[I][0]>=x; I=I+1)
    {
    a=I;
    }
    ......
    Вообщем, по разному делал, как только не крутил резисторы, но значения на дисплее фиксируются то на 5, то на 200, то на 500 ( в зависимости от вариантов условий в цикле for).
     
    Последнее редактирование: 28 сен 2017
  2. b707

    b707 Гуру

    в первом коде индексы в циклах на единицу меньше, чем длина массива.
    Второй код вообще бредовый и чреват вылетами программы из-за выхода за границы массива.
     
  3. fogary

    fogary Гик

    У Вас в коде ряд ошибок. Не правильно инициализирован массив. Результат функций analogRead() никуда не сохраняется. Переменные a и b могут оказаться не инициализированными.

    Попробовал исправить, если предположить, что x и z - это аналоговые пины на которых 'висят' переменные резисторы.
    Код (C++):
    int m[4][4]= {
      {0, 50, 200, 600},
      {350, 1, 2, 3},
      {500, 4, 5, 6},
      {800, 7, 8, 9}
    };
    int x = 0;
    int z = 2;
    .......
    void loop(){
      int a,b,f,i;

      f = analogRead(x);
      a = 0;
      for (i = 0; i < 3; i++){
        if (f >= m[i][0]){
          a = i;
        }
      }
     
      b = 0;
      f = analogRead(z);
      for (i = 0; i < 3; i++){
        if (f >= m[0][i]){
          b = i;
        }
      }
     
      f = m[a][b];
      lcd.print(f);
    }
     
  4. ORLENOK

    ORLENOK Гик

    можно ещё красивее)
    Код (C++):
    int m[4][4]= {
      {0, 50, 200, 600},
      {350, 1, 2, 3},
      {500, 4, 5, 6},
      {800, 7, 8, 9}
    };
    int x = 0;
    int z = 2;
    .......
    void loop(){
      int a,b,f,xVal,yVal;

      xVal = analogRead(x);
      yVal = analogRead(y);
      a = 0;
      b = 0;
      for (int i = 0; i < 3; i++)
      {
        if (xVal == m[0][i])
        {
          a = i;
        }
        if (yVal == m[i][0])
        {
          y = i;
        }
      }
      f = m[a][b];
      lcd.print(f);
    }
    Вообще не очень понял, для чего знак >=. Число может быть не четко 200, а 250, например? Просто из-за этого знака могут быть ошибочные данные.
     
  5. b707

    b707 Гуру

    ORLENOK - Ошибка в логике - вы не вполне поняли замысел автора, он проверяет, между какими элементами массива лежит значение, считанное с аналогового пина - поэтому условие (xVal == m[0]) тут не подходит, надо (xVal >= m[0])
     
    Последнее редактирование: 29 сен 2017
  6. Limoney

    Limoney Гик

    Надо условие больше чем и меньше чем, потому что возможен вариант, например, значение z = 900, что больше значений элементов 500 и 800 по строкам, тогда неизвестный искомый индекс массива.
    Тоже самое по столбцам массива. Также переменным резистором, тяжело выставить точное значение, поэтому разделить поворот ручки переменного резистора на несколько секторов.
     
    Последнее редактирование: 29 сен 2017
  7. Braun

    Braun Нуб

    Спасибо парни. Теперь всё работает. b707 правильно понял, верхняя строка и левый столбец это значения диапазонов. Но я заметил что программа работает 'правильно', только когда x>=m[ ][ ], если написать x<=m[ ][ ], то всегда выдает '9'.
     
  8. fogary

    fogary Гик

    У Вас же проверяются все значения m[ ][ ], а не до первого совпадения.
    Допустим, x=40, тогда для m[0] будет проверяться:
    (40 <= 0) = false --> a - не меняется
    (40 <= 50) = true --> a = 1
    (40 <= 200) = true --> a = 2
    (40 <= 600) = true --> a = 3

    Аналогично будет для 'z' и 'b'. В итоге значения 'a' и 'b' всегда будут равны 3, а m[3][3] = 9.

    PS
    Да, самое интересное, что 'a' и 'b' объявлены как глобальные, и при этом не имеют начальных значений (вероятно - ноль, но не гарантируется). Это значит, что даже когда ни одна из проверок не выполняется, эти переменные будут иметь значения последней успешной проверки. Например, если после включения крутить пременник от мин. до макс. значений - начальное значение переменной не важно, а если на оборот - очень даже важно.
     
    Последнее редактирование: 2 окт 2017
  9. b707

    b707 Гуру

    По спецификации С++ все глобальные переменные в обязательном порядке инициализируются нулевыми значениями. Но, в общем смысле, ваше замечание верно - во избежание ошибок лучше инициализировать переменные явно.
     
  10. fogary

    fogary Гик

    Спасибо за уточнение!
     
  11. Tomasina

    Tomasina Сушитель лампочек Модератор

    Нулевыми - это 0 или NULL?
     
  12. b707

    b707 Гуру

    для численных типов - 0
     
    Tomasina нравится это.
  13. issaom

    issaom Гуру

    А в C++ NULL вообще бывает в каких-нибудь случаях? В других прикладных вещах такое часто встречаются...
     
  14. ORLENOK

    ORLENOK Гик

    Я думаю все переменные ссылочного типа, значения которых не инициализированы имеют значение NULL.