Объявление одного массива по информации из другого
- Войдите на сайт для отправки комментариев
Курил и этот форум, и гугл, и все равно мозгов своих не хватает...
Задача следующая: существуют "колечки" из адресных светодиодных лент (вроде как от Adafruit, вот из 8 светодиодов, вот из 12, вот из 16, ну и т.д.). Если их вложить друг в друга, то получится эдакая мишень. Понятно, что соединяются эти светодиодные колечки последовательно, но при этом у каждого из светодиодов, помимо порядкового номера, есть еще и номер его колечка, и порядковый номер на этом колечке. Понятно, что задача создать всякого рода эффекты типа "Пропеллера" или "Разбегающихся из центра волн" гораздо проще, если порядковый номер диода в ленте перевести в номер кольца и номер на кольце.
Самое простое и тривиальное - просто ручками объявить массив с подходящей структурой
#include "FastLED.h" #define NUM_LEDS 61 // Число светодиодов в ленте typedef struct { //Объявляем структуру адресации мишени для прямого обращения к позиции и номеру круга byte pos; // Номер позиции на кольце byte cyrcle; // Номер кольца } Aim; Aim Chain[NUM_LEDS]= { //Объявляем массив адресов элементов ленты с объявленной перед этим структурой {0, 0}, // На нулевом (первом) кольце светодиод в нулевой (первой) позиции {1, 0}, {2, 0}, {3, 0}, ........... {0x00, 0x04} // В моем случае всего 5 отдельных элементов: первый - из 24 диодов, последний - один центральный }; byte Circles[5] = {24, 16, 12, 08, 01}; // Обозначаем число светодиодов в каждом из колец для использования в разных циклах void Effect1{ // ****** Первый эффект "белые круги" byte i, count, rep; for (rep = 0; rep < 5; rep++) { // Количество повторений эффекта for (count = 5; count > 0; count--){ // Цикл по числу колец в мишени for (i = 0; i < NUM_LEDS; i++) { // Цикл по числу светодиодов в ленте if (Chain[i].circle == count-1) { leds[i] = CRGB::White; // Зажечь светодиод, если номер круга совпадает с номером счетчика } else { leds[i] = CRGB::Black; // Остальные - погасить }; }; FastLED.show(); FastLED.delay(10000 / FRAMES_PER_SECOND); }; }; }
Этот код работает нормально (там еще в setup надо не забыть ленту объявить, надеюсь, это очевидно). Но в нем слишком много надо править руками при смене ленты. Если я, к примеру, этот же самый скетч попробую использовать с адресной лентой, намотанной вокруг ёлки, то неизбежно понадобиться переопределять и число колец, и число светодиодов в каждом из них. Кроме того, совершенно понятно, что число определений данных в данном скетче - избыточно. По хорошему, вся информация о всей цепочке светодиодов содержится всего в одной строке:
byte Circles[5] = {24, 16, 12, 08, 01};
Здесь есть и указание на число колец, и число элементов в каждом из колец. Разумеется, можно написать две функции - для вычисления номера кольца и позиции светодиода по его номеру в ленте, но это как-то не очень спортивно, что ли... Слишком большие накладные расходы будут - при каждом чих-пыхе вычислять заново эти значения. Вариант задать массив один раз при первом запуске и в дальнейшем его использование при создании различных эффектов видится более предпочтительным.
Но тут выясняется, что для объявления массива необходимо знать или его размерность, или уже точно иметь все элементы. На этапе объявления глобальных переменных невозможно даже посчитать NUM_LEDS, а без этого невозможно объявить массив
Aim Chain[NUM_LEDS]={};
Как объявить массив в том же void setup(), чтобы потом его можно было использовать во всех частях программы?
Может что-то типа этого подойдет:
Ну, если просто руками объявить число светодиодов в ленте, то это сразу решит проблему, т.к. потом спокойно объявляем массив адресов по этому числу.
Но хотелось бы красивости, т.е. компьютер на то и компьютер, чтобы считать все то, что можно посчитать. Если уже заданы элементы, неужели нет никакой возможности через них объявить новый массив?
Ничего не понимаю. Вы чего хотите-то в итоге... чтобы ардуина из вашей головы улавливала вибрации и соответственно им перестраивала массивы/индексы? В приведенном примере и описании я вижу способ задания только один - через изменение исходника и перекомпиляцию. На этом этапе NUM_LEDS определяется однозначно.
Но хотелось бы красивости, т.е. компьютер на то и компьютер, чтобы считать все то, что можно посчитать. Если уже заданы элементы, неужели нет никакой возможности через них объявить новый массив?
если вся задача - рассчитать NUM_LEDS - то можно вот так, в лоб:
Так ему надо массив посуммировать штоли...
Тогда как-то так (извините, набираю в фаре, не проверял на компилируемость):
To b707:
Спасибо, что попытались помочь. Но вторая строчка - в целом бессмысленна, т.к. гораздо проще тупо указать число. А идея в целом: все вычисления сделать только по одной строке данных - той самой, что стоит первой.
To sadman41:
"ему надо" объявить один массив по параметрам другого. Извините, но ваш последний пример очень напоминает интернет-мем "как нарисовать сову". В разделе "для новичков" он особенно доставляет. На 11 строке кода мои знания в программировании закончились.
Других вариантов, кроме как получить желаемое вами, через выделение памяти malloc-ом и оперировании указателями - я не вижу. Чудес не будет - или, как все новички, оперируйте заранее определенными константами или прокачивайте скилл через чтение литературы. Направление приложения ума указано...
И... у массива нет параметров, насколько я знаю. Выражайтесь как-то более понятно, будьте любезны.
To sadman41:
Да, изучая этот вопрос, я встречал схожие рекомендации: на этапе инициализации переменных зааллокировать под массив объем памяти, заведомо больший, чем нужно, потом в коде вычислить реальный массив и выполнить релокацию памяти. Видимо, это действительно единственно рабочий вариант для данного случая.
Спасибо, что попытались помочь! И прошу прощения за несоблюдение терминологии.
На данном этапе я бы не рекомендовал устраивать пляски с с релокацией. Думаю, что будет достаточно самым первым действием программы выделить память под массив и на этом остановиться. На AVR никто не будет устранять дыры в куче, которые вы можете получить от последующих перераспределений памяти.
Да, изучая этот вопрос, я встречал схожие рекомендации: на этапе инициализации переменных зааллокировать под массив объем памяти, заведомо больший, чем нужно, потом в коде вычислить реальный массив и выполнить релокацию памяти. Видимо, это действительно единственно рабочий вариант для данного случая.
Да, ладно. Чего память-то дёргать? Дыр нафрагментировать и потерять кусок для дальнейшего использования?
Вот Вам работающий пример. Всё, что здесь нужно, это задать Ваш массив размеров колец
static const uint8_t RingSizes[] = {8, 4, 2, 1};
Указали его, всё остальное расчитается само. Никаких перезахватов памяти - нафиг.
В реальности, кроме этого массива память будет жрать ещё один вспомогательный массив такого же размера. В нём будут номера диодов - начал колец. Он нужен исключительно для ускорения доступа к светодиодам. Так-то можно и без него обойтись. Не, ну собственно массив структур RGB разумеется будет тоже. Причём будет правильного размера - сколько нужно и безо всяких "перезахватов".
В моём примере нужно таки вызвать один раз (из сетап) функцию fillUpRingStarts, которая дозаполнит тот вспомогательный массив начал колец. Не вижу в этом проблемы. Но если Вам уж так сильно хочется, чтобы всё заполнял именно компилятор - ответственно заявляю (готов отвечать) сделать такое заполнение препроцессором можно, только получится громоздко (можно в include файл спрятать, конечно). Только вот нафига? Считаю приведённое решение вполне рабочим. Изучайте.
Да, кстати, в структуре в самом начале не пугайтесь слова Printable и функции printTo - они нужны для простой и короткой печати структуры и не более того (посмотрите как элегантно она в setup печатается). Если интересно, то теория про эти дела вот здесь.
Собственно код примера. Проверен, запускайте. смотрите.
Для определённости стоит сказать, что
И что? У Вас-то нет проблем, а вот те, у кого есть, обязательно после первого запроса запулят какой-нибудь String, а потом перезапросят - здравствуй фрагментация.
Я же написал - для определенности. Чтобы не было ложного чувства, что new() - это что-то другое, менее опасное.
To ЕвгенийП:
Большое спасибо, что не потрудились наваять так много кода. С интересом просмотрел его и взял на заметку кусок с 35 по 56 строку.
Но раз уж мы в разделе "для новичков", разрешите задать пару вопросов?
1. Какой смысл использовать определение 'static' на этапе объявления глобальных переменных? (строки 19, 29) В документации на Arduino сказано, что такое определение имеет смысл только при определении переменной в подпрограммах, чтобы запоминалось её последнее состоянии при новом входе в эту самую подпрограмму? Глобальная переменная ведь всегда остается глобальной для всех подпрограмм. Разве нет?
2. Совсем не понял, что происходит в строке 24. Почему простого sizeof от массива недостаточно для определения числа колец? Зачем вы его еще делите на число светодиодов в первом кольце?
3. Выбранное вами обозначение RGB сбило с толку абсолютно. Голову сломал, при чем здесь определение цветов. Учитывая, что для управления светодиодами я практически везде использую HSV-пространство.
спасибо, что не потрудились
Это «да» - не потрудился.
1. Какой смысл использовать определение 'static' на этапе объявления глобальных переменных? (строки 19, 29) В документации на Arduino сказано
Я не знаю, где что сказано. static в глобальном контексте ограничивает область видимости переменной данным файлом и делает её невидимой в других файлах.
Общее правило в программировании: не расширять область видимости без необходимости. Это переменная используется (планируется к использованию) в других файлах проекта? Нет? Значит надо объявлять static.
Кроме очевидностей (типа в другом файле имеет право быть переменная с таким же именем), это даёт и другие приятные бонусы. Например, если компилятор поймёт, что Вы эту переменную не используете, он её смело выбросит, чтобы память не жрала, а если она не static, то выбрасывать нельзя – вдруг в другом файле используется. Справедливости ради надо сказать, что в умных современных системах таки выбросится (не компилятором, но не суть), но в любом случае это просто полезная практика – никогда не расширять область видимости без необходимости.
2. Совсем не понял, что происходит в строке 24. Почему простого sizeof от массива недостаточно для определения числа колец? Зачем вы его еще делите на число светодиодов в первом кольце?
А Вы невнимательно смотрите, потому и непонятно. Кто Вам сказал, что я делю на число светодиодов? Смотрите внимательнее. Я делю размер всего массива на размер одного элемента – получаю количество элементов в массиве. А «простой sizeof», как Вы выразились, даёт Вам не количество элементов в массиве, а количество байтов, которые массив занимает. В данном конкретном случае это одно и тоже, но если у Вас массив int или long или там вообще структур каких-нибудь, то количество байтов и количество элементов – две большие разницы. Такая форма «размер массива поделить на размер элемента» - универсальна и работает всегда, для любых массивов. Вот её всегда и применяют.
3. Выбранное вами обозначение RGB сбило с толку абсолютно. ... использую HSV-пространство.
Не моя проблема, я лишь пример писал :)
2 ЕвгенийП:
1. Я правильно понял, что если у меня скетч - один (в виде одного файла .ino), то и смысла использовать static при объявлении глобальных переменных нет?
2. Очень полезное замечание, спасибо!
3. "Не следует указывать старожилам, для чего нужен форум, и что на нем следует делать." - первым пунктом в прикрепленном топике, так что я промолчу.
1. Я правильно понял, что если у меня скетч - один (в виде одного файла .ino), то и смысла использовать static при объявлении глобальных переменных нет?
Неправильно. Во-первых, файл у Вас не один - вам система ещё штуки три-четыре подсовывает, но дело не в этом. Такие вещи должны делаться на автомате - всегда. Не собираешься использовать в других файлах - делай static, не собираешься изменять - объявляй const, нужна только в одной функции - в ней и объявляй, а не глобально.
Делать так всегда (и никогда по-другому) самый надёжный способ не забыть сделать это тогда, когда это действительно нужно - это просто очень полезные привычки.
А кроме того, программы имеют привычку модифицироваться. И чем более стандартно и правильно (даже избыточно правильно) они написаны, тем безболезненнее проходит этот процесс. Вот с Вашим прошлым вопросом - я написал "
sizeof
(RingSizes) /
sizeof
(RingSizes[0])
" хотя отлично знаю. что знаменатель в данном случае равен 1 и смысла в делении нет, но я всегда так пишу. А через год у Вас появится какое-то мегакольцо из 300 светодиодов и Вам придётся поменять тип массива RingSizes с uint8_t на uint16_t. Если бы я не написал этого деления, Вам бы и здесь тоже менять пришлось бы (наверняка бы забыли!), а так, поменяете только тип массива, а подсчёт элементов останется правильным потому, что изначально был правильно написан.И вообще, делать что-то всегда одинаково - это профессиональное поведение. Вы можете себе представить профессионального электрика, который посадит фазу на жёлто-зелёный провод? Даже во временной проводке, которую он завтра разбирать будет? Вот и я нет. Он всегда на жёлто-зелёный провод заводит землю. Почему? А потому что всегда так делает.
Программирование тоже профессиональная деятельность, и в нём тоже есть профессиональное поведение.
"Не следует указывать старожилам, для чего нужен форум, и что на нем следует делать."
Это точно, особенно таким стервозным и злопамятным, как я - это Вы правильно поступили.
To ЕвгенийП:
Хорошо, тогда "вопрос на засыпку". Почему вот в этом скетче - простом и вроде бы как совершенно очевидном, если в 3-ей строке убрать 'const', то Arduino IDE ругается с указанием на 10-ю строку "error: array bound is not an integer constant before ']' token"
https://prog-cpp.ru/c-massiv/
To qwone:
Спасибо за ссылку, но там нет ответа на мой вопрос.
Есть, просто Вы читать не умеете.
А что, из сообщения непонятно? Хочет система видеть константу, а Вы слово const убрали и пихаете вместо константы переменную. Вот и ругается.
Почему вот в этом скетче - простом и вроде бы как совершенно очевидном, если в 3-ей строке убрать 'const', то Arduino IDE ругается с указанием на 10-ю строку "error: array bound is not an integer constant before ']' token"
Опасается IDE, что переменную коварно измените, а перекомпилироваться на ходу она не умеет. А виноват кто будет? Правильно, Си.))))
2 ЕвгенийП:
Я понимаю конечно, что унизить и поглумиться над новичком - это как сигаретка к утреннему кофию, но ткните меня носом, т.е. приведите цитату с той страницы на prog-cpp-dot-ru, в которой прямо указывается, что размерность массива должна объявляться именно константой, а не вычисляемой переменной.
Кроме этого, в вашем же собственном примере из #11 в данном треде, вы объявляете массив в 61-ой строке через переменную, которую перед этим вычиляете в строках с 35-ой по 56-ю, и в Вашем примере это не является ошибкой.
Поэтому я повторяю свой вопрос, т.к. ответа на него так не было дано: почему в данном конкретном примере компилятор требует именно константу?
С одной стороны песочница, а с другой - хамство в адрес "старших по званию"... Я бы, конечно, потер, но Евгений у нас добрый...
--------------
1. В стандарте С требуется, чтобы размер массива, который объявляется, был известен на момент компиляции, а не момент вычислений.
2. При желании можно использовать иные методы создания массива, например оператор new, тогда требуется значение, известное на момент исполнения кода.
3. В строке 61 у Евгения мало того, что не объявление, а создание объекта с помощью new, так еще и не с переменной, а насквозь константной размерностью. Все, что определено через #define, как бы сложно оно не выглядело - это константа, вычисляемая в момент компиляции.
-------------------
И еще раз отсылаю к топику Печоницы: Тут не курсы по языку Си и не справочная. Не на любой дурацкий вопрос новичка есть желающие отвечать. Жене нужно памятник поставить, за терпение.
Я понимаю конечно, что унизить и поглумиться над новичком - это как сигаретка к утреннему кофию
ткните меня носом, т.е. приведите цитату с той страницы на prog-cpp-dot-ru
Давайте, сразу договоримся о трёх вещах:
1.
Я над Вам абсолютно никак не глумлюсь. Это моя нормальная манера общения. Если она Вам неприятна, не общайтесь, но, пожалуйста, не обвиняйте меня в том, чего я не делаю.
2.
Не знаю, какова Ваша профессия, возможно, Вы специалист по логистике, варке стали или разведению животных, а я специалист по языкам программирования (если быть точнее, то по языковым средствам хранения данных в параллельных языках, но для любительского форума такая узкая специализация - перебор), у меня есть научные статьи, я бываю на конференциях по этой тематике, в общем я этим занимаюсь - это моя профессия. А потому, когда мне нужна информация о каком-то языке, мой источник - не википедия и не prog-cpp-dot-ru, а официальное, формальное описание языка. Если речь о языке С++, то это документ ISO/IEC 14882:2017. В него я могу Вас ткнуть носом, пожалуйста - п. 11.3.4(1) (стр. 208). Там сказано, что в квадратных скобках должно быть константное выражение, приводимое к типу std::size_t и его значение должно быть больше 0. Наверняка, такая информация есть и на указанном Вами сайте, но искать её ради того, чтобы привести Вам пруф я не буду, уж извините (на эту тему моё следующее замечание).
3.
По поводу пруфов. Как я уже сказал, я специалист по языкам и потому совершенно искренне считаю, что ссылка на то, что «я так сказал» - вполне достаточный пруф, по крайней мере на любительском форуме. Да, некоторые статьи в Интернете написаны хорошими специалистами, с этим никто не спорит, но для 99% (если не больше) материалов из Интернета, мои слова - более весомый пруф, чем эти материалы, уж поверьте мне. Я готов отвечать на Ваши вопросы, но искать для Вас подтверждения моим словам в Интернете (и уж тем более опровергать бред, который Вы там, возможно, найдёте), я не буду - извините. Я готов потратить время на ответы Вам, но не готов тратить его на борьбу с ветряными мельницами.
Возможно, эти слова Вам кажутся самовосхвалением и хвастовством - ради Бога, Вы имеете право на любое мнение и на такое в том числе. Но я действительно так считаю, и если Вы считаете по-другому - это Ваше право, но не моя проблема. Просто , хотите задавать вопросы - я отвечу, но от поиска подтверждения моим слова в Интернете увольте. Ищите сами.
Если Вы согласны продолжать общение на таких условия, давайте продолжать. Нет - извините.
Да, неужели?
Вы когда нибудь писали что-нибудь вроде
И что, по-Вашему LED_PIN здесь переменная? Вы можете в программе измненить её значение? А ведь моя TotalLedsтоже определена оператором #define. Так с чего ей быть переменной?
То, что определяется #define является макросом времени компиляции. Оно вычисляется на этапе компиляции и в код подставляется уже готовое числовое значение. Т.е. это даже не константа (в понимании языка) - это литерал, т.е. готовое число!
Поэтому я повторяю свой вопрос, т.к. ответа на него так не было дано: почему в данном конкретном примере компилятор требует именно константу?
Ответ был дан, просто Вы ему не поверили. Там необходима константа и это прямо написано в п. 11.3.4(1) ISO/IEC 14882:2017 на стр. 208. А в моём примере была вовсе не переменная, а литерал.
Надеюсь, теперь проянилось? Если нет, спрашивайте, только без наездов и требований ссылок на различные помойки.
И, да, уж коль на то пошло, в компилятое gcc, который испольуется в Arduino IDE ,есть расширение (т.е. возможность не предусмотренная стандартом языка), позволяющее использовать переменные в размерности массива, но не везде и не всегда. В данном контектсе (глобально объявленный массив) - нельзя.
Уважаемый ТС, а чем Вам двухмерные массивы не угодили? Чего уж проще int Massiv[8][34]?
Уважаемый ТС, а чем Вам двухмерные массивы не угодили? Чего уж проще int Massiv[8][34]?
Ну, на это я могу ответить. Двумерный массив всегда квадратный, потому неминуем перерасход памяти.
Допустим, что кольца, как в моём примере, содержат 8. 4, 2 и 1 светодиод. Потребуется массив [4][8], т.е. 32 значения, а светодиодов реально только 15. Более половины памяти псу под хвост.
Ну, на это я могу ответить. Двумерный массив всегда квадратный, потому неминуем перерасход памяти.
Допустим, что кольца, как в моём примере, содержат 8. 4, 2 и 1 светодиод. Потребуется массив [4][8], т.е. 32 значения, а светодиодов реально только 15. Более половины памяти псу под хвост.
Евгений, ну если-бы я здесь увидел программу запуска ракеты, то я бы с Вами согласился, но то что представил ТС и 10% памяти не жрет. Так чего экономить с ущербом для простоты?
Не, ну если ресурсов хватает, то ничего не имею против. (я не маньяк оптимизации, как некоторые коллеги :)))
Я премного благодарен всем, кто находит время и желание отвечать на ньюбаевские вопросы. Особенно, когда ответ на вопрос требует некоторых усилий - написания кода, его проверки и т.п. Это все прежде всего требует времени, которого ни у кого из нас нет. Я готов благодарить по многу раз каждого, кто решится на это неблагодарное дело. Я очень ценю это, ибо делается это все на голом энтузиазме, в свободное время, и, я глубоко в это верю, из самых благих побуждений. Поэтому еще раз выражаю свою глубочайшую признательность!
Совершенно понятно, что в этом разделе не обязаны учить основам языка Си, и уж совершенно точно никто не обязан в режиме 24/7 отвечать на любые самые глупые вопросы. Но этот форум, как и сайт целиком - про Ардуино, систему, которая и задумывалась изначально, как самая простейшая для освоения _основ_ работы с микроконтроллерами, а данный раздел - ДЛЯ НОВИЧКОВ, т.е. ньюбаев из ньюбаев. Повторю еще раз раздельно, чтобы получше донести свою мысль: это - раздел для _новичков_ на форуме, посвященном _основам_ работы с микроконтроллерами. Где же еще задавать наши глупые (с вашей точки зрения) вопросы?
Дорогие, многоуважаемые сторожилы! Ваш опыт - это бесценное сокровище! Ваша помощь нам - новичкам - просто необходима! Но если уж вы беретесь её оказывать, пожалуйста, делайте это в понятно НАМ форме, на понятном НАМ языке! Очевидно, что вам и проще, и привычнее, и удобнее писать код так, как вы уже привыкли, по тем правилам, которые вы выработали годами, но для нас это выглядит нечитаемо, за гранью нашего понимания. Это для вас, уже много лет варящихся в этом котле, все очевидно и понятно, а для нас, начинающих, большие строки кода с сокращениями и краткой записью - китайская грамота. Ведь основа-основ любого процесса обучения - последовательное движение от простого к сложному. Человек должен быть готов воспринять ту информацию, которая ему выдается, иначе она просто "уйдет в песок". Ну нельзя умирающего от голода кормить пирогами и шашлыком - он помрет от несварения. Никто не начинает изучение основ Английского языка с герундия и модальных глаголов. Учитывайте, пожалуйста, при своих ответах наш уровень "чуть выше плинтуса", и наша благодарность к вам просто не будет иметь границ (в пределах разумного, разумеется).
Спасибо за то, что выслушали и еще раз спасибо за вашу бесценную помощь!
Про массивы лично у меня [пока] вопросов больше нет.
To mykaida:
Да мне как раз и нужно объявить такой массив. Именно двумерный. Но только проблема в том, что сделать это нужно (точнее, хочется) не руками, а путем неких вычислений из параметров (точнее, из числа записей и значения этих записей) одномерного массива.
Многоуважаемый ЕвгенийП показал путь, как это можно решить - в сообщении #11 строки кода ##35-56, исходными данным для чего используется строка #19. Полностью и до конца осознать этот код у меня пока знаний не хватает, но я попробую это использовать.
а данный раздел - ДЛЯ НОВИЧКОВ, т.е. ньюбаев из ньюбаев. Повторю еще раз раздельно, чтобы получше донести свою мысль: это - раздел для _новичков_ на форуме, посвященном _основам_ работы с микроконтроллерами.
Повеселили.)))) Вы сейчас попытались объяснить создателям этого раздела, для чего они его создавали.))))
Повеселили.)))) Вы сейчас попытались объяснить создателям этого раздела, для чего они его создавали.))))
Нет, ну право... Это на самом деле не очень смешно. Список из заглавного топика всего того, что должен знать новичок, насколько обширен, что если это все знать, то и вопросов в данном разделе возникать не будет. По идее, хорошего усвоения азов (отсюда, или хотя бы даже отсюда) уже должно быть достаточно, чтобы считаться "начинающим". Поэтому вполне логично, что этот самый начинающий ответов ожидает именно в плоскости этих знаний - с нормальным синтаксисом всех комманд и в пределах этого уровня. Нельзя требовать от новичка знаний всех тонкостей языка Си или отраслевых стандартов. Он потому и "новичок", что у него нет этих знаний. И если уж ответ на заданный новичком вопрос выходит за рамки базового уровня (а так, по идее, и должно случаться в большинстве случаев), то это стоит отдельно подчеркнуть и акцентировать на этом внимание. Тогда, и только тогда, ответ будет понят и принят. Причем, принят с большой благодарностью. Иначе получается издевательство.
Этот урок я усвоил, когда дочке то ли в 3-ем, то ли в 4-ом классе по Математике задали задачу, которая (с моей точки зрения) крайне просто и легко решалась с помощью системы уравнений из двух переменных. Элементарно! Выразить 'a' через 'b' и найти по нему 'c'. Но дочь разревелась и ушла от папы, потому что "Нас в школе учили не так!" И как бы я не объяснял, что так решить проще и лучше, мой ответ не подходил, потому что уровень был - другой.
Здесь, на этом форуме, постоянно происходит абсолютно то же самое. Едва не в каждом треде стон и крики начинающих: "Да объясните же мне нормально! Я ничего не понимаю!" А в ответ: "Да ты просто понимать не хочешь! Мы тебе уже все объяснили!"
Нет, уважаемые Господа, нифига вы не объяснили! Вы показали уровень своих знаний, но не смогли дать ответ на заданный вопрос. Это разные вещи: показать, как эту задачку ты бы решил сам, со своим уровнем знаний, и дать правильный ответ на заданный вопрос. Вот в этом главная причина большинства споров и ломания копий, а не в глупости новичков или невежливости старожилов.
И вы меня, конечно, извините, но "Я так пишу, потому что только это считаю правильным и только так и надо писать, а как там что заявлено у Arduino - это меня не касается. У меня опыт, сын ошибок трудных." - это нифига не объяснение. Это позерство и ничего более, даже если все заявленно и есть чистейшая правда. Ибо со стороны новичка такой ответ выглядит чистым издевательством, т.к. ответа на вопрос нет, а тебя еще и унизили.
Поэтому я в который уже раз повторяю свою ПРОСЬБУ или даже МОЛЬБУ: уважаемые господа Старожилы, при ответах учитывайте, пожалуйста, низкий уровень знаний спрашивающих. Заранее БОЛЬШОЕ СПАСИБО!
И вы меня, конечно, извините, но "Я так пишу, потому что только это считаю правильным и только так и надо писать, а как там что заявлено у Arduino - это меня не касается. У меня опыт, сын ошибок трудных."
Давайте не будем передёргивать. Я вам написал вовсе не так, а вот так:
Я не знаю, где что сказано. static в глобальном контексте ограничивает область видимости переменной данным файлом и делает её невидимой в других файлах.
разве я не объяснил почему именно я так пишу? Или я привлёк какие-то непонятные термины? Что в моём объяснении бло снобисткого и неясного?
Простите, но не разочаровывайте меня.
To mykaida:
Да мне как раз и нужно объявить такой массив. Именно двумерный. Но только проблема в том, что сделать это нужно (точнее, хочется) не руками, а путем неких вычислений из параметров (точнее, из числа записей и значения этих записей) одномерного массива.
Уважаемый, массив придуман именно для того, чтобы меньше думать. Например 1 ряд 8 диодов, 2 ряд 24, 3 - 56. Создаем массив byte LED[3][56]. А далее обращаетесь по номеру ряда и номеру светодиода в ряде.
Про какой одномерный массив вы говорите? Количество светодиодов в ряду? Так создайте массив NLED[i], где i - номер ряда и обращайтесь в цикле к LED[i][n] for (n=0; n<NLED[i]; n++){
Для особо жадных - пустые элемента массива тоже можно использовать. Напрмер в приведенном мной примере можно написать предпроцессору #define hernia LED[1][8], #define hernia1 LED[1][9]...#define herniaN LED[1][55]
Кароче, Вы опять фсе ниправильна памагаити беднаму навичку!
Научитеись наканец правильна памагать!
Второй день читаю ТС вашу забавную историю. Я делал светодиодный куб на 125 пикселей и конечно, управлять пикселями куба по их порядковым номерам в ленте неудобно, поэтому рационально N=(x)+k*(y)+k*k*(z) где k=5 число пикселей в ребре куба, а x,y,z их координаты. Их значения в круглых скобках можно задавать произвольным образом. Они могут менятся от (0,0,0) до (4,4,4). Может и тут надо аналогично помыслить о переводной формуле из "координат самопридуманных" в номер пикселя в ленте?
Может и тут надо аналогично помыслить о переводной формуле из "координат самопридуманных" в номер пикселя в ленте?
Так уж советовали. Функция singleLed в моём примере именно это и делает. Но тут, похоже, Владимир прав - неправильно помогаем :)
Второй день читаю ТС вашу забавную историю. Я делал светодиодный куб на 125 пикселей и конечно, управлять пикселями куба по их порядковым номерам в ленте неудобно, поэтому рационально N=(x)+k*(y)+k*k*(z) где k=5 число пикселей в ребре куба, а x,y,z их координаты. Их значения в круглых скобках можно задавать произвольным образом. Они могут менятся от (0,0,0) до (4,4,4). Может и тут надо аналогично помыслить о переводной формуле из "координат самопридуманных" в номер пикселя в ленте?
Не, уважаемый, у вас-то куб, а тут круг (слышали что-нибудь про квадратуру круга?) Вы хоть раз попытайтесь взять косинус арктангеса нуля и все поймете :))
Этот урок я усвоил, когда дочке то ли в 3-ем, то ли в 4-ом классе по Математике задали задачу, которая (с моей точки зрения) крайне просто и легко решалась с помощью системы уравнений из двух переменных. Элементарно! Выразить 'a' через 'b' и найти по нему 'c'. Но дочь разревелась и ушла от папы, потому что "Нас в школе учили не так!" И как бы я не объяснял, что так решить проще и лучше, мой ответ не подходил, потому что уровень был - другой.
Тут Вам просто надо ответить на два вопроса:
1) Кому нужно, чтобы Ваша девочка научилась решать задачу?
2) Кому нужно, чтобы Вы научились программировать на Си?
Поэтому я в который уже раз повторяю свою ПРОСЬБУ или даже МОЛЬБУ: уважаемые господа Старожилы, при ответах учитывайте, пожалуйста, низкий уровень знаний спрашивающих. Заранее БОЛЬШОЕ СПАСИБО!
По нику уровень не виден.
Совершенно понятно, что в этом разделе не обязаны учить основам языка Си, и уж совершенно точно никто не обязан в режиме 24/7 отвечать на любые самые глупые вопросы. Но этот форум, как и сайт целиком - про Ардуино, систему, которая и задумывалась изначально, как самая простейшая для освоения _основ_ работы с микроконтроллерами, а данный раздел - ДЛЯ НОВИЧКОВ, т.е. ньюбаев из ньюбаев. Повторю еще раз раздельно, чтобы получше донести свою мысль: это - раздел для _новичков_ на форуме, посвященном _основам_ работы с микроконтроллерами. Где же еще задавать наши глупые (с вашей точки зрения) вопросы?
Посмотрев на дату моей регистрации, Вы можете узнать, когда новичком на форуме (и в Ардуино) был я. Поверьте, ни я, и нкто из моих оппонентов в дискуссиях не подвергал сомнению мой статус новичка. И я всегда терпеливо отвечал на "наезды" старожилов, не пытаясь им указывать, как им следует себя вести. Хотя мой опыт в программировании на тот момент составлял 37 лет, а в схемотехнике - более 20.
Причина, на мой взгляд, очевидна: можно быть специалистом как в области программирования, так и в области схемотехники, но при этом совершенным профаном в области Ардуино или микроконтроллеров. Потому что это совершенно другая область, которая подразумевает знание как программирования, так и схемотехники, но далеко не ограничивается ими.
Я клоню к тому, что любой вопрос рациональнее всего задавать на специализированном форуме: вопрос по схемотехнике - на форуме по схемотехнике, вопрос по прошграммированию - на форуме по программированию, а на данном форуме - вопросы по Ардуино. Т.е. если у Вас вопрос именно по языку программирования, а не по особенностям его применеиня для МК, то и задавыать его нужно не здесь, а на специализированном форуме.
Вопросы не по теме всегда вызывают раздражение, а если задающий такие вопросы еще и начинает "качать права", требовать не просто краткого ответа либо отсылки к документации, а подробного разбора подобных вопросов на уровне новичка, не кажется ли Вам, что это уже черезчур?