Добрый день!
Суть вопроса: имеется некая процедура TEST, аргументом которой является число k. В зависимости от значения k нужно выполнять много одних и тех же действий, но с различными глобальными переменными (для примера: a, b, c).
Как я оформляю это сейчас:
void TEST (byte k) {
switch (k) {
case 1: a = 0; a = 1; a = 2; a = 3; break; //действия указаны образно, для примера
case 2: b = 0; b = 1; b = 2; b = 3; break;
case 3: c = 0; c = 1; c = 2; c = 3; break;
}
}
Вопрос: можно ли создать какой-то псевдоним (pse*), присваивать ему имена переменных внутри кода и использовать его в последствии вместо имен переменных? Т.е. что я хотел бы получить на выходе:
void TEST (byte k) {
switch (k) {
case 1: pse* = a; break;
case 2: pse* = b; break;
case 3: pse* = c; break;
}
pse = 0; pse = 1; pse = 2; pse = 3; //вот тут надо чтобы в зависимости от значения k выполнялись действия с переменными a b или c
}
P.S. если что, можете просто подсказать как это правильно называется, а нагуглить я сам нагуглю. Просто хз как это правильно называть, чтоб запрос сформировать
PP. S. Пример обобщенный. Есть конечно и другие способы оптимизировать мой код в реальной задаче, но такой, в случае если это возможно, импонирует мне больше всего.
PPP. S. Почему бы просто не использовать доп. переменную, а не выдумывать псевдонимы? Потому что в реальной задаче переменные a b c - это массивы. Т.е. там надо создавать еще один массив той же разномерности - не хочу, в целях экономии памяти. А так можно было бы обойтись без лишнего массива
Выполнять действия внутри процедуры с глобальными переменными - это гавнокод. В правильном коде процедура должна быть самодостаточным блоком кода. То есть работать только с парметрами вызова и локальными переменными.
Передавайте свои переменные внутрь процедуры как параметры - это и будет то, что вы называете “псевдонимами”
И снова здравствуйте, мой дорогой и уважаемый друг снова мы с вами встретились на просторах данного форума. Как помните, я больше в машинах разбираюсь, чем в программировании, поэтому не сердчайте.
Я намеренно не указывал конкретный пример, так как будет 100 советов как оптимизировать код иначе, а меня в целях образования интересует возможность реализации именно этого метода
Скорее наоборот, вы из тех, кто ко мне наиболее адекватно отсился относительно других обитателей форума, но можете и в игнор сунуть, ежели вам там угодно)
Если что это я вам пару лет назад TLCшки отправлял на проверку, а в прошлом году устроил срач в теме про соединение контакта BAT DS1307 с пином 3v3 ардуины)
void pse(byte x)
{
x = 0;
x = 1;
x = 2;
x = 3; // действия указаны образно, для примера
}
void TEST(byte k)
{
switch (k)
{
case 1:
pse(a);
break;
case 2:
pse(b);
break;
case 3:
pse(c);
break;
}
}
Хорошо, согласен, это один из способов оптимизации и тут он сработает, согласен. Но пример я дал максимально упрощенный. Вопрос про “псевдонимы” я задал на 50% для практического применения и на 50% из образовательных соображений. Внутренний голос подсказывает, что С как-то позволяет использовать псевдонимы, присваивая им имена переменных в теле кода, а потом использовать псевдоним вместо имени переменной.
Окей, открою ящик пандоры и распишу реальную задачу, но сейчас посыпется сотня альтернативных вариантов оптимизации кода, но таким образом я закрою вопрос только на 50% - практическую часть, а теоретическая останется открытой.
Проект банально простой: часы на адресных светодиодах, из которых сформированы 4 / 6 семисегментных разрядов (с секундами и без). Каждый разряд - это массив из 7ми светодиодов. В программе они определяются объектами библиотеки FastLED и представляют из себя 4 / 6 массива по 7 элементов:
LED_H[7] - первый разряд (десятки часов)
LED_h[7] - второй разряд (единицы часов)
LED_M[7]
LED_m[7]
LED_S[7]
LED_s[7]
Я создал процедуру DRAW с аргументами P и N, где P - разряд, а N - выводимая цифра. Соответственно вызов в теле программы DRAW(1,2) - должен нарисовать в первый разряд цифру “2”.
…и так далее, ещё для массивов LED_S и LED_s и потом ещё для остальных цифр от 1 до 9.
Т.е. я использовал case для выводимых цифр N, а внутри кейса в зависимости от значения аргумента P (через if, чтоб не делать вложенные кейсы) включаю нужные светодиоды в разных массивах.
Понимаю, что решение не самое оптимальное, но только не надо пожалуйста говорить, что уже есть куча готовых решений. Я не люблю ими пользоваться, так как интересней самому, да и разбирать в этом коде мне будет потом проще, потому что сам же его и писал )
Знаю несколько способов по оптимизации этого г***окода: с использование массива-маски или даже просто битовой маски, но в голову закралась идея с псевдонимом, что было бы не плохо реализовать это примерно так:
Может я и дохрена хочу и так нельзя - если таких “псевдонимов” не существует, то вопрос снят ) А оптимизировать код иными путями думаю я тоже смогу, немного посидев и подумав. Просто пока не было времени на то самое “посидеть и вдумчиво подумать”, а опыта чтоб сходу написать оптимально, как понимаете, не много )
так можно, но сложно. Если хотите подробнее - покажите как описаны массивы светодиодов.
Значительно проще описать все шесть массивов как единую ленту и выводить цифры в нужную позицию по смещению диода
Это реально тупой способ. Зачем изобретать велосипед?
Один сегмент - это один байт, в котором нулями и единицами закодировано, какие светодиоды должны светиться. Вот так это делается
//
// A
// ---
// F | | B
// -G-
// E | | C
// ---
// D
// Здесь A .. G - соответствующие светодиоды
const uint8_t digitToSegment[] = {
// XGFEDCBA
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
0b01110111, // A
0b01111100, // b
0b00111001, // C
0b01011110, // d
0b01111001, // E
0b01110001 // F
};
Т.е. один массив, в котором закодированы все символы от 1 до F
Это основной способ работы с семисегментными индикаторами. Возьмите любую библиотеку да хоть для TM1637 и изучите. Не изобретайте велосипед. А если уж совсем неймется - ниипите людям моск, разгребайте самостоятельно
Ну там микрухи всетаки неисправные скорее, в том нет вашей вины, так что нечего стыдится.
Что до массивов - тоже размышлял эту сторону, но разные разряды подключены к разным пинам ардуино (D2 D3 D4 D5), а при создании объекта там указывается пин, к которому подключена линейка светодиодов. Я в недра библиотеки не лез, для меня это темный лес до небес, я просто нашел как создавать ленты в программе и как их включать)
Можно конечно изменить аппаратную часть и реализовать все светодиоды как одну цепочку из 28 светодиодов (а не 4 по 7, как у меня) и сделать один массив и запрограммировать сдвиги для каждого разряда, но рука взяла почему-то 4 по 7… Возможно в будущем переделаю на 1 х 28
насколько я помню, в Фастледе такие отдельные цепочки светодиодов, подключенные к разным пинам - можно описать как целую ленту.
Но в принципе, можно сделать на отдельных массивах с использованием ссылок. Только вывод на ленту хорошо бы переписать, как @v258 советует, а то от этих одинаковых кейсов противно становится
Ну одинаковые кейсы в процессе работы часов никто не видит, а лишний массив 7 байт схавает
На самом деле завтра переделаю на массив - маску, на работе в свободное время просто этим занимаюсь, а сегодня не успел)
А что значит “на отдельных массивах с использованием ссылок”?