Советы по встроенному микропрограммному обеспечению:как инициализировать массивы на языке C с помощью форм сигналов и других файловых данных
В этой статье показано, как инициализировать массивы в программе на языке C значениями из текстовых файлов.
В этой статье показано, как инициализировать массивы в программе на языке C значениями из текстовых файлов. Данные не хранятся в исходных файлах. Файлы читаются при компиляции программы. Рассмотрены одномерные и многомерные массивы. Примеры также показывают, как управлять помещением массивов в ОЗУ или энергонезависимой памяти и выбирать, какие файлы данных использовать для инициализации.
В примерах используется компилятор GCC для ARM с 32-разрядным микроконтроллером в качестве целевого. Все примеры используют стандартный C и работали с этим компилятором.
Основы инициализации массива
Массив может быть инициализирован значениями, когда он «объявлен». Здесь показано типичное объявление. Значения в фигурных скобках называются «инициализаторами».
Если размер массива не указан внутри скобок, размером будет количество инициализаторов. Если инициализаторов меньше, чем размер массива, дополнительные элементы устанавливаются в 0. Наличие большего количества инициализаторов, чем размер массива, является ошибкой.
Пробел
Инициализаторы необходимо разделять запятыми. Можно добавить «пустое пространство». В этом случае пробел - это «пробелы» или пробелы. Набор символов пробела включает пробел (или пробел), табуляцию, новую строку, возврат каретки, вертикальную табуляцию и подачу страницы. Новая строка и возврат каретки используются для обозначения конца строки в исходном коде C. Я знаю подачу формы, но с вертикальной табуляцией?
В общем, C не заботится о том, содержит ли оператор пробел или продолжается на другой строке. Утверждение здесь эквивалентно приведенному выше. Часто можно увидеть много-много строк инициализаторов для больших массивов. Может даже страницы. В какой-то момент мы можем спросить:«Есть ли способ лучше?»
Инициализация массива из файла
Исходный код C перед компиляцией проходит через препроцессор. Часто используемой функцией препроцессоров C является «включение файлов». Вот цитата из известной книги Кернигана и Ричи «Язык программирования C».
«Включение файлов упрощает работу с коллекциями #defines и декларации ( среди прочего ). »
Я добавил курсивом «среди прочего». Хотя мы обычно включаем файлы «.c» и «.h», препроцессор не заботится о расширении имени файла. Подойдет любой текстовый файл. Итак, следующий синтаксис работает для инициализации массива.
Файл не должен содержать специальных символов, которые иногда скрываются при форматировании документа. Будь проще. Нет форматированного текста. Без заголовков столбцов. Только числа, запятые и пробелы. Вот файл, созданный с помощью Блокнота Windows.
Вот массив в памяти, показанный отладчиком. В этом случае массив находится в ОЗУ, на что указывают верхние адреса в столбце «Местоположение».
Сохранение массива в энергонезависимой памяти и выбор файла данных
В приведенном выше примере массив является глобальной переменной, и ничто не указывает, куда поместить массив. Компилятор и компоновщик предполагают, что массив может быть изменен программой, и помещается в ОЗУ. Начальные значения находятся в энергонезависимой памяти («NVM», обычно во флэш-памяти), а массив в ОЗУ инициализируется из этих данных с помощью кода, который выполняется перед основной программой. Эти данные в NVM не доступны для программы. Если массив не будет изменен (это «константа»), он будет помещен только в NVM и доступен непосредственно из программы. Это экономит оперативную память, которой часто не хватает. Сообщив компилятору и компоновщику, что массив не будет изменен, и чтобы найти его в NVM, обычно используется команда « const Квалификатор. Вот пример и посмотрим на результат. Столбец «Расположение» показывает низкий уровень памяти в карте памяти, которой для этого микроконтроллера является флэш-память.
#define и #if операторы предварительной обработки могут использоваться для предоставления параметров для поиска массива и выбора файлов данных, используемых для инициализации. Вот пример, в котором можно выбрать расположение массива в ОЗУ или NVM.
#if конструкция является примером «условного включения». В этом случае он определяет, будет ли параметр « const »Квалификатор используется при объявлении массива. Это работает, потому что объявление может быть на более чем одной строке или, говоря по-другому, пустое пространство - это нормально.
Вот пример использования условного включения для выбора файла для инициализации.
Тестирование с большим массивом
У меня был большой файл случайных данных, изображающих форму волны шума, и я использовал его для проверки инициализации большого массива в NVM. Вот график данных и объявления.
Вот начало файла.
В исходном CSV-файле не было запятой после значений. Их можно было легко добавить с помощью редактора, который мог использовать выражения в операциях поиска / замены. В этом случае я использовал выражение для разделителя строк «\ R». Находка была «\ R», а Заменить была «, \ R». Одна операция поиска / замены добавила все запятые для 10 000 значений.
Все отлично работало и очень быстро компилировалось! Вот начало массива в памяти. Отладчик красиво разбил отображение на группы по 100 элементов в каждой.
Многомерные массивы
Что, если данные организованы в двух или более измерениях? Давайте посмотрим на двумерный массив, объявленный как uint16_t test [2] [3] . В языке C правый индекс (3) представляет собой одномерный массив с непрерывными в памяти элементами. Левый индекс (2) означает, что существует два таких трехэлементных массива. Это расположение шести элементов в памяти:
[0,0] [0,1] [0,2] [1,0] [1,1] [1,2]
Порядок в памяти важен, потому что доступ к последовательным элементам в памяти путем увеличения правого нижнего индекса происходит быстрее, чем доступ к элементам путем увеличения левого нижнего индекса, что требует «скачков» через память. Если массив содержал два вектора по 1000 элементов, организация должна быть test [2] [1000] для максимально быстрого доступа.
Вот пример инициализации двумерного массива. Обратите внимание, что инициализаторы сгруппированы с дополнительными фигурными скобками, группирующими инициализаторы для одномерных массивов правого нижнего индекса.
Этот формат создает проблему для файла данных, который может содержать только числа, запятые и пробелы. Что произойдет, если опустить дополнительные фигурные скобки?
Компилятор заполняет массив, проходя через инициализаторы слева направо, при этом сначала заполняется правый нижний индекс. Компилятор, который я использую, выдает предупреждение:« отсутствуют фигурные скобки вокруг инициализатора ». Нет проблем, если количество инициализаторов точно такое же, как количество элементов в массиве. Однако, если они не равны, непонятно, как заполнить массив, если фигурные скобки не используются в качестве направляющих.
Массив может быть заполнен из нескольких файлов с несколькими #include заявления. Вот пример, когда инициализация полностью заключена в фигурные скобки. Я опускаю детали, показанные в предыдущих примерах.
Инициализация массивов в объединениях
Объединение - это переменная, которая может содержать объекты разных типов, которые совместно используют одну и ту же память, и компилятор отслеживает объекты, как если бы они были разными вещами. Такое расположение может быть полезно для встроенного приложения, которому не хватает памяти. Вот пример с vector [6] с одним измерением и матрицей [2] [3] с двумя измерениями. Это два массива, которые занимают одни и те же места в памяти.
Правило инициализации объединения - это первое, что входит в объединение ( vector [6] ) заполняется инициализаторами. Если порядок массивов был изменен на обратный, компилятор выдает предупреждение, потому что инициализаторы не полностью заключены в фигурные скобки. Обратите внимание на фигурные скобки вокруг #include удваиваются. Я думаю, что внешний набор включает в себя любые инициализаторы для объединения, а внутренний набор предназначен для типа массива.
Вот файл. У меня две строки, но это не важно. Просто больше белого пространства.
Вот массив в памяти. Обратите внимание на начальное местоположение vector [] и матрица [] [] такие же.
Есть ли другие способы инициализировать многомерные массивы из одного файла, используя только числа, запятые и пробелы? Сообщите нам, добавив комментарий.
Дополнительный совет:струны
А что насчет струн? Вот пример инициализации строки.
#include внутри кавычек не работает. Мой редактор, знакомый с синтаксисом C, ставит мне много вопросительных знаков и волнистых подчеркиваний. Символы для новых строк и #include сами являются инициализаторами! Бедный редактор сбит с толку. Этот беспорядок компилируется, но строка заполнена символами, которые мы видим здесь, а не из файла.
Решение - заключить файл в кавычки.
Затем используйте такую инструкцию.
Обратите внимание:кавычки вокруг имени файла являются частью #include синтаксис и не управляют инициализаторами. Вот результат в ОЗУ.
<час />
Важно отметить, что все примеры должны работать теоретически . с любым компилятором. Однако некоторые примеры могут быть необычными и вызывать проблемы с некоторыми компиляторами. Пожалуйста, дайте нам знать в комментариях, если вы обнаружите проблему.
Встроенный
- Облако и как оно меняет мир ИТ
- ST управляет ИИ для граничных и узловых встроенных устройств с помощью набора инструментов разработчика нейр…
- МОДУЛЬ ДАННЫХ:мониторы с открытой рамкой большого размера с высокой яркостью и функцией easyTouch
- Микрочип:24-битные и 16-битные АЦП со скоростью передачи данных до 153,6 kSPS
- Contrinex:интеллектуальные датчики с поддержкой облачных вычислений и световые завесы безопасности с интерфейсо…
- Массивы в C++ | Объявить | Инициализировать | Указатель на примеры массивов
- C++ динамическое выделение массивов с примером
- Java BufferedReader:как читать файл в Java с примером
- Как сделать IOT реальным с помощью Tech Data и IBM Part 2
- Как сделать Интернет вещей реальным с помощью Tech Data и IBM Часть 1