В чем смысл нескольких константных квалификаторов?
-
21-12-2019 - |
Вопрос
Код:
const char* const* const* foo(int bar);
Раньше я видел двойные константы, которые также предотвращали изменение указателя.Впервые в жизни вижу тройную константу.Интересно, в чем его польза?
Решение
В вашем примере все, кроме верхнего уровня косвенности, все const
квалифицированный.
const char /* const qualified base level */
*const /* const qualified level 1 */
*const /* const qualified level 2 */
* /* regular level 3 */
foo(int bar);
foo
это функция, которая принимает int
аргумент и возвращает обычный указатель.
Указатель, который он возвращает, указывает на const
квалифицированный указатель
что, в свою очередь, указывает на другое const
квалифицированный указатель
что указывает на const
квалифицированный char
Другие советы
Если у вас есть многоуровневый указатель, у вас есть несколько переменных указателей.Пример:
char*** foo;
.
доступно так:
| foo | pointer1 | pointer2 | string |
| ^ | ^ | ^
\___/ \___/ \___/
.
Вы можете получить квалификацию каждого из четырех мест в памяти как const
, как в декларации
const char *const *const *const foo;
.
Тем не менее, лучше избегать трехзвездочного программиста.
Ха - суматоха вокруг const
.
По сути, если он квалифицирует указатель, он применяется к указателю непосредственно слева от него.Например:
char *const c;
делает c
указатель, доступный только для чтения char
, тогда как
const char *c;
Делает c
указатель на доступный только для чтения char
, хотя вы можете изменить место c
указывает на.
Конечно, и указатель, и то, на что он указывает, можно сделать доступными только для чтения:
const char *const c;
Это делает c
указатель только для чтения на доступный только для чтения char
.С помощью предыдущего объявления вы можете изменить *c
, но вы не можете изменить c
(т.е.вы не можете указать на другое место).С помощью второго вы можете назначить c
но не для того *c
, а в третьем вы не можете изменить место, на которое он указывает, а также не можете изменить объект, на который указывает.
Это распространяется на несколько уровней косвенности.В вашем случае вы можете перегруппировать const
ключевые слова с соответствующим указателем, к которому они относятся.В основном это проблема пробелов, но это было бы так:
const char *const *const *foo(int bar);
Что делает foo
вернуть указатель на указатель, доступный только для чтения, на указатель, доступный только для чтения, на указатель, доступный только для чтения char
.Прочтите это внимательно:обратите внимание, что учитывая этот фрагмент кода:
const char *const *const *ptr = foo(0);
Тогда вы знаете, что присвоение ptr
законно, но любое другое присвоение незаконно, а именно, вы не можете назначить *ptr
, **ptr
, и ***ptr
.
foo
Возвращает генеракодицетагкод, который указывает на генеракодицетагкод, который указывает на другой генеракодицетагкод, который указывает на генеракодицетагкод.Посмотрите на Спиральное правило .
int bar;
const char* const* const* ptr = foo(bar);
.
Так что в основном вы не можете изменить ни один из генеракодицетагкода или генеракодицетагкода или генеракодицетагкод.