Всем привет! Помогите пожалуйста разобраться в вопросе программирования. А именно, как-то уменьшить размер структуры, в которой содержится массив строк. У меня в проекте используется такая структура, хранящая меню с названиями ручек управления: Код (C++): struct strSetCC { byte CC[4]; //Номера MIDI СС, соответствующие ручкам настройки, при выборе раздела настроек byte Res[4]; //Шаг ручки char* PotName[4]; //Названия ручек }; strSetCC SetCC [10]; Пользоваться этим мне очень удобно, т.к. можно очень просто задать и получить в цикле названия ручек управления: SetCC[Номер настройки].PotName[Номер ручки] = Имя; - очень удобно. Но занимает это все добро почти всю память контроллера. У меня названия ручек точно не будут более 4 символов. Поэтому я полагаю, что можно задать массив строк таким образом: char PotName[4][4]; Но я не могу понять как с этим удобно работать. Или какую-то промежуточную функцию написать, чтобы можно было одной строкой по индексам задать значение? Или особо ужать char* PotName[4]; не получится? Буду рад любому совету, спасибо.
то, что описано - занимает всего 160 байт. Что за контроллер у вас. что 160 байт это "почти вся память"?
Я храню там имена ручек настройки: SetCC[Номер настройки].PotName[Номер ручки] = Имя; SetCC - это массив структур.
У меня Амперка Iskra nano Pro. Да, одна такая структура занимает не много. Но у меня массив из этих структур. И есть ещё другие массивы. Если приводить полный код объявления глобальных переменных, то вот он: Спойлер: Код объявления переменных Код (C++): struct strPot { byte analogInPin; //Номер Пина int ValAnalog; //Аналоговое значение потенциометра 1 byte ValMIDI; //MIDI значение потенциометра 1. От 0 до 127 byte PrValMIDI; //Предыдущее значение для устранения дребезга потенциометра byte CC; //Номер CC byte Res; //Точность/шаг значения }; strPot Pot[3]; struct strSetCC { byte CC[4]; //Номера СС, соответствующие ручкам настройки, при выборе раздела настроек byte Res[4]; //Шаг ручки char* PotName[4]; //Названия ручек //char PotName[4][4]; byte ValName[4]; //Если 0, то выводится числовое значение, если больше - выводятся спец. названия }; strSetCC SetCC [10]; struct strValName { byte BorderVal[9]; //Граничное значение для этого имени char* Name[9]; //Названия этого значения Синус, Треугольник и т.д. }; strValName ValName[3];
Таким образом сэкономите примерно 80 байт, которые тратились на хранение указателей. Вот только массив должен быть размером равным количеству символов + 1, т.е.: Код (C++): struct strSetCC { byte CC[4]; //Номера MIDI СС, соответствующие ручкам настройки, при выборе раздела настроек byte Res[4]; //Шаг ручки char PotName[4][5]; //Названия ручек, при условии что длина названия не более 4-х символов }; Есть подозрение, что можно сэкономить гораздо больше памяти. Если есть не изменяемые в процессе работы прошивки данные, то их можно из оперативной памяти перенести в постоянную.
На lcd дисплей выводятся. Я так понимаю, вы хотели предложить удалить переменные, если они никуда не выводятся или что это меняет? )
Тогда вот пример: Спойлер: Пример Код (C++): // №№ CC Точность Ручка Значения iniSet(0,0, 16, 0, "", 0);// iniSet(0,1, 77, 15, "Wave", 1);// iniSet(0,2, 14, 0, "Ctrl1", 0);// iniSet(0,3, 15, 0, "Ctrl2", 0);// ... ... ... void iniSet(byte nSet,byte nCtrl , byte nCC, byte nRes, char* nName, byte nValName) { SetCC[nSet].CC[nCtrl] = nCC; SetCC[nSet].Res[nCtrl] = nRes; SetCC[nSet].PotName[nCtrl] = nName; SetCC[nSet].ValName[nCtrl] = nValName; } Там все имена разные. 32 разновидности в разных комбинациях. Поэтому я их сохраняю в массиве и использую, ссылаясь на элемент массива по индексу.
Да, это фактически не изменяемые данные. Это настройки, которые инициализируются при старте и далее мне нужно выводить на lcd экран названия в зависимости от выбранной настройки. Поясните пожалуйста, под постоянной памятью вы имеете ввиду работу с SD картой или что-то другое?
Все, понял, http://arduino.ru/Tutorial/Memory Ок, большое спасибо всем за ответы! Дальше, думаю, решу вопрос.
Ну тогда их можно поместить во flash (см. PROGMEM в avr/pgmspace.h) и статически инициализировать в коде. Могут возникнуть проблемы с инициализацией строковых литералов -- при статической инициализации строковые литералы просто так во flash не переносятся. Если не справитесь, могу подсказать как это сделать.