Подтвердить что ты не робот

Понимая, где "const" идет в декларации

Мне трудно найти интуитивный шаблон для того, как const используется в объявлениях на языках 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, что и изменяет.

  • Итак, как в строке 4 компилятор решает, что const изменяет * (указатель), а не int?
  • Какое правило следует использовать компилятору для определения того, к чему относится const?
  • Соответствует ли это правилу для *?
4b9b3361

Ответ 1

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

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 & Уст.

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

Ответ 2

Предполагая, что вы всегда располагаете 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

Ответ 3

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

Чтобы уточнить:

int * const a означает, что a является const, а не int. И "a" является указателем на int (не const const).

Ответ 4

Ключом к пониманию этого является осознание того, что * привязывается к 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.

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

Ответ 5

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

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

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

(3) Да, правила одинаковы для *, как в случае const int * const a;

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

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