const (C++)
При изменении объявления данных ключевое слово указывает, const что объект или переменная не изменяются.
Синтаксис
declarator :
ptr-declarator
noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator :
noptr-declarator
ptr-operator ptr-declarator
noptr-declarator :
declarator-id attribute-specifier-seq необ.
noptr-declarator parameters-and-qualifiers
noptr-declarator [ constant-expression opt ] attribute-specifier-seq opt
( ptr-declarator )
parameters-and-qualifiers :
( parameter-declaration-clause ) cv-qualifier-seq необ.
ref-qualifier opt noexcept-specifier opt attribute-specifier-seq opt
trailing-return-type :
-> type-id
ptr-operator :
* attribute-specifier-seq opt cv-qualifier-seq opt
& attribute-specifier-seq необ.
&& attribute-specifier-seq необ.
nested-name-specifier * attribute-specifier-seq opt cv-qualifier-seq opt
cv-qualifier-seq :
cv-qualifier cv-qualifier-seq необ.
cv-qualifier :
const
volatile
ref-qualifier :
&
&&
declarator-id :
. необ. id-expression
Значения const
Ключевое слово const указывает, что значение переменной является константой и сообщает компилятору, чтобы предотвратить изменение программистом.
// constant_values1.cpp int main() < const int i = 5; i = 10; // C3892 i++; // C2105 >
В C++можно использовать const ключевое слово вместо #define директивы препроцессора для определения константных значений. Значения, определенные с const помощью, подвергаются типу проверка и могут использоваться вместо константных выражений. В C++можно указать размер массива с переменной const следующим образом:
// constant_values2.cpp // compile with: /c const int maxarray = 255; char store_char[maxarray]; // allowed in C++; not allowed in C
В языке C константные значения по умолчанию имеют внешнюю компоновку, поэтому они могут использоваться только в файлах исходного кода. В языке C++ константные значения по умолчанию имеют внутреннюю компоновку, которая позволяет использовать их в файлах заголовков.
Ключевое слово const также можно использовать в объявлениях указателя.
// constant_values3.cpp int main() < char this_char, that_char; char *mybuf = &this_char, *yourbuf = &that_char; char *const aptr = mybuf; *aptr = 'c'; // OK aptr = yourbuf; // C3892 >
Указатель на переменную, объявленную как const можно назначить только указателю, который также объявлен как const .
// constant_values4.cpp #include int main() < const char *mybuf = "test"; char *yourbuf = "test2"; printf_s("%s\n", mybuf); const char *bptr = mybuf; // Pointer to constant data printf_s("%s\n", bptr); // *bptr = 'a'; // Error >
Указатели на данные-константы можно использовать в качестве параметров функций, чтобы функция не могла изменять параметр, переданный посредством указателя.
Для объектов, объявленных как const , можно вызывать только функции-члены констант. Компилятор гарантирует, что объект константы никогда не изменяется.
birthday.getMonth(); // Okay birthday.setMonth( 4 ); // Error
Можно вызывать функции-члены констант или неконстантных для неконстантного объекта. Можно также перегрузить функцию-член с помощью const ключевое слово; эта функция позволяет вызывать другую версию функции для постоянных и неконстантных объектов.
Вы не можете объявлять конструкторы или деструкторы с const помощью ключевое слово.
const функции-члены
Объявление функции-члена с const помощью ключевое слово указывает, что функция является функцией только для чтения, которая не изменяет объект, для которого он вызывается. Функция-член констант не может изменять нестатические элементы данных или вызывать какие-либо функции-члены, которые не являются константами. Чтобы объявить функцию-член константы, поместите const ключевое слово после закрывающей скобки списка аргументов. В const объявлении и определении требуется ключевое слово.
// constant_member_function.cpp class Date < public: Date( int mn, int dy, int yr ); int getMonth() const; // A read-only function void setMonth( int mn ); // A write function; can't be const private: int month; >; int Date::getMonth() const < return month; // Doesn't modify anything >void Date::setMonth( int mn ) < month = mn; // Modifies data member >int main() < Date MyDate( 7, 4, 1998 ); const Date BirthDate( 1, 18, 1953 ); MyDate.setMonth( 4 ); // Okay BirthDate.getMonth(); // Okay BirthDate.setMonth( 4 ); // C2662 Error >
Различия C и C++ const
При определении переменной const в файле исходного кода C это делается так:
const int i = 2;
Затем эту переменную можно использовать в другом модуле следующим образом:
extern const int i;
Но чтобы получить такое же поведение в C++, необходимо определить const переменную следующим образом:
extern const int i = 2;
Как и в C, эту переменную можно использовать в другом модуле следующим образом:
extern const int i;
Если вы хотите определить extern переменную в файле исходного кода C++ для использования в файле исходного кода C, используйте следующее:
extern "C" const int x=10;
для предотвращения изменения имени компилятором C++.
Замечания
При выполнении списка параметров функции-члена ключевое слово указывает, const что функция не изменяет объект, для которого он вызывается.
Дополнительные сведения const см. в следующих статьях:
- const указатели и volatile указатели
- Квалификаторы типов (справочник по языку C)
- volatile
- #define
Как ввести константу в c
Отличительной особенностью переменных является то, что мы можем многократно в течение работы программы изменять их значение:
int n ; n = 9; n = 5;
Но кроме переменных в языке программирования C++ можно определять константы . Их значение устанавливается один раз и впоследствии мы его не можем изменить. Константа определяется практически так же, как и переменная за тем исключением, что в начале определения константы идет ключевое слово const . Например:
const int n ; // или // const int n = 22;
И также в процессе программы мы сможем обращаться к значению константы:
#include int main() < const int age ; std::cout
Но если же мы захотим после определения константы присвоить ей некоторое значение, то компилятор не сможет скомпилировать программу и выведет ошибку:
const int age ; age = 78;
То есть такой код не будет работать. И так как нельзя изменить значения константы, то ее всегда необходимо инициализировать, если мы хотим, чтобы она имела некоторое значение.
Если константа не будет инициализирована, то компилятор также выведет ошибку и не сможет скомпилировать программу, как в следующем случае:
const int age;
В качестве значения константам можно передавать как обычные литералы, так и динамически вычисляемые значения, например, значения переменных или других констант:
int a ; const int b ; const int d ; const int x ;
Обычно в качестве констант определяются такие значения, которые должны оставаться постоянными в течение работы всей программы и не могут быть изменены. Например, если программы выполняет математические операции с использованием числа PI, то было бы оптимально определить данное значение как константу, так как оно все равно в принципе неизменно:
Константы (Руководство по программированию на C#)
Константы — это постоянные значения, которые известны во время компиляции и не изменяются во время выполнения программы. Константы должны объявляться с модификатором const. Только встроенные типы C# могут быть объявлены как const . Константы ссылочного типа, отличные от того, String которые могут быть инициализированы только с значением NULL . Пользовательские типы, включая классы, структуры и массивы, не могут объявляться как const . Модификатор readonly позволяет создать класс, структуру или массив, которые инициализируются один раз (например, в конструкторе), и впоследствии изменить их нельзя.
C# не поддерживает методы, свойства или события const .
Тип перечисления позволяет определять именованные константы для целочисленных встроенных типов (например int , uint , long и т. д.). Дополнительные сведения см. в разделе Перечисление.
Константы должны инициализироваться сразу после объявления. Например:
class Calendar1
В этом примере константа Months всегда имеет значение 12, и его не может изменить даже сам класс. На самом деле в случае, если компилятор встречает идентификатор константы в исходном коде C# (например, Months ), он подставляет значение литерала непосредственно в создаваемый им промежуточный язык (IL). Поскольку с константой в среде выполнения не связан адрес ни одной переменной, поля const не могут передаваться по ссылке и отображаться в выражении как левостороннее значение.
Будьте внимательны, ссылаясь на постоянные значения, определенные в другом коде, например, в DLL. Если в новой версии DLL для константы определяется новое значение, старое значение литерала хранится в вашей программе вплоть до повторной компиляции для новой версии.
Несколько констант одного типа можно объявить одновременно, например:
class Calendar2
Выражение, которое используется для инициализации константы, может ссылаться на другую константу, если не создает циклическую ссылку. Например:
class Calendar3 < public const int Months = 12; public const int Weeks = 52; public const int Days = 365; public const double DaysPerWeek = (double) Days / (double) Weeks; public const double DaysPerMonth = (double) Days / (double) Months; >
Константы могут иметь пометку public, private, protected, internal, protected internal или private protected. Эти модификаторы доступа определяют, каким образом пользователи класса смогут получать доступ к константе. Дополнительные сведения см. в статье Модификаторы доступа.
Доступ к константам осуществляется так, как если бы они были статическими полями, поскольку значение константы одинаково для всех экземпляров типа. Для их объявления используйте ключевое слово static . Выражения, которые не относятся к классу, определяющему константу, должны включать имя класса, период и имя константы для доступа к этой константе. Например:
int birthstones = Calendar.Months;
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
См. также
- Руководство по программированию на C#
- Свойства
- Типы
- readonly
- Неизменность в C#, часть 1. Виды неизменности
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Как задать тип константы в Си?
К примеру, в программе (для экономия места) я использую символьный массив для хранения и операций над значениями. При этом есть одно число: 9 — которое имеет важное значение, и которое, в целях практичности мне нужно записать как константу
#define SIZE 9
При этом, насколько я сумел понять из учебника, эта константа будет иметь тип int . В результате при операциях с этим значением будет все время использоваться приведение типа к int . Это меня не устраивает — я хочу знать, можно ли явно задать тип (символьный) такой константе?
Отслеживать
2,969 3 3 золотых знака 15 15 серебряных знаков 30 30 бронзовых знаков
задан 31 авг 2017 в 17:13
Andrej Levkovitch Andrej Levkovitch
8,047 2 2 золотых знака 19 19 серебряных знаков 46 46 бронзовых знаков
это не константа, это просто define. Нужна константа — пишите const char SIZE = ‘9’; , если Ваш компилятор это поддерживает. Но оно как бы все равно не совсем «символьное».
31 авг 2017 в 17:47
Статический массив из одного элемента? Только учтите, выравнивание никто не отменял, так что смотрите карту памяти после линковки.
31 авг 2017 в 17:54
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
Смотрите как работает define, самый первый этап компиляции это препроцессинг, везде где встречается ваша директива ‘SIZE’, она будет заменена на 9, а только потом будет компиляция, линковка.. Вы можете написать туда что угодно в рамках синтаксиса, это будет работать как если бы в блокноте произвели поиск и замену.
Отслеживать
ответ дан 31 авг 2017 в 18:22
Паша Иванов Паша Иванов
408 2 2 серебряных знака 8 8 бронзовых знаков
А чтобы посмотреть, что получилось после поиска и замены, можно запустить gcc -E
1 сен 2017 в 3:15
Я не понимаю зачем ты это написал — вопрос вообще-то о типе. С тем же успехом мог бы рассказать что такое «выражение» или «компилятор».
1 сен 2017 в 6:10
Тип литерала в #define (и в любом другом месте) задается неявно и определяется тем значением, что вы укажете. 9 имеет тип int , ‘9’ — тоже int , но соответствующий отличному от предыдущей ситуации значению (об этом далее), «9» — char[2] (строковый литерал, в котором один символ это ‘9’ , а второй — терминирующий ноль ‘\0’ ), 9.0 будет иметь тип double , 9.f — float и т.д.
В любом случае для #define вы задаете то значение, которое можно будет использовать в нужном контексте. Хотя здесь и возможны ситуации, когда компилятор молча проглотит, казалось бы, ошибочное значение. Например, при попытке задать массив:
#define N '9' int A[N];
вы получите массив из 57 элементов (соответствует ASCII коду символа ‘9’ ), а не из 9 элементов.
В общем, чтобы понять более точно вашу проблему, хорошо бы увидеть конкретный пример, почему требуется явно указать какой-то специфический тип для дефайна.