Вопрос о типе String

Переменные объявлены следующим образом:

int a;
String b;
int c;
........

Может ли случиться такое, что переменная b выйдет за свои границы и накроет переменную c?
Если - да, то как это предотвратить?

поменять местами

Не может

1 лайк

ты хочешь сказать что память будет выделяться на стеке?
кстати, ты в своей библиотеке переменные ssid и pass хранишь в String, почему?

Я хочу сказать, что String - это класс, а не указатель на строку символов

Так проще ))

1 лайк

В Serial передаю строку “1234”.
Необходимо преобразовать “12” в число a, а “34” в число c.
Ответьте, пожалуйста:

  1. Правильно ли я обрабатываю конец пакета?
  2. Правильно ли я выполняю преобразование?
  3. Что будет, если вместо цифры в порт попадет какой-нибудь другой символ?
int a;
String b;
int c;
int x;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0)
  {
    char priem = Serial.read();
    if (priem == '\n') //конец пакета
    {
      a = String(b.substring(0, 1)).toInt();
      c = String(b.substring(2, 3)).toInt();
      x = a + c;
      a = x;
      b = "";
    }
    else
    {
      if ((byte) priem != 13)
      {
        b += priem;
      }
    }
  }
}

ТС! Я бы порекомендовал тебе отучаться от плохого стиля кода, пока ты начинающий3. .

  1. Вот эта куча глобальных переменных перед сетап и луп - очень плохой стиль. Это а-ля фортран времен 70 годов. Если тебе нужно что-то в лупе - там их и объявляй статическими, если нужно помнить значения между входами в луп.

  2. Однобуквенные переменные. Вообще их не использовать - снобизм, на мой взгляд. Но если имя переменной не имеет значения и она “техническая”, то и объявлять её стоит рядом с использованием

  3. стринги стоит использовать на МК с достаточными ресурсами. Не на Нано/Уно.

  4. про твой код. подумай над тем, как обрабатывать ошибки. То есть слишком длинную строку или слишком короткую.

Мне нужна строка не более 50 байт. Так что? Если мне нужен String, то и контроллер менять из-за этого? Переменные я взял для примера. Скорей всего я знаю, о чем Вы говорите:

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

void loop()
{
  if (Serial.available() > 0)
  {
    char priem = Serial.read();
    if (priem == '\n') //конец пакета
    {
      int a = String(b.substring(0, 1)).toInt();
      int c = String(b.substring(2, 3)).toInt();
      int x = a + c;
      a = x;
      b = "";
    }
    else
    {
      if ((byte) priem != 13)
      {
        b += priem;
      }
    }
  }
}

Последнее в целом верно.
Только b.substring уже возвращает String, не нужно явно оборачивать результат в String(…)
Сами тип String имеет фиксированный размер потому что хранит тело строки не в самой переменной а в так называемой куче (heap). ОЗУ всего 2Кб в которых лежат глобальные переменные и куча со стеком растущие навстречу друг другу.
Главная проблема кучи - это даже не размер, а фрагментация. Это когда после серии неудачных выделений/освобождений памяти образуется ситуация когда в куче есть много дырок между которыми лежат полезные данные и эти дырки сильно раздувают размер кучи.
Поэтому действительно на моделях с парой килобайт памяти следует очень осторожно и взвешенно обращаться с кучей и по возможности вообще избегать её использования.
Несколько строк с небольшими размерами не должны вызвать проблем, но если задаться целью, то ваш код легко завесить передав длинную строку без переносов строк - куча переполнится и приплыли.

1 лайк

то-есть делаем все переменные глобальными?

Глобальность или нет переменной перпендикулярная вещь куче, т.к. стек где локальные переменные лежат не есть куча. Они растут навстречу друг другу - стек и куча, но не одно и то же.
Стек в этом смысле проще контролировать, в нём фрагментации не бывает.

бывает, но она не критична, ибо живет тольько до выхода из функции.

используйте массивы символов

3 лайка

А это - ИДЕЯ!!!

Нет, это здравый смысл и Си++ )))

char a[10]="abcdefghij";
void setup()
{
}

void loop()
{
float ff=45.6;
//?
}

А покажите, пожалуйста, что надо написать в строке 9, чтобы с использованием переменной ff массив a имел такой вид: “abc45.6hij”?

Неверно. Элементов немного больше))

Умножте ff на 10, получите целое, затем поразрядно получите цифры.

а потом получить символьный код?

Ну естественно, ascii как азбука должна быть