локальный массив в фукнции Loop()

RainMan
Offline
Зарегистрирован: 21.06.2011

Привет. Столкнулся с такой задачей. Необходимо создать локальный массив, величина которого задается в секции Setup().

Т.к секция Loop()  выполняется в бесконечном цикле, то массив надо объявить один раз. Полученный код не пропускает компилятор, требуя объявлять массив безусловно, т.е без if. Как решить мою задачу? 

boolean Flag = true;
byte Max_Star;
void setup() {
  Max_Star=5;
}

void loop() {
if (Flag) {
  int Mas[Max_Star];
  Flag=false;
}
  Mas[1]=3;
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Массив видно только в обрамляющих его "{" "}"

RainMan
Offline
Зарегистрирован: 21.06.2011

понял. А какие есть варианты решения моей задачи? Глобальный массив требует известного заранее кол-ва элементов

RainMan
Offline
Зарегистрирован: 21.06.2011

можно его объявить в Setup и передать в Viod?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

RainMan пишет:

понял. А какие есть варианты решения моей задачи? 

Мля, да поменяйте ж Вы местами строки №№ 8 и 9

RainMan
Offline
Зарегистрирован: 21.06.2011

более чем спасибо. 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Какой сокральный смысл объявлять массив только если выполняется условие?

b707
Offline
Зарегистрирован: 26.05.2017

BOOM пишет:

Какой сокральный смысл объявлять массив только если выполняется условие?

Дофига смыслов может быть

Например если массив нужен только при определенном условии

b707
Offline
Зарегистрирован: 26.05.2017

RainMan пишет:

более чем спасибо. 

рано благодарите :) Полученный код скомпилируется, но будет работать не так, как вы ожидаете.

sadman41
Offline
Зарегистрирован: 19.10.2016

BOOM пишет:

Какой сокральный смысл объявлять массив только если выполняется условие?

Штобы память сыканомить. Вдруг понадобится в другом месте.

OK0
Offline
Зарегистрирован: 06.03.2020
Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

RainMan пишет:

А Max_star на момент компиляции не известна? То есть значение приходит откуда-то в момент старта контроллера?

 

OK0
Offline
Зарегистрирован: 06.03.2020

Rumata, обычное дело - читаем размер из EEPROM, например.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

BOOM пишет:

Какой сокральный смысл объявлять массив только если выполняется условие?

Штобы память сыканомить. Вдруг понадобится в другом месте.

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

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

https://www.youtube.com/watch?v=EHc2TG90VWM

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014
BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

sadman41 пишет:

BOOM пишет:

Какой сокральный смысл объявлять массив только если выполняется условие?

Штобы память сыканомить. Вдруг понадобится в другом месте.

В области видимости массива (или любой другой переменной) это понятно, но в примере ТС мне не понятно. Судя по его коду - если флаг стоит - объявляем переменную, которая должна быть «видима» где-то ещё.
Я, наверное, вопрос не верно сформулировал. 

RainMan
Offline
Зарегистрирован: 21.06.2011

Размер массива по умалчиванию считывается из Epprom. Потом его размер может меняться в процессе работы программы, через последовательный порт. 

Я думал что если определить массив в секции Loop без условия, то при каждой итерации Loop под него будет выделяться память в разных частях Heap. И в итоге у меня будут теряться данные масива. 

RainMan
Offline
Зарегистрирован: 21.06.2011

рано благодарите :) Полученный код скомпилируется, но будет работать не так, как вы ожидаете.

 - как ни странно все отлично работает. Пока...

Kakmyc
Offline
Зарегистрирован: 15.01.2018

RainMan пишет:

Размер массива по умалчиванию считывается из Epprom. Потом его размер может меняться в процессе работы программы, через последовательный порт. 

Я думал что если определить массив в секции Loop без условия, то при каждой итерации Loop под него будет выделяться память в разных частях Heap. И в итоге у меня будут теряться данные масива. 

Тут два варианта:
1. В конце цикла массив уничтожается ,освобождая занимаемые адреса(освобождает память), и в начале цикла создаётся заново.
2. Массив имеет тип static и адреса закрепляются за ним на все время работы программы.

ЗЫ: Это справедливо для Ардуино.
ЗЗЫ: рекомендую спросить в Гугле и ознакомится с информацией по запросу "область видимости и время жизни переменных в C++"

OK0
Offline
Зарегистрирован: 06.03.2020

Вариант 2 - не получится, static не работает для нашего случая

А вот так, правильно?

int max_Star = 0;
void setup() {
  max_Star = 100; // or read from EEPROM
}
void loop() {
  myLoop(max_Star);
}
void myLoop(int const local_Max_Star) {
  int myArr[ local_Max_Star];
  while (1) {
    // users cod
    //................................
    //................................
  }
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:
1. В конце цикла массив уничтожается ,освобождая занимаемые адреса(освобождает память), и в начале цикла создаётся заново.
Ну, так у ТС написано - именно это и получается.

RainMan
Offline
Зарегистрирован: 21.06.2011

Помогите пож. Ничего не понимаю.

Вот код:

struct Star 
{
   float kR,kG;
};
boolean Flag=true;

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

void loop() {
 Star Mas[0]; 
 if (Flag) {
     Mas[0].kG=4;
     Mas[0].kR=4;
     Serial.println("SS3");
     Serial.println(Mas[0].kR);
     Serial.println(Mas[0].kG);
     Flag=false;
 }  
 Serial.println("SS4");
 Serial.println(Mas[0].kR);
 Serial.println(Mas[0].kG);
 delay(1000);
}

В результате в последовательном порту имеем такую картину:

SS3
4.00
4.00
SS4
4.00
0.00
Сразу после выхода из условия, поменялось значение Mas[0].kG на 0. Как это понимать?
 
Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Star Mas[0]; ??

RainMan
Offline
Зарегистрирован: 21.06.2011

Если сделать безусловный вход в условие, то все работает!

struct Star 
{
   float kR,kG;
};

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
}

void loop() {
 Star Mas[0]; 
 if (true) {
     Mas[0].kG=4;
     Mas[0].kR=4;
     Serial.println("SS3");
     Serial.println(Mas[0].kR);
     Serial.println(Mas[0].kG);
 }  
 Serial.println("SS4");
 Serial.println(Mas[0].kR);
 Serial.println(Mas[0].kG);
 delay(1000);
}

В порту имеем:

Start
SS3
4.00
4.00
SS4
4.00
4.00
 
b707
Offline
Зарегистрирован: 26.05.2017

RainMan - еще раз, внимательно, прочитайте что написал дон Румата в #23.

RainMan
Offline
Зарегистрирован: 21.06.2011


Я вижу в примерах  присваивание значения  0 элементу массива как values[0] = 10
А объявлять массив из одного элемента надо как   byte values[1]; Так?
b707
Offline
Зарегистрирован: 26.05.2017

RainMan пишет:
Я вижу в примерах  присваивание значения  0 элементу массива как values[0] = 10

А объявлять массив из одного элемента надо как   byte values[1]; Так?

так

вы тоже, что ли, "учитесь по примерам", а книжки читать не умеете?

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

RainMan пишет:



Я вижу в примерах  присваивание значения  0 элементу массива как values[0] = 10
А объявлять массив из одного элемента надо как   byte values[1]; Так?

Вы размер массива определили в 0 элементов. Я вообще много нового узнал сейчас об инициализации несуществующих элементов массива :) Шаблон слегка треснул у меня, пойду пивом лечиться ))

RainMan
Offline
Зарегистрирован: 21.06.2011

спасибо!  Давно читал, уже забыл что-то.

b707
Offline
Зарегистрирован: 26.05.2017

Rumata пишет:

много нового узнал сейчас об инициализации несуществующих элементов массива :)

в этом-то как раз нет ничего удивительного. Типичный выход за границу. Ничем не отличается от случая обьявления массива byte arr[5] и потом присвоения значения элементу arr[5] = 1 :))))

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

b707 пишет:

Типичный выход за границу. Ничем не отличается от случая обьявления массива byte arr[5] и потом присвоения значения элементу arr[5] = 1 :))))

Это все понятно. Меня поразило, что у него это ПОЛУЧИЛОСЬ 

incdpr
Offline
Зарегистрирован: 28.11.2020

Kakmyc][quote=RainMan пишет:

ЗЗЫ: рекомендую спросить в Гугле и ознакомится с информацией по запросу "область видимости и время жизни переменных в C++"

Или здесь почитать.

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Rumata пишет:

Это все понятно. Меня поразило, что у него это ПОЛУЧИЛОСЬ 

А чего тут удивительного ?

byte b[0] - эквивалент byte* b.

То что он "накакал" в некую область памяти там пролежало недолго :) Надо еще посмотреть чего там накомпилил компилятор :)

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

brokly пишет:

А чего тут удивительного ?

byte b[0] - эквивалент byte* b.

Мало того, что он положил байт в "необъявленную" ячейку памяти, так еще хватило наглости и везения получить его оттуда обратно)) 

sadman41
Offline
Зарегистрирован: 19.10.2016

Я бы на месте компилятора просто печать константных значений оставил в коде.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Вот я и говорю, интересно посмотреть . Но лениво :)