Arduino как обнулить массив char

Arduino.ru

Проблема с обнулением массива

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Подскжите где косяк .

вот этот кусок кода «вешает» программу .

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Если delay(100); выполнить 1440 раз то так и будет)))

А еще у вас Serial лопнет от потока данных

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

1440 * 100 = 144000 мили секунд = 144 секунды =

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Дело в том, что delay и Serial я сделал просто в этом примере в самом скетче такого нет, но всеравно виснит контроллер хоть так, хоть иначе.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

а памяти у вас хватает на него?? у вас там не 4 гига ведь, а int сколько байт занимает в памяти? умножить на 1440 и добавить все остальное. Вобщем не знаете матчасть потому и не работает .

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Я бы, на Вашем месте, выводил на печать отладочную тинформацию. Например, значение счетчика цикла.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

1. сколько оперативной памяти у вашего контроллера?

3. проще и быстрее обнулить массив можно приблизительно так: memset(&tstArr[0], 0, sizeof(tstArr));

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

1. сколько оперативной памяти у вашего контроллера?

3. проще и быстрее обнулить массив можно приблизительно так: memset(&tstArr[0], 0, sizeof(tstArr));

2 — по ссылкам не особо понял как решить проблемму. поменял где можно int на byte но ничего не изменилось

3 — в таком виде компилятор ругается. пробывал обнулить так memset(tstArr, ‘\0’, 1441); компилятор пропустил но проблемма не решилась.

Источник

Arduino.ru

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

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

его надо обнулять при каждом проходе цикла

но сейчас он 8 элементов, а есть будет 80..800 то смотрится это страшновать

ВОПРПОС: можно ли (С и ардуина могут ли?) обявить и обнулить массив такой записью?

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

memset ( celoe , 0 ,8);

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

если масив объявлен как

то да. изменили на

уже не прокатит.

прокатит в обоих вар-ах.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

да, memset(celoe,0,8); работает

при этом памяти жрет ровно столько, сколько и byte celoe[8]=<0,0,0,0,0,0,0,0>;

главное не ошибиться и не задавать его больше, чем размер переменной.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

если масив объявлен как

то да. изменили на

уже не прокатит.

прокатит в обоих вар-ах.

В обоих вариантах прокатит будет memset(celoe,0,sizeof(celoe));

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

а разве memset -у надо не число байт заменяемых указывать?

тогда для int будет *2 размер, а long *4.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

а разве memset -у надо не число байт заменяемых указывать?

sizeof() дает размер в байтах, а не число элементов

Забавно, что ТС не приходит в голову набрать в гугле memset и sizeof

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

если масив объявлен как

то да. изменили на

уже не прокатит.

прокатит в обоих вар-ах.

В обоих вариантах прокатит будет memset(celoe,0,sizeof(celoe));

не хотел давать гранату.

далее последовало бы (при отличном от byte)

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

не хотел давать гранату.

далее последовало бы (при отличном от byte)

Почему не работает-то? — работает

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

не хотел давать гранату.

далее последовало бы (при отличном от byte)

Почему не работает-то? — работает

ну то есть оно работает, но как !

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

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

мне достаточно было ответа «да» или «нет»

но спасибо Logik за memset — о нем не знал.

цикл — это старый и самый «школьный» метод. так тчо его даже не рассматривал (если есть иные механизмы)

ну и спасибо b707 за уточнение по sizeof — я думал он дает размер в виде числа элементов, а не в байтах. а щас почитал, оказывается именно для МАССИВОВ он возращает размер в байтах. а для остально (строки например) — просто числом её длинну

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

ну то есть оно работает, но как !

Ну вы других-то совсем за идиотов не держите :) Я ж сразу написал. что sizeof дает длину структуры в байтах, а не число элетнтов. Вот, так. к примеру, работает:

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

цикл — это старый и самый «школьный» метод. так тчо его даже не рассматривал (если есть иные механизмы)

Вы будете удивлены, заглянув внутрь типичному memset’у: https://searchcode.com/codesearch/view/19105601/

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

это я чтото не понял. но похоже sizeof дает размер в байтах самой переменной, вместо её размера в символах.

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

ну и спасибо b707 за уточнение по sizeof — я думал он дает размер в виде числа элементов, а не в байтах. а щас почитал, оказывается именно для МАССИВОВ он возращает размер в байтах. а для остально (строки например) — просто числом её длинну

sizeof для любых структур возвращает размер занимаемой памяти в байтах. В том числе для массивов, структур, классов.

И для строк тоже — в байтах. Просто для строки, если это классичемкий ASCII — размер в байтах и в символах совпадает. А вот если строка UTF — то уже нет.

Источник

Си-строки (массивы символов)

Си-строки

В прошлом уроке мы разобрали динамические String-строки в реализации Arduino, а сейчас настало время стандартных статических строк языка C/C++. Такая строка представляет собой массив символов типа char (char array) и для неё работает такой же синтаксис, как и для остальных массивов (урок про массивы). Конец строки определяется нулевым символом \0 (или целым число 0 ), за это такой тип строк называют null-terminated string: ноль на конце позволяет программе определять конец строки и её длину. Также это стандартные строки языка Си и поэтому называются cstring.

Текст в кавычках

Любой написанный в двойных кавычках текст «some text» :

  • Является строковой константой – string constant
  • Имеет тип данных const char* – то есть указывает на свой первый символ в памяти
  • Хранится и в программной, и в оперативной памяти микроконтроллера
  • Компилятор автоматически добавляет нулевой символ в конец строки ‘\0’ – то есть реальный размер строки всегда на 1 символ больше
  • Оптимизируется компилятором – об этом ниже

Объявление как массив

Основное отличие таких строк от String -строк: это обычный массив, размер которого известен заранее и не меняется в процессе работы. Можно объявить строку как массив и посимвольно задать текст:

Такой вариант записи не очень удобный, поэтому строки в C/C++ можно задавать просто текстом в двойных кавычках – компилятор сам посчитает размер массива:

Полученный выше массив содержит 6 символов: 5 на слово hello и 1 на завершающий символ. Текст в данном массиве можно изменять в процессе работы программы, потому что с точки зрения программы мы создали обычный массив и заполнили его буквами. Изменим первую букву на прописную: str[0] = ‘H’; . Выведем в монитор порта:

Serial умеет работать с такими данными и с радостью их выведет.

Объявление как указатель

Также строку можно объявить как указатель на const char* – то есть сам текст в кавычках хранится где то в программе, а мы получаем на него “ссылку”:

Текст в такой строке менять уже нельзя, но можно использовать дальше в программе для сложения или вывода:

Оптимизация

Компилятор оптимизирует строковые константы, но не во всех случаях.

Если создать несколько строк как массивы (которые можно изменять) и присвоить им одинаковые строки, то они займут место в памяти как разные строки, т.е. столько, сколько в них суммарно символов:

Если создать несколько одинаковых строк как указатели – то компилятор их оптимизирует и они займут место в памяти как одна строка!

Если при выводе в Serial или передаче в другие функции мы используем одинаковые строки, то они также будут оптимизироваться и занимать место как одна строка:

В то же время F() – строки (подробнее в уроке про PROGMEM) не оптимизируются компилятором и занимают в программной памяти каждая своё место:

Сложение компилятором

Си-строки можно складывать из нескольких строк через пробелы:

И переносить сложение на новую строку:

Сложение происходит на этапе компиляции, то есть скомпилированной программе это будет одна большая строка.

Отличия от String

В отличие от String-строк, Си-строки:

Для этого существуют специальные функции, о которых мы поговорим ниже.

Длина строки

Для определения длины текста можно использовать оператор strlen() , который возвращает количество символов в строке. Сравним его работу с оператором sizeof() :

Здесь оператор sizeof() вернул количество байт, занимаемое массивом. Массив я специально объявил с размером бОльшим, чем содержащийся в нём текст. А вот оператор strlen() посчитал и вернул количество символов, которые идут с начала массива и до нулевого символа в конце текста без его учёта. А вот такой будет результат при инициализации без указания размера массива:

Массив строк

Можно создать один массив с несколькими строками и обращаться к ним по индексу, фактически это будет двухмерный массив. Выглядит следующим образом:

Таким образом удобно паковать строки для создания текстовых меню и прочего. Единственный большой минус – весь этот текст висит в оперативной памяти мёртвым грузом. Можно сохранить его во Flash – программной памяти (PROGMEM), об этом читайте в отдельном уроке.

Оптимизация памяти

Как я писал выше – “текст в кавычках” хранится и в памяти программы, и в оперативной памяти, то есть после запуска микроконтроллера строка загружается в оперативную память, и уже там мы имеем к ней доступ. Как правило, объём программной памяти микроконтроллера в несколько раз больше, чем оперативной. Есть несколько возможностей хранения строк только в программной памяти, об этом очень подробно поговорим в уроке про PROGMEM.

Инструменты для Си-строк

Есть готовые функции, позволяющие конвертировать различные типы данных в строки:

  • itoa(int_data, str, base) – записывает переменную типа int int_data в строку str с базисом* base.
  • ltoa (long_data, str, base) – записывает переменную типа long long_data в строку str с базисом* base.
  • ultoa (unsigned_long_data, str, base) – записывает переменную типа unsigned long unsigned_long_data в строку str с базисом* base.
  • dtostrf(float_data, width, dec, str) – записывает переменную типа float float_data в строку str с количеством символов width и знаков после запятой dec.

* Примечание: base – основание системы счисления, тут всё как при выводе в Serial:

  • DEC – десятичная
  • BIN – двоичная
  • OCT – восьмеричная
  • HEX – шестнадцатеричная

И наоборот, можно преобразовывать строки в численные данные, функция вернёт результат:

  • atoi(str) – преобразование str в int
  • atol(str) – преобразование str в long
  • atof(str) – преобразование str в float

2 кБ Flash памяти!! Максимально избегайте их применения в крупном проекте. Для преобразования можно сделать свою функцию, практически готовые варианты для всех типов данных можно найти в стандартной ардуиновской Print.cpp (ссылка на файл на гитхабе Arduino).

Массивы символов не так просты, как кажутся: их возможности сильно расширяет стандартная библиотека cstring. Использование всех доступных фишек по работе с массивами символов позволяет полностью избавить свой код от тяжёлых String-строк и сделать его легче, быстрее и оптимальнее. Подробно обо всех инструментах можно почитать в официальной документации. Очень интересный пример с манипуляцией этими инструментами можно посмотреть здесь. А мы вкратце рассмотрим самые полезные.

Важный момент: библиотека работает со строками как с указателями, и многие функции возвращают как результат именно указатель. Как это понимать, если вы не читали урок про указатели и/или тема слишком сложная? Указатель – первый символ в строке, работа со строкой начнётся с него. Последним символом является нулевой символ, и для программы строка существует именно в этом диапазоне. Если какая-то функция возвращает указатель на конкретный символ в строке – по сути она возвращает часть строки, начиная с этого символа и до конца строки. Например, мы искали символ , в строке «Hello, world!» . Программа вернёт нам указатель на эту запятую, по сути это будет кусочек той же самой строки, содержащий «, world!» . Просто “начало” строки сместится.

Копирует str2 в str1, включая NULL . Так как мы передаём указатель, цель и место назначения можно “подвинуть”:

Копирует num символов из начала str2 в начало str1

Библиотека

У меня есть библиотека для работы с Си-строками: их преобразования и парсинга на блоки данных. Некоторые инструменты реализованы гораздо эффективнее, чем в стандартной строковой библиотеке. Библиотека называется GParser, документацию и примеры смотрите на GitHub.

Видео

Источник

Adblock
detector