В чем разница между константный инт*, константный тип int * const и int строительства *?
Я всегда путаю, как использовать const int*,const int * const и int const * правильно. Есть ли набор правил, определяющих, что вы можете и не можете сделать?
Я хочу знать все do и все don'T с точки зрения заданий, перехода к функциям и т. д.
14 ответов:
прочитайте его назад (как управляется По Часовой Стрелке/Спираль Правило):
int*- указатель на intint const *- указатель на const intint * const- const указатель на intint const * const- const указатель на const intпервое
constможет быть по обе стороны от типа так:
const int *==int const *const int * const==int const * constесли вы хотите действительно сойти с ума, вы можете делать такие вещи:
int **- указатель на указатель на intint ** const- указатель const на указатель на intint * const *- указатель на const указатель на intint const **- указатель на указатель на const intint * const * const- константный указатель на константный указатель на int- ...
и чтобы убедиться, что мы ясно понимаем значение const
const int* foo; int *const bar; //note, you actually need to set the pointer //here because you can't change it later ;)
foo- это переменная-указатель на постоянное целое число. Это позволяет изменить то, на что вы указываете, но не значение, на которое вы указываете. Чаще всего это видно со строками C-стиля, где у вас есть указатель на Aconst char. Вы можете изменить, на какую строку вы указываете, но вы не можете изменить содержимое этих строк. Это важно, когда сама строка в сегмент данных программы и не должен быть изменен.
barпостоянный или фиксированный указатель на значение, которое может быть изменено. Это как ссылка без дополнительного синтаксического сахара. Из-за этого факта, как правило, вы будете использовать ссылку, где вы будете использоватьT* constуказатель, если вам нужно разрешитьNULLуказатели.
для тех, кто не знает о правиле по часовой стрелке / спирали: Начните с имени переменной, двигайтесь по часовой стрелке (в данном случае назад) к следующему указатель или тип. Повторяйте, пока выражение не закончится.
вот демо:
Я думаю все уже ответили, но я просто хочу добавить, что вы должны остерегаться
typedefs! Это не просто замена текста.например:
typedef char *ASTRING; const ASTRING astring;тип
astringиchar * const, а неconst char *. Это одна из причин, по которой я всегда склонен ставитьconstсправа от типа, а не в начале.
как почти все указали:
в чем разница между
const X* p,X* const pиconst X* const p?вы должны прочитать объявления указателей справа налево.
const X* pозначает "P указывает на X, который является const": объект X не может быть изменен через p.
X* const pозначает "p-это указатель const на X, который не является const": вы не можете изменить сам указатель p, но вы можете изменить объект X через p.
const X* const pозначает "p-это указатель const на X, который является const": вы не можете изменить сам указатель p, и вы не можете изменить объект X через p.
постоянные ссылки:
ссылка на переменную (здесь int), которая является постоянной. Мы передаем переменную как ссылку в основном, потому что ссылки меньше по размеру, чем фактическое значение, но есть побочный эффект, и это потому, что это похоже на псевдоним для фактической переменной. Мы можем случайно изменить основную переменную через наш полный доступ к псевдониму, поэтому мы делаем его постоянным, чтобы предотвратить эту сторону эффект.
int var0 = 0; const int &ptr1 = var0; ptr1 = 8; // Error var0 = 6; // OKконстантными указателями
как только постоянный указатель указывает на переменную, он не может указывать на любую другую переменную.
int var1 = 1; int var2 = 0; int *const ptr2 = &var1; ptr2 = &var2; // Errorуказатель на константу
указатель, с помощью которого нельзя изменить значение переменной, на которую он указывает, называется указателем на константу.
int const * ptr3 = &var2; *ptr3 = 4; // Errorпостоянный указатель на a константа
постоянный указатель на константу-это указатель, который не может ни изменить адрес, на который он указывает, ни изменить значение, хранящееся по этому адресу.
int var3 = 0; int var4 = 0; const int * const ptr4 = &var3; *ptr4 = 1; // Error ptr4 = &var4; // Error
этот вопрос показывает точно почему мне нравится делать все так, как я упомянул в своем вопросе является ли const после идентификатора типа приемлемым?
короче говоря, я нахожу самый простой способ запомнить правило, что "const" идет после то, к чему это относится. Поэтому в вашем вопросе "int const * "означает, что int является постоянным, а" int * const " будет означать, что указатель является постоянным.
Если кто-то решит поставить его в очень фронт (например: "const int *"), как специальное исключение в этом случае он применяется к вещи после него.
многие люди любят использовать это специальное исключение, потому что они думают, что это выглядит лучше. Мне это не нравится, потому что это исключение, и поэтому все путает.
общее правило заключается в том, что
constключевое слово применяется к тому, что непосредственно предшествует ему. Исключение, стартовыйconstотносится к тому, что следует.
const int*это то же самое, чтоint const*и означает "указатель на константу типа int".const int* constэто то же самое, чтоint const* constи означает "постоянный указатель на константу int".Edit: Для Дос и не надо, если ответ не достаточно, не могли бы вы быть более точным о том, что вы хотите?
простое использование 'const'
самое простое использование-объявить именованную константу. Для этого объявляется константа, как если бы это была переменная, но перед ней добавляется "const". Нужно инициализировать его немедленно в конструкторе, потому что, конечно, нельзя установить значение позже, так как это изменило бы его. Например,
const int Constant1=96;создаст целочисленную константу, невообразимо называемую 'Constant1', со значением 96.
такие константы полезны для параметры, которые используются в программе, но не должны быть изменены после компиляции программы. Он имеет преимущество для программистов над командой препроцессора C "#define " в том, что он понимается и используется самим компилятором, а не просто подставляется в текст программы препроцессором до достижения основного компилятора, поэтому сообщения об ошибках гораздо более полезны.
Он также работает с указателями, но нужно быть осторожным, где с const’, чтобы определить, является ли указатель или то, на что он указывает, является постоянным или обоими. Например,
const int * Constant2объявляет, что Constant2 является переменным указателем на постоянное целое число и
int const * Constant2- Это альтернативный синтаксис, который делает то же самое, в то время как
int * const Constant3объявляет, что Constant3 является постоянным указателем на переменное целое число и
int const * const Constant4объявляет, что Constant4 является постоянным указателем на постоянное целое число. В основном "const" применяется к тому, что находится на его непосредственной левой стороне (кроме если там ничего нет, в этом случае он применяется к тому, что является его непосредственным правом).
ref:http://duramecho.com/ComputerInformation/WhyHowCppConst.html
у меня были такие же сомнения как у вас, пока я не наткнулся на этот книги гуру C++ Скотт Мейерс. Обратитесь к третьему пункту этой книги, где он подробно рассказывает об использовании
const.просто следуйте этому совету
- если слово
constпоявляется слева от звездочки, на что указывает константа- если слово
constпоявляется справа от звездочки, сам указатель является константой- если
constпоявляется с обеих сторон, оба являются постоянными
есть много других тонких точек, окружающих правильность const в C++. Я полагаю, что вопрос здесь просто был о C, но я приведу некоторые связанные примеры, так как тег C++:
вы часто передаете большие аргументы, такие как строки, как
TYPE const &что предотвращает изменение или копирование объекта. Пример :
TYPE& TYPE::operator=(const TYPE &rhs) { ... return *this; }но
TYPE & constбессмысленно, потому что ссылки всегда константа.вы всегда должны обозначить методы класса, которые не изменяют класс
const, в противном случае вы не можете вызвать метод изTYPE const &ссылка. Пример :
bool TYPE::operator==(const TYPE &rhs) const { ... }существуют распространенные ситуации, когда и возвращаемое значение, и метод должны быть const. Пример :
const TYPE TYPE::operator+(const TYPE &rhs) const { ... }фактически, методы const не должны возвращать внутренние данные класса как a ссылка на неконстантный.
в результате часто приходится создавать как const, так и неконстантный метод с использованием перегрузки const. Например, если вы определяете
T const& operator[] (unsigned i) const;, то вы, вероятно, также хотите неконстантную версию, заданную :
inline T& operator[] (unsigned i) { return const_cast<char&>( static_cast<const TYPE&>(*this)[](i) ); }Afaik, в C нет функций const, функции, не являющиеся членами, не могут сами быть const в C++, методы const могут иметь побочные эффекты, и компилятор не может использовать const функции, чтобы избежать дублирования функций. На самом деле, даже простой
int const &ссылка может свидетельствовать о том, что значение, на которое она ссылается, будет изменено в другом месте.
это просто, но сложно. Обратите внимание, что мы можем поменять
constквалификатор с любым типом данных (int,char,floatи т. д.).давайте посмотрим на примеры.
const int *p==>*pдоступно только для чтения [p- указатель на постоянное целое число]
int const *p==>*pдоступно только для чтения [p- указатель на постоянное целое число]
int *p const==>неправильно заявление. Компилятор выдает синтаксическая ошибка.
int *const p==>pдоступно только для чтения [pпостоянный указатель на целое число]. Как указательpздесь только для чтения, объявление и определение должны быть в одном месте.
const int *p const==>неправильно заявление. Компилятор выдает синтаксическую ошибку.
const int const *p==>*pдоступно только для чтения
const int *const p1==>*pиpтолько для чтения [pпостоянный указатель на константу целое.] Как указательpздесь только для чтения, объявление и определение должны быть в одном месте.
int const *p const==>неправильно заявление. Компилятор выдает синтаксическую ошибку.
int const int *p==>неправильно заявление. Компилятор выдает синтаксическую ошибку.
int const const *p==>*pдоступно только для чтения и эквивалентноint const *p
int const *const p==>*pиpтолько для чтения [pпостоянная указатель на постоянное целое число]. Как указательpздесь только для чтения, объявление и определение должны быть в одном месте.
синтаксис объявления C и C++ неоднократно описывался оригинальными разработчиками как неудачный эксперимент.
давайте имя тип "указатель наType"; Я назову егоPtr_:template< class Type > using Ptr_ = Type*;теперь
Ptr_<char>- это указатель наchar.
Ptr_<const char>указательconst char.и
const Ptr_<const char>этоconstуказатель наconst char.там.
const с int с обеих сторон сделает указатель на константу типа int.
const int *ptr=&i;или
int const *ptr=&i;const после ' * ' сделает постоянный указатель на int.
int *const ptr=&i;в данном случае все это указатель на постоянное целое число, но ни один из них не является постоянным указателем.
const int *ptr1=&i, *ptr2=&j;в этом случае все указатель на постоянное целое число и ptr2-это постоянный указатель к постоянному целому числу. Но ptr1 не является постоянным указателем.
int const *ptr1=&i, *const ptr2=&j;
в основном это касается второй строки: лучшие практики, назначения, параметры функций и т. д.
общей практикой. Постарайтесь сделать все
constЧто вы можете. Или, говоря по-другому, сделать всеconstдля начала, а затем удалить точно минимальный наборconsts необходимо, чтобы программа функционировала. Это будет большой помощью в достижении const-корректности и поможет гарантировать, что тонкие ошибки не будут введены, когда люди пытаются назначить в вещи, которые они не должны изменять.избегайте const_cast как чума. Есть один или два законных случая использования для него, но их очень мало и далеко друг от друга. Если вы пытаетесь изменить






Comments