Виды памяти в технических средствах информатизации постоянная переменная внутренняя внешняя
Обновлено: 22.11.2024
Класс хранения – это настройка генерации кода, которую вы применяете к данным, таким как параметры, сигналы и состояния. Во время настройки кода используйте класс хранения, чтобы управлять внешним видом и размещением элемента данных в сгенерированном коде, а также не допускать, чтобы оптимизация убирала хранилище для этого элемента данных.
Для данных модели вы можете применить класс хранения непосредственно к элементу данных модели с помощью редактора сопоставлений кода или API сопоставления кода. С помощью редактора или API примените класс хранения по умолчанию для категорий данных, а затем при необходимости переопределите этот параметр для отдельных элементов данных.
Для внешних данных вы применяете класс хранения к объекту данных с помощью обозревателя моделей или программно с помощью таких функций, как get_param и set_param .
После того как вы указали класс хранения для элемента или категории элементов, вы можете установить свойства для этого класса хранения, такие как заголовочные файлы, файлы определений и разделы памяти.
Свойства класса хранилища
Настройки свойств для класса хранения определяют, как и где генератор кода представляет данные в сгенерированном коде. Свойства, которые может настроить пользователь класса хранения, различаются в зависимости от класса хранения. Для большинства отдельных элементов пользователь может настроить идентификатор для именования элемента данных в коде. Чтобы определить свойства, которые пользователь может настроить для предопределенных классов хранения, см. следующую информацию о конкретных классах хранения.
При создании класса хранения с помощью конструктора настраиваемых классов хранения вы можете указать, может ли пользователь класса хранения задавать дополнительные параметры. См. Разрешить пользователям класса хранения указывать значение свойства (Embedded Coder) .
Класс хранения по умолчанию
По умолчанию для отдельного элемента данных используется класс хранения Auto . Используя это значение по умолчанию, вы выбираете, чтобы генератор кода обрабатывал выбор класса хранения и приложение. В этом случае элемент данных подлежит оптимизации генерации кода, которая может исключить элемент из кода или изменить представление элемента. Если оптимизации не устраняют элемент данных, элемент отображается как поле стандартной структуры данных в сгенерированном коде.
При использовании редактора сопоставления кода или API сопоставления кода элемент данных, настроенный с классом хранения Auto, который не устранен оптимизацией, получает параметры генерации кода по умолчанию для соответствующей категории данных. Если вы не укажете конфигурацию кода для категории элементов данных, классом хранения будет Default . Когда категория элементов данных использует этот класс хранения, элементы данных в этой категории отображаются как поле стандартной структуры данных в сгенерированном коде.
Встроенные и предопределенные классы хранения
Чтобы оптимизация не приводила к сокращению хранилища для элемента данных, вы можете выбрать класс хранения для элемента в соответствии с вашими требованиями к генерации кода. Доступные классы хранения включают встроенные классы хранения, предопределенные классы хранения в пакете Simulink, а также могут включать другие классы хранения для конкретного проекта, определенные в словаре Embedded Coder. Если у вас есть особые требования, которым не отвечают перечисленные классы хранения, и вы создаете код для цели на основе ERT, вы можете определить и использовать новый класс хранения. См. разделы Определение классов хранения, разделов памяти и шаблонов функций для архитектуры программного обеспечения (встроенный кодер) и Создание классов хранения с помощью конструктора настраиваемых классов хранения (встроенный кодер) .
Для Simulink® Coder™ вы можете выбирать из этих встроенных и предопределенных классов хранения.
Требования | Класс хранилища |
---|---|
Включите оптимизацию, потенциально генерирующую более эффективный код.< /td> | Авто (Отдельные элементы данных) |
Для элементов данных, которые нельзя оптимизировать, представьте данные как поле стандартной структуры данных. | По умолчанию (сопоставление по умолчанию) |
Предотвратить устранение хранилища для элемента данных при оптимизации. | Модель по умолчанию (индивидуальное сопоставление) | < /tr>
Доступ к данным из отдельной глобальной переменной. Сгенерированный код содержит объявление и определение переменной. | ExportedGlobal |
Доступ к данным из автономной глобальной переменной. Сгенерированный код содержит объявление переменной. Ваш внешний код предоставляет определение. | ImportedExtern, ImportedExternPointer |
Если у вас есть Embedded Coder®, вы можете выбрать один из этих дополнительных предопределенных классов хранения, доступных в пакете Simulink.
Проще говоря, переменная — это место хранения, которому выделена некоторая память. По сути, переменная, используемая для хранения некоторой формы данных.Различные типы переменных требуют разного объема памяти и имеют определенный набор операций, которые можно к ним применить.
Объявление переменной:
Типичное объявление переменной имеет форму:
Имя переменной может состоять из букв (как в верхнем, так и в нижнем регистре), цифр и символа подчеркивания «_». Однако имя не должно начинаться с цифры.
Различие ч/б объявления и определения переменной
Объявление переменной относится к той части, где переменная впервые объявляется или вводится перед ее первым использованием. Определение переменной — это часть, в которой переменной присваивается место в памяти и значение. В большинстве случаев объявление и определение переменных выполняются вместе.
См. следующую программу C для лучшего понимания:
Вывод:
Возможно ли иметь отдельное объявление и определение?
Возможно в случае внешних переменных и функций. См. вопрос 1 для получения более подробной информации.
- Переменная может содержать буквы, цифры и знак подчеркивания.
- Имя переменной может начинаться с алфавита и только с символа подчеркивания. Оно не может начинаться с цифры.
- В имени переменной не допускаются пробелы.
- Имя переменной не должно быть зарезервированным словом или ключевым словом, например. int, goto и т. д.
Типы переменных в C
1. Локальная переменная
Переменная, объявленная и используемая внутри функции или блока, называется локальной переменной.
Сфера действия ограничена функцией или блоком. Его нельзя использовать вне блока. Локальные переменные необходимо
инициализировать перед использованием.
Пример —
В приведенном выше коде x можно использовать только в области действия function() . Использование его в основной функции приведет к ошибке.
<р>2. Глобальная переменнаяПеременная, объявленная вне функции или блока, называется глобальной переменной.
Объявляется при запуске программы. Он доступен для всех функций.
Пример —
В приведенном выше коде обе функции могут использовать глобальную переменную x, поскольку глобальные переменные уже доступны для всех функций.
3.Статическая переменная
Переменная, которая сохраняет свое значение между вызовами нескольких функций, называется статической переменной.
Он объявляется с ключевым словом static.
Пример-
В приведенном выше примере локальная переменная всегда будет выводить одно и то же значение всякий раз, когда будет вызываться функция, тогда как статическая переменная будет выводить увеличенное значение при каждом вызове функции.
4.Автоматическая переменная
Все переменные в C, объявленные внутри блока, по умолчанию являются автоматическими переменными. Мы
можем явно объявить автоматическую переменную, используя ключевое слово auto. Автоматические переменные аналогичны
локальным переменным.
Пример —
В приведенном выше примере и x, и y являются автоматическими переменными. Единственное отличие состоит в том, что переменная y явно объявлена с ключевым словом auto.
5.Внешняя переменная
Внешняя переменная может совместно использоваться несколькими файлами C. Мы можем объявить внешнюю переменную с помощью ключевого слова extern.
Пример:
В приведенном выше примере x — это внешняя переменная, которая используется в нескольких файлах.
Ключевые слова — это определенные зарезервированные слова в C, каждое из которых имеет определенную функцию, связанную с ним. Почти все слова, которые помогают нам использовать функциональность языка C, включены в список ключевых слов. Так что можете себе представить, что список ключевых слов будет немаленьким!
Всего в C 44 ключевых слова (C89 – 32, C99 – 5, C11 – 7):
Большинство этих ключевых слов уже обсуждались в различных подразделах языка C, таких как типы данных, классы хранения, операторы управления, функции и т. д.
Давайте обсудим некоторые другие ключевые слова, которые позволяют нам использовать основные функции C:
const: const может использоваться для объявления постоянных переменных. Постоянные переменные — это переменные, которые при инициализации не могут изменить свое значение. Или, другими словами, присвоенное им значение не может быть изменено дальше в программе.
Синтаксис:
Примечание. Постоянные переменные должны быть инициализированы во время их объявления. Ключевое слово const также используется с указателями. Пожалуйста, обратитесь к квалификатору const в C, чтобы понять то же самое.
extern: extern просто сообщает нам, что переменная определена в другом месте, а не в том же блоке, где она используется. По сути, значение присваивается ему в другом блоке, и оно также может быть перезаписано/изменено в другом блоке. Таким образом, внешняя переменная — это не что иное, как глобальная переменная, инициализированная допустимым значением, где она объявлена для использования в другом месте. Доступ к нему можно получить из любой функции/блока. Кроме того, обычную глобальную переменную также можно сделать внешней, поместив ключевое слово «extern» перед ее объявлением/определением в любой функции/блоке. В основном это означает, что мы не инициализируем новую переменную, а вместо этого используем/имеем доступ только к глобальной переменной.Основная цель использования внешних переменных заключается в том, что к ним можно получить доступ между двумя разными файлами, которые являются частью большой программы.
Синтаксис:
static: ключевое слово static используется для объявления статических переменных, которые обычно используются при написании программ на языке C. Статические переменные имеют свойство сохранять свое значение даже после того, как они выходят за пределы своей области видимости! Следовательно, статические переменные сохраняют значение своего последнего использования в своей области. Таким образом, можно сказать, что они инициализируются только один раз и существуют до завершения работы программы. Таким образом, новая память не выделяется, потому что они не объявляются повторно. Их область действия является локальной для функции, для которой они были определены. Доступ к глобальным статическим переменным можно получить в любом месте этого файла, поскольку их область действия является локальной для файла. По умолчанию компилятор присваивает им значение 0.
Синтаксис:
void: void — это особый тип данных. Но что делает его таким особенным? void, как это буквально означает, является пустым типом данных. Это означает, что он ничего не имеет или не имеет ценности. Например, когда он используется в качестве возвращаемого типа данных для функции, он просто означает, что функция не возвращает никакого значения. Точно так же, когда он добавляется к заголовку функции, он означает, что функция не принимает аргументов.
Примечание: void также часто используется с указателями. Пожалуйста, обратитесь к указателю void в C, чтобы понять то же самое.
typedef: typedef используется для присвоения нового имени уже существующему или даже пользовательскому типу данных (например, структуре). Иногда это очень удобно, например, в случае, когда имя определенной вами структуры очень длинное или вам просто нужно сокращенное обозначение уже существующего типа данных.
Давайте реализуем ключевые слова, которые мы обсуждали выше. Взгляните на следующий код, который является рабочим примером для демонстрации этих ключевых слов:
Спецификаторы класса хранения являются частью decl-specifier-seq синтаксиса объявления имени. Вместе с областью действия имени они управляют двумя независимыми свойствами имени: его длительностью хранения и его связью.
- auto или (до C++11) без спецификатора - automatic продолжительность хранения.
- register - автоматическая продолжительность хранения. Также подсказывает компилятору поместить объект в регистр процессора. (устарело)
- static — продолжительность хранения static или thread и внутренняя связь (или внешняя связь для статических членов класса, не в анонимном пространстве имен).
- extern — статическая или потоковая продолжительность хранения и внешняя связь.
- thread_local — длительность хранения потока.
- изменяемый — не влияет на продолжительность хранения или привязку. Объяснение см. в const/volatile.
В объявлении может присутствовать только один спецификатор класса хранения, за исключением того, что thread_local может сочетаться со static или extern (начиная с C++11).
Содержание
[править] Объяснение
1) Спецификатор auto был разрешен только для объектов, объявленных в области блока или в списках параметров функций. В нем указана продолжительность автоматического хранения, которая является значением по умолчанию для таких деклараций. Значение этого ключевого слова было изменено в C++11.
2) Спецификатор регистра разрешен только для объектов, объявленных в области блока и в списках параметров функций. Он указывает продолжительность автоматического хранения, которая является значением по умолчанию для таких объявлений. Кроме того, наличие этого ключевого слова может быть использовано оптимизатором как подсказка для сохранения значения этой переменной в регистре ЦП. Это ключевое слово устарело в C++11.
3) Статический спецификатор разрешен только в объявлениях объектов (кроме списков параметров функций), объявлениях функций (кроме области блока) и объявлениях анонимных объединений. При использовании в объявлении члена класса он объявляет статический член. При использовании в объявлении объекта он указывает продолжительность статического хранения (кроме случаев, когда он сопровождается thread_local ). При использовании в объявлении в области пространства имен он указывает внутреннюю связь.
4) Спецификатор extern разрешен только в объявлениях переменных и функций (кроме членов класса или параметров функции). Он указывает внешнюю связь и технически не влияет на продолжительность хранения, но его нельзя использовать в определении объекта автоматической продолжительности хранения, поэтому все внешние объекты имеют статическую продолжительность или продолжительность потока. Кроме того, объявление переменной, использующее extern и не имеющее инициализатора, не является определением.
5) Ключевое слово thread_local разрешено только для объектов, объявленных в области пространства имен, объектов, объявленных в области блока, и статических элементов данных. Это указывает на то, что объект имеет продолжительность хранения потока.Его можно комбинировать со статическим или внешним для указания внутренней или внешней связи (за исключением статических элементов данных, которые всегда имеют внешнюю связь) соответственно, но этот дополнительный статический параметр не влияет на продолжительность хранения.
[править] Срок хранения
Все объекты в программе имеют одну из следующих продолжительностей хранения:
- автоматическая продолжительность хранения. Память для объекта выделяется в начале окружающего блока кода и освобождается в конце. Все локальные объекты имеют этот срок хранения, кроме объявленных static , extern или thread_local .
-
Продолжительность
- статического хранения. Память для объекта выделяется при запуске программы и освобождается при завершении программы. Существует только один экземпляр объекта. Все объекты, объявленные в области пространства имен (включая глобальное пространство имен), имеют эту продолжительность хранения, а также объекты, объявленные с помощью static или extern . См. Нелокальные переменные и Статические локальные переменные для получения подробной информации об инициализации объектов с этим сроком хранения.
-
Длительность хранения
- потока. Память для объекта выделяется, когда начинается поток, и освобождается, когда поток заканчивается. Каждый поток имеет свой собственный экземпляр объекта. Только объекты, объявленные thread_local, имеют этот срок хранения. thread_local может отображаться вместе со static или extern для настройки связи. См. Нелокальные переменные и Статические локальные переменные для получения подробной информации об инициализации объектов с этим сроком хранения.
- динамическая продолжительность хранения. Хранилище для объекта выделяется и освобождается по запросу с помощью функций динамического выделения памяти. Подробнее об инициализации объектов с такой продолжительностью хранения см. в разделе new-expression.
[править] Связь
Имя, обозначающее объект, ссылку, функцию, тип, шаблон, пространство имен или значение, может иметь связь. Если имя имеет связь, оно ссылается на тот же объект, что и то же имя, представленное объявлением в другой области. Если переменная, функция или другой объект с одним и тем же именем объявлены в нескольких областях видимости, но не имеют достаточной связи, то создается несколько экземпляров объекта.
Распознаются следующие связи:
[edit] нет связи
На имя можно ссылаться только из той области, в которой оно находится.
Любое из следующих имен, объявленных в области блока, не имеет связи:
- переменные, явно не объявленные extern (независимо от модификатора static);
- локальные классы и их функции-члены;
- другие имена, объявленные в области блока, такие как typedefs, enumerations и enumerators.
Имена, не указанные с помощью external , module (начиная с C++20) или внутренней связи, также не имеют связи, независимо от того, в какой области они объявлены.
[править] внутренняя связь
На имя можно ссылаться из всех областей текущей единицы перевода.
Любое из следующих имен, объявленных в области пространства имен, имеет внутреннюю связь:
- переменные, шаблоны переменных (начиная с C++14), функции или шаблоны функций, объявленные статическими;
- энергонезависимые нешаблонные (начиная с C++14) неинлайновые (начиная с C++17) неэкспортируемые (начиная с C++20) константные переменные (включая constexpr), не объявленные extern и ранее не были заявлены как имеющие внешнюю ссылку;
- члены данных анонимных союзов.
Кроме того, все имена, объявленные в безымянном пространстве имен или пространстве имен внутри безымянного пространства имен, даже явно объявленные extern , имеют внутреннюю связь.
[править] внешняя ссылка
На имя можно ссылаться из областей действия в других единицах перевода. Переменные и функции с внешней привязкой также имеют языковую привязку, что позволяет связывать единицы перевода, написанные на разных языках программирования.
Любое из следующих имен, объявленных в области пространства имен, имеет внешнюю связь, если только они не объявлены в безымянном пространстве имен или их объявления не присоединены к именованному модулю и не экспортируются (начиная с C++20):
- переменные и функции, не перечисленные выше (то есть функции, не объявленные static , неконстантные переменные, не объявленные static , и любые переменные, объявленные extern );
- перечисления;
- названия классов, их функции-члены, статические данные-члены (константные или нет), вложенные классы и перечисления, а также функции, впервые представленные в объявлениях друзей внутри тела класса;
- имена всех шаблонов, не перечисленных выше (то есть не шаблоны функций, объявленные статическими).
Любое из следующих имен, впервые объявленных в области блока, имеет внешнюю ссылку:
- имена переменных, объявленных extern ;
- названия функций.
связь модулей
На имя можно ссылаться только из областей действия в том же модульном модуле или в других модулях трансляции того же именованного модуля.
Имена, объявленные в области пространства имен, связаны с модулем, если их объявления прикреплены к именованному модулю, не экспортируются и не имеют внутренней связи.
[править] Статические локальные переменные
Переменные, объявленные в области блока со спецификатором static или thread_local (начиная с C++11), имеют статическое или потоковое (начиная с C++11) время хранения, но инициализируются при первом прохождении управления через их объявление (если только их инициализация не нулевую или константную инициализацию, которую можно выполнить перед первым входом в блок). При всех дальнейших вызовах объявление пропускается.
Если инициализация вызывает исключение, переменная не считается инициализированной, и попытка инициализации будет предпринята снова при следующем прохождении управления через объявление.
Если инициализация рекурсивно входит в блок, в котором инициализируется переменная, поведение не определено.
Если несколько потоков пытаются одновременно инициализировать одну и ту же статическую локальную переменную, инициализация происходит ровно один раз (аналогичное поведение можно получить для произвольных функций с помощью std::call_once ).
Примечание. В обычных реализациях этой функции используются варианты шаблона блокировки с двойной проверкой, что сокращает накладные расходы во время выполнения для уже инициализированных локальных статических данных до одного неатомарного логического сравнения.
Деструктор для статической переменной области блока вызывается при выходе из программы, но только в том случае, если инициализация прошла успешно.
Все статические объекты, локальные для функции, во всех определениях одной и той же встроенной функции (которые могут быть неявно встроенными) ссылаются на один и тот же объект, определенный в одной единице перевода, если функция имеет внешнюю связь.
[edit] Местные сущности блока перевода
Концепция локальных единиц перевода стандартизирована в C++20, дополнительные сведения см. на этой странице.
Объект является локальным для единицы перевода (или локальным для TU для краткости), если
- у него есть имя с внутренней связью, или
- у него нет связанного имени, и он вводится в определение локального объекта TU, или
- это шаблон или специализация шаблона, аргумент шаблона или объявление шаблона которого использует локальный объект TU.
Плохие вещи (как правило, нарушение ODR) могут произойти, если тип нелокального объекта TU зависит от локального объекта TU, или если объявление или руководство по выводу для (начиная с C++17 ) нелокальный объект TU называет локальный объект TU вне его
- тело функции для невстроенной функции или шаблона функции
- инициализатор для переменной или шаблона переменной
- объявления друзей в определении класса
- использование значения переменной, если переменная может использоваться в константных выражениях
Такое использование запрещено в интерфейсном блоке модуля (вне его частного-модуля-фрагмента, если таковой имеется) или в разделе модуля и не рекомендуется в любом другом контексте.
Объявление, которое появляется в одной единице перевода, не может называть локальный объект TU, объявленный в другой единице перевода, которая не является единицей заголовка. Объявление, созданное для шаблона, появляется в момент создания экземпляра специализации.
[править] Примечания
Имена в области пространства имен верхнего уровня (области файла в C), которые являются константными, а не внешними, имеют внешнюю связь в C, но внутреннюю связь в C++.
Начиная с C++11, auto больше не является спецификатором класса хранения; он используется для обозначения вывода типа.
В C адрес регистровой переменной нельзя взять, но в C++ переменная, объявленная в регистре, семантически неотличима от переменной, объявленной без каких-либо спецификаторов класса хранения.
В C++, в отличие от C, переменные нельзя объявлять в регистре.
Имена переменных thread_local с внутренней или внешней связью, на которые ссылаются разные области видимости, могут относиться к одному и тому же или к разным экземплярам в зависимости от того, выполняется ли код в одном или разных потоках.
Ключевое слово extern также можно использовать для указания привязки к языку и явных объявлений создания экземпляров шаблона, но в этих случаях оно не является спецификатором класса хранения (за исключением случаев, когда объявление содержится непосредственно в спецификации привязки к языку, и в этом случае объявление обрабатывается так, как если бы он содержал спецификатор extern).
Ключевое слово mutable — это спецификатор класса хранения в грамматике языка C++, хотя оно не влияет на продолжительность хранения или связывание.
Этот раздел неполный Причина: правила повторного объявления имен в одной и той же ТУ |