В чем разница между константный инт*, константный тип int * const и int строительства *?



Я всегда путаю, как использовать const int*,const int * const и int const * правильно. Есть ли набор правил, определяющих, что вы можете и не можете сделать?



Я хочу знать все do и все don'T с точки зрения заданий, перехода к функциям и т. д.

702   14  

14 ответов:

прочитайте его назад (как управляется По Часовой Стрелке/Спираль Правило):

  • int* - указатель на int
  • int const * - указатель на const int
  • int * const - const указатель на int
  • int const * const - const указатель на const int

первое const может быть по обе стороны от типа так:

  • const int * ==int const *
  • const int * const == int const * const

если вы хотите действительно сойти с ума, вы можете делать такие вещи:

  • int ** - указатель на указатель на int
  • int ** const - указатель const на указатель на int
  • int * const * - указатель на const указатель на int
  • int const ** - указатель на указатель на const int
  • int * 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-стиля, где у вас есть указатель на A const char. Вы можете изменить, на какую строку вы указываете, но вы не можете изменить содержимое этих строк. Это важно, когда сама строка в сегмент данных программы и не должен быть изменен.

bar постоянный или фиксированный указатель на значение, которое может быть изменено. Это как ссылка без дополнительного синтаксического сахара. Из-за этого факта, как правило, вы будете использовать ссылку, где вы будете использовать T* const указатель, если вам нужно разрешить NULL указатели.

для тех, кто не знает о правиле по часовой стрелке / спирали: Начните с имени переменной, двигайтесь по часовой стрелке (в данном случае назад) к следующему указатель или тип. Повторяйте, пока выражение не закончится.

вот демо:

pointer to int

const pointer to int const

pointer to int const

pointer to const int

const pointer to int

Я думаю все уже ответили, но я просто хочу добавить, что вы должны остерегаться 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.

  1. постоянные ссылки:

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

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
    
  2. константными указателями

    как только постоянный указатель указывает на переменную, он не может указывать на любую другую переменную.

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
    
  3. указатель на константу

    указатель, с помощью которого нельзя изменить значение переменной, на которую он указывает, называется указателем на константу.

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
    
  4. постоянный указатель на 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.

просто следуйте этому совету

  1. если слово const появляется слева от звездочки, на что указывает константа
  2. если слово const появляется справа от звездочки, сам указатель является константой
  3. если 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.

там.

enter image description here

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

    Ничего не найдено.