Понимание того, куда "const" идет в объявлении - PullRequest
12 голосов
/ 06 июля 2011

У меня проблемы с поиском интуитивно понятного шаблона для использования const в объявлениях на языках C и C ++.Вот несколько примеров:

const int a;    //Const integer
int const a;    //Const integer
const int * a;  //Pointer to constant integer
int * const a;  //Const pointer to an integer
int const * a const;    //Const pointer to a const integer

В строках 1 и 2 кажется, что const может идти до или после int, что и изменяет его.

  1. Таккак в строке 4 компилятор решает, что const изменяет * (указатель), а не int?
  2. Каково правило, которому следует компилятор, чтобы решить, какую вещь constотносится к?
  3. Следует ли то же правило для *?

Ответы [ 5 ]

7 голосов
/ 06 июля 2011

Если вы всегда помещаете const в справа типа, вы можете прочитать объявление переменной как предложение справа налево:

int const x;        // x is a constant int
int *const x;       // x is a constant pointer to an int
int const *x;       // x is a pointer to a constant int
int const *const x; // x is a constant pointer to a constant int

Это все еще работает, еслиВы ставите const слева от типа, но требует немного больше умственных усилий.Обратите внимание, что это работает так же хорошо с указателями на указатели (и конструкции более высокого порядка):

int *const *const x; // x is a constant pointer to a constant pointer to an int
5 голосов
/ 06 июля 2011

Компилятор обычно читает тип справа налево, поэтому:

T const& const

будет читаться как:

 const (a constant)
 & (to a reference)
 const (to a constant)
 T (of type T)

Итак, в основном ключевое слово "const" изменяет все, что ему предшествует. Однако, есть исключение в случае, когда «const» стоит первым, и в этом случае он изменяет элемент прямо справа от него:

const T& const

Выше читается как:

const (a constant)
& (to a reference)
const T (to a constant of type T)

А приведенное выше эквивалентно T const & const.

Хотя компилятор так и поступает, я действительно рекомендую запомнить случаи "T", "const T", "const T &", "const T *", "const T & const", "const T * const "," T & const "и" T * const ". Вы редко встретите какой-либо другой вариант «const», и когда вы это сделаете, вероятно, будет хорошей идеей использовать typedef.

2 голосов
/ 06 июля 2011

Что касается указателей, вот один, который я взял из одной из книг Скотта Мейерса (я думаю). Нарисуйте вертикальную линию через *, и тогда все, что находится на той же стороне линии, что и ключевое слово const, - это то, что является const.

Для уточнения:

int * const a означает, что const, а не int. А «a» - указатель на (неконстантный) int.

0 голосов
/ 06 июля 2011

Ключом к пониманию этого является осознание того, что * связывается с a, а не с типом.Поэтому вы должны прочитать их как:

const int a;    // a has type const int
int const a;    // a has type int const
const int * a;  // *a has type const int
int * const a;  // *(const a) has type int, which means *a has type int and a is const
int const * a const;    // *(const a) has type int const, which means *a has type const int and a is const.

(Обратите внимание, что ссылки на C ++ не следуют этому правилу).

0 голосов
/ 06 июля 2011

Ну, для начала, этот вопрос больше личного предпочтения.Для программистов на досуге это скорее личный стиль.Тем не менее, для тех, кто имеет дело с корпорациями, может быть какое-то соглашение о кодировании, которое они планируют, чтобы программисты следовали так, чтобы у всех были согласованные стили кодирования.

(1) Для const int * const a; это означаетчто вы не можете изменить то, на что указывает ваш указатель, но вы можете изменить это место в памяти.

(2) «const» определяется вами, как программистом, хотите ли вы указывать адрес, на который указывает указатель, быть постоянным или если вы хотите, чтобы указатель НЕ изменял указатель, на который он указывает.

(3) Да, правила * такие же, как и в случае const int * const a;

В качестве дополнительного примечания, ваша последняя строка недействительна C89.

Надеюсь, это поможет.Ура! * * 1013

...