область видимости динамический String array
- Войдите на сайт для отправки комментариев
Чт, 19/11/2015 - 15:35
если сделать глобальный массив то не видит содержимого a, b, c,
пример
String a, b, c = "";
String abc [] = {a, b, c};
void setup() {
}
void loop() {
}
а если локально то все ок
String a, b, c = "";
void setup() {
}
void loop() {
}
void abc() {
String abc [] = {a, b, c};
]
в чем проблема?
Кто не видит? Кого не видит? Как удалось выяснить, что не видит? Приведите скетч из которого явно следует, что кто-то кого-то не видит. Приведёте скечт, иллюстрирующий проблему - тогда и поговорим.
String a, b, c = ""; String abc [] = {a, b, c}; //глобальная область видимости void setup() { Serial.begin(9600); } void loop() { a = "1234567890"; //переменные a, b, c b = "0987654321"; c = "admin"; for (int i = 0; i < 3; i++) { Serial.println(abc[i]); // печатает пустоту } }так не работает
String a, b, c = ""; void setup() { Serial.begin(9600); } void loop() { a = "1234567890"; b = "0987654321"; c = "admin"; abc (); } void abc () { String abc [] = {a, b, c}; // локальная область видимости for (int i = 0; i < 3; i++) { Serial.println(abc[i]); // печатает все как надо }так работает
String a, b, c = ""; String abc [] = {a, b, c}; //глобальная область видимоститак не работает
ясен пень, что не работает - помоги мне развидеть строку, где символами являются объекты класса.
String abc [] = {String a, String b, String c};да понял уже
можно и так
String a, b, c = ""; String abc [3]; void setup() { Serial.begin(9600); } void loop() { a = "1234567890"; b = "0987654321"; c = "admin"; abc[0] = a; abc[1] = b; abc[2] = c; for (int i = 0; i < 3; i++) { Serial.println(abc[i]); // печатает все как надо }// String a, b, c = ""; String abc[3]; void setup() { Serial.begin(9600); } void loop() { // a = "1234567890"; // b = "0987654321"; // c = "admin"; // abc[0] = a; // abc[1] = b; // abc[2] = c; abc[0] = "1234567890"; abc[1] = "0987654321"; abc[2] = "admin"; for (int i = 0; i < 3; i++) { Serial.println(abc[i]); // печатает все как надо } }в том то и вся соль, что a, b, c меняющиеся переменные считаные из eeprom и в процессе работы могут менятся и записываться в eeprom, то я для примера привел
в том то и вся соль, что a, b, c меняющиеся переменные считаные из eeprom и в процессе работы могут менятся и записываться в eeprom
ок
Значит история ещё не закончилась, без попкорна не обойтись.
закончилась - дальше можно выпиливать избыточность по реальному коду.
Присаживайся пока, попкорна пожуем, человек держит в массиве копии переменных a, b, c. Поменяет a, b или c, а в массиве ничего не изменится. Хотя нужен массив указателей или ссылок на переменные a, b, c, тогда и заработает как надо.
Не-а! Не работает. Вы не то протестировали. Вот, смотрите, я после Вашей печати меняю a и ещё раз печатаю и ... какая боль, ни хрена не поменялось :(
String a, b, c = ""; void setup() { Serial.begin(19200); } void loop() { a = "1234567890"; b = "0987654321"; c = "admin"; abc (); } void abc () { String abc [] = {a, b, c}; // локальная область видимости for (int i = 0; i < 3; i++) { Serial.println(abc[i]); // печатает все как надо } a = "5:0"; // Какая боль! Serial.println("Must be a=5:0"); for (int i = 0; i < 3; i++) { Serial.println(abc[i]); // печатает НЕ все как надо } }На самом деле Ваш первый вариант ничем не отличается от второго - ошибка одна и та же и не работают они одинаково. Вам показалось, что типа работает из-за того, что Вы сжульничали - поменяли последовательность действий.
И никакого отношения к области видимости Ваша ошибка не имеет - абсолютно никакого.
Запомните, объекты (а String - это объект) нельзя так просто присваивать друг другу, как числа (а в инициализации массива Вы именно присваиваете). Вернее, присваивать-то можно, но нужно понимать механизм присваивания объектов (он совсем не такой. как у чисел) и не удивляться, когда они присваиваются по своим правилам, а не по правилам присваивания чисел. Я не буду здесь читать Вам лекцию об устройстве объетков - Страуструп Вам в помощь, я же попробую догадаться чего Вы хотели.
Вы хотели к одним и тем же строкам обращаться и как к отдельным переменным, и как к элементам массива, правильно? Если так, то ... я не спрашиваю для чего Вам это надо, потому что уверен, что на самом Вам это не нужно, а желание так сделать - следствие какого-то другого заблуждения. Впрочем, хотите - значит зачем-то нужно.
Такое извращение можно сделать 100500 способами, например можно обзозвать a, b и c ссылками и сделать, чтобы они ссылались на элементы массива. Например,
String abc [3]; String &a = abc[0], &b = abc[1], &c = abc[2]; void setup() { Serial.begin(19200); while(!Serial) yield(); Serial.println("Fun begins!"); } void loop() { a = "aaa"; b = "bbb"; c = "ccc"; for (int i = 0; i < 3; i++) Serial.println(abc[i]); delay(100500); }есть ещё 100500-1 способ сделать это, но я пока ограничусь одним примером, тем более, что я не понимаю для чего это Вам.
я сделал функцией, она вызывается когда мне надо и собирает массив
void abc () { String abc [] = {a, b, c}; for (int i = 0; i < 3; i++) { Serial.println(abc[i]); }может и неправильно , но работает (сильно не пинать, занимаюсь ардуиной всего пару месяцев)
если есть какие то подсказки пишите, не стесняйтесь
ЕвгенийП спасибо за подсказку!
Да ни фига ж не работает! Вы мой пример (первый скетч в моём посте) смотрели? Как же работает, когда значение поменять нельзя???.
Ладно, давайте чуть подробнее.
Когда Вы присваиваете стринги в инициализации, вы на самом деле создаёте новые объекты - копии старых (ваших переменных).
Потому Вам и кажется что работает - Вы создали новый обект в элементе массива - копию переменной и вроде она печатается, т.к. она ж такая же - копия! Но теперь поменяйте переменную (что я и сделал в своём примере) - элемент массива и не подумает меняться - он ведь самостоятельный объект! Он так иостанется тем, чем был и это чётко видно в моём примере.
Вы понимаете о чём я?
Посмотрите первый скетч из моего поста. Если бы у Вас всё работало, то и мои 5:0 присвоились бы, но они же не присвоились!
А вот во втором скетче я сделал ссылки - там не создаются новые объекты, а заводятся ссылки на на Ваши переменные и там действительно всё работает, т.к. элемент массива не является самостоятельным объектом, а просто ссылается на переменную.
В общем, берите Страуструпа и читайте.
и еще вопрос, как правильно подсчитать кол-во заполненых строк в массиве,, исключая пустые
int num = (num, sizeof(abc) / sizeof (String)); это кол-во строк
а как исключить пустые?
да, что за дурь?
String a; String b; String c; void setup() { Serial.begin(9600); } void loop() { a = "1234567890"; b = "0987654321"; c = "admin"; abc(); } void abc() { Serial.println(a); Serial.println(b); Serial.println(c); }*Страуструп-чмо.
и еще вопрос, как правильно подсчитать кол-во заполненых строк в массиве,, исключая пустые
int num = (num, sizeof(abc) / sizeof (String)); это кол-во строк
а как исключить пустые?
пустые это
String a, b, c ="";?ну, они как бы не пустые - они содержат символ '\0', насколько правильно я понимаю концепцию String.
исключить - поменять местами с "непустой" строкой? что бы что?
01String a, b, c ="";02String abc [] = {a, b, c};//глобальная область видимости03voidsetup() {04Serial.begin(9600);05}06voidloop() {07a ="1234567890";//переменные a, b, c08b ="0987654321";09c ="admin";abc[0] = a;abc[1] = b;abc[2] = c;10for(inti = 0; i < 3; i++) {11Serial.println(abc[i]);// печатает пустоту12}13}griin, ну, Вы после присваивания значений переменным, заново всунули их в массив. А если придётся ещё раз переменную поменять, Снова её элементу массива присваивать?
Нет, не зря kisoft про попкорн говорил, надо бы тоже запастись.
и еще вопрос, как правильно подсчитать кол-во заполненых строк в массиве,, исключая пустые
int num = (num, sizeof(abc) / sizeof (String)); это кол-во строк
а как исключить пустые?
Жутко интересно, как Вы понимаете выражение:
Вы понимаете как это работает? Можете объяснить?
Если нужно количество элементов в массиве, то почему так и не написать:
Это чем-то некошерно? Не наш метод, типа?
------------------
Посчитать количество непустых строк можно самым обыкновенным циклом. Просто идём по массиву и считаем сколько там строк ненулевой длины. Ну, как-то так ...
String abc [3]; String &a = abc[0], &b = abc[1], &c = abc[2]; void setup() { Serial.begin(19200); while(!Serial) yield(); Serial.println("Fun begins!"); a = "kaka"; b = "mumu"; short NotEmpty = 0; for (size_t i = 0, total = sizeof(abc)/sizeof(abc[0]); i < total; i++) { if (abc[i].length() > 0) NotEmpty++; } Serial.println(NotEmpty); } void loop() { }А вот последний вопрос нуждается в уточнении. Что значит "исключить пустые"? Выбросить их из массива, чтобы их там не было? Или просто не обрабатывать? Если второе, то так же в цикле смотрите на длину и если ноль, то не обрабатываете. Если первое, то ... проще было не добавлять :) Удаление из массива операция дорогая и её по-возможности избегают. Если нужен "массив" из которого надо часто удалять, то делают его не массивом. а списком.
вы тут все требуете рассказать что я пытаюсь сделать, вообщем так a,b,c это телефоные номера, их может быть от 1 до 3, вот надо чтобы в sms отправлялку не попадали пустые номера телефонов
void SendMessage(String text) { // тут надо обрезать пустые номера for (byte i = 0; i < (тут надо указать кол-во не пустых номеров); i++) { gprs.print("AT+CMGF=1\r"); delay(200); gprs.println("AT+CMGS=\"" + abc[i] + "\""); delay(200); gprs.println(text); delay(200); gprs.println((char)26); delay(5000); } }как то так
на - писал для себя заметку по String
только не забывай, что каждая строка содержит в конце символ '\0' - нужно корректировать +1 если нужно знать реальный размер строки.
*и прекращай эту дурь с массивом из трёх строк.
*и прекращай эту дурь с массивом из трёх строк.
:), иду за пузырем, буду разбираться
вы тут все требуете рассказать что я пытаюсь сделать, вообщем так a,b,c это телефоные номера, их может быть от 1 до 3, вот надо чтобы в sms отправлялку не попадали пустые номера телефонов
void SendMessage(String text) { // тут надо обрезать пустые номера for (byte i = 0; i < (тут надо указать кол-во не пустых номеров); i++) {как то так
Не надо ни обрезать, ни указывать. Надо просто проверять, если длина больше нуля - отправлять, если равно нулю - пропускать. В примере отправку надо вставить вместо многоточия. По ходу дела печатается на какие номера отправляется, а в конце печатается на какое количество номеров отправлено.
String abc [3]; String &a = abc[0], &b = abc[1], &c = abc[2]; void setup() { Serial.begin(19200); while(!Serial) yield(); Serial.println("Fun begins!"); a = "kaka"; b = "mumu"; short NotEmpty = 0; for (size_t i = 0, total = sizeof(abc)/sizeof (abc[0]); i < total; i++) { if (abc[i].length() > 0) { NotEmpty++; Serial.println("Sending SMS to number: "); Serial.print(abc[i]); // Отправляем смс по номеру, сидящему в abc[i] // ... } } Serial.print(NotEmpty); Serial.println(" SMS'es sent."); } void loop() { }Теперь про Вашу функцию. Вы ей в параметрах записали одну строку, а не массив. Так что у Вас номера всё=таки в массиве или в одной строке сидят?
в массиве
А функции строку SendMessage передаёте. Может Вы её хотите вызывать уже для конкретного номера? Тогда зачем в ней цикл по номерам? Если её передаётся один номер, то не надо никакого цикла, просто проверяйте не путой ли он и, если не пустой, отправляйте.
В общем, разбирайтесь, у Вас тут каша какая-то. Как проверить не пустой ли номер. я Вам показал.
А функции строку SendMessage передаёте. Может Вы её хотите вызывать уже для конкретного номера? Тогда зачем в ней цикл по номерам? Если её передаётся один номер, то не надо никакого цикла, просто проверяйте не путой ли он и, если не пустой, отправляйте.
В общем, разбирайтесь, у Вас тут каша какая-то. Как проверить не пустой ли номер. я Вам показал.
да, я тоже подумал чтобы убраь массив, и отправлять с проверкй на пустую строку
сделал так, все работает нормально
void SendMessage(String text) { if (a.length() > 0) { for (byte i = 0; i < 1; i++) { gprs.print("AT+CMGF=1\r"); delay(200); gprs.println("AT+CMGS=\"" + a + "\""); delay(200); gprs.println(text); delay(200); gprs.println((char)26); delay(5000); } } if (b.length() > 0) { for (byte i = 0; i < 1; i++) { gprs.print("AT+CMGF=1\r"); delay(200); gprs.println("AT+CMGS=\"" + b + "\""); delay(200); gprs.println(text); delay(200); gprs.println((char)26); delay(5000); } } }Странно как-то.
Где у Вас номер телефона сидит? В a и b? А в text - сидит текст смс-ки?
А номер в c решили не проверять или ещё третий блок допишете? И вообще, зачем два (или тем более три) одинаковых блока? Не проще ли добавить ещё один параметр и дважды вызвать функцию?
Кроме того, что за странная конструкция
for(bytei = 0; i < 1; i++)её можно просто убрать (как и закрывающую скобку в строках 12 и 24 - ничего не изменится.
ну, говорит, что три номера ему нужно одновременно хратить в переменных еепрома.
Странно как-то.
Где у Вас номер телефона сидит? В a и b? А в text - сидит текст смс-ки?
А номер в c решили не проверять или ещё третий блок допишете? И вообще, зачем два (или тем более три) одинаковых блока? Не проще ли добавить ещё один параметр и дважды вызвать функцию?
номер сидит в a и b , text это текст смски
а два блока из-за динамической памяти, пусть на флэше будет больше, чем добавлять переменную
for(bytei = 0; i < 1; i++)это блокировка на одно срабатываниеа два блока из-за динамической памяти, пусть на флэше будет больше, чем добавлять переменную
for(bytei = 0; i < 1; i++)это блокировка на одно срабатываниеу меня еще в коде конструктор смс
ненужный код убрал
просто подпишусь, интересная тема.