В следующей строке кода, какова цель ключевых слов const
?volatile unsigned int * const
volatile unsigned int * const UART0DR = (unsigned int *)0x10009000;
Я понимаю volatile unsigned int *
немного, но почему const
там?
В следующей строке кода, какова цель ключевых слов const
?volatile unsigned int * const
volatile unsigned int * const UART0DR = (unsigned int *)0x10009000;
Я понимаю volatile unsigned int *
немного, но почему const
там?
const
и volatile
называются "классификаторы типа". Их синтаксис является одной из самых запутанных вещей в C.
Прежде всего, мы имеем случай с обычной переменной. Обычно вы указываете спецификатор типа перед именем переменной: const int x;
, но также хорошо писать его после имени переменной: int const x;
. Смысл один и тот же, последний синтаксис просто путается.
При объявлении указателя вы имеете дело с двумя типами: типом самого указателя и типом, на который указывает. С обычными указателями это тривиально: int* x
означает, что тип указателя является указателем-на-int, а указательный тип - int.
Если указательный тип является const int, указатель объявляется как const int* x
. Указатель имеет тип pointer-to-const-int, а указательный тип - const int. Если вы хотите все запутать, вы также можете написать int const* x
, это эквивалентно.
Скажем, мы хотим, чтобы и сам указатель был постоянным. По какой-то причине мы хотим заблокировать программиста от изменения указанного адреса. Например, возможно, указатель должен храниться в постоянной памяти встроенной системы. Постоянный указатель на данные объявляется как int*const x;
с ключевым словом const после *. Указанный тип в этом случае равен int
, а неconst int
.(Я пытаюсь написать const вместе с *, без пробела между ними, чтобы подчеркнуть, что указатель является постоянным)
Если мы хотим, чтобы указательный тип был постоянным, мы бы должны объединить два указанных выше объявления: const int*const x;
означает постоянный указатель, указывающий на константу int.
const int x; // x is a constant data variable
int const x; // x is a constant data variable
const int* x; // x is a non-constant pointer to constant data
int const* x; // x is a non-constant pointer to constant data
int*const x; // x is a constant pointer to non-constant data
const int*const x; // x is a constant pointer to constant data
В приведенных выше примерах я использовал тип спецификатор const
. Но volatile
также является классификатором типов, и он ведет себя точно так же! Можно объявить энергонезависимые указатели на летучие данные и т. Д.
И, наконец, можно комбинировать различные классификаторы. Например, volatile const int*
является непостоянным, энергонезависимым указателем на данные volatile const. Еще раз у нас есть замечательный вариант смешать их порядок, чтобы смутить, поэтому мы также можем написать volatile int const *
или int volatile const *
и т. Д., И все это означает то же самое.
Я понимаю volatile unsigned int *
бит, но почему именно const
?
Это означает, что указатель является постоянным, что означает, что указатель не может (а не должен) указывать на любой другой адрес.
Обратите внимание на следующее, конструирует:
volatile unsigned int * const UART0DR =
Указатель постоянен здесь.
volatile unsigned int const * UART0DR =
Указанный адрес постоянен здесь.
volatile unsigned int const * const UART0DR =
Указанный адрес, а также указатель постоянен в этом случае.
Спасибо. Итак, 'const' для какой-то оптимизации компилятора? – Randomblue
@Randomblue: это спецификатор, который сообщает компилятору, что этот конкретный объект является постоянным и не будет меняться. Это помогает компилятору указывать ошибки в тех же случаях, а также * может * разрешать компилятору применять оптимизации. Большинство ipmortantly сообщает пользователям вашего исходного кода важную информацию о конкретной переменной, просто прочитав ее декларацию. –
«Указанный адрес здесь постоянный». Скорее, содержимое_ указательного адреса. – Lundin
volatile unsigned int *const a
=>
declare a as const pointer to volatile unsigned int
+1, хорошее объяснение типов квалификаторов, но ОП спрашивают, почему он используется в его коде – jeb
Спасибо. Один быстрый вопрос. Является ли 'int * x' эквивалентным' int * int x'? – Randomblue
'volatile const int * ptr *' -> указатель на данные, которые были предоставлены только разрешению на чтение кодом, но могут быть изменены внешними событиями (прерываниями и т. Д.) –