Каковы используются константные указатели (в отличие от указателей на объекты const)?
Я часто использовал указатели на объекты const, например...
const int *p;
Это просто означает, что вы не можете изменить целое число, которое p
указывает на p
. Но я также видел ссылку на константные указатели, объявленные вот так...
int* const p;
Как я понимаю, это означает, что переменная указателя сама по себе постоянна - вы можете изменить целое число, которое оно указывает на весь день, но вы не можете указать на что-то еще.
Какое возможное использование имеет?
Ответы
Ответ 1
Когда вы разрабатываете C-программы для встроенных систем или программы специального назначения, которые должны ссылаться на одну и ту же память (многопроцессорные приложения, использующие память), вам понадобятся постоянные указатели.
Например, у меня есть 32-битный MIP-процессор, который имеет маленький ЖК-экран. Мне приходится записывать данные на ЖК-дисплее в определенный порт в памяти, который затем отправляется на ЖК-контроллер.
Я мог бы #define это число, но тогда я также должен использовать его как указатель, а у компилятора C не так много вариантов, когда я это делаю.
Кроме того, мне может потребоваться, чтобы он был volatile, который также может быть запущен, но проще и понятнее использовать предоставленный синтаксис - указатель на константу в ячейке памяти.
Для ПК-программ примером может быть: Если вы разрабатываете игры DOS VGA (есть онлайн-учебники, которые интересны для изучения базовой низкоуровневой графики), тогда вам нужно записать в VGA-память, на которую можно ссылаться как смещение от указателя const.
-Adam
Ответ 2
Он позволяет защитить указатель от изменения. Это означает, что вы можете защитить допущения, которые вы делаете, на основе указателя, который никогда не меняется или от непреднамеренной модификации, например:
int* const p = &i;
...
p++; /* Compiler error, oops you meant */
(*p)++; /* Increment the number */
Ответ 3
другой пример:
если вы знаете, где он был инициализирован, вы можете избежать будущих проверок NULL.
Компилятор гарантирует, что указатель никогда не изменился (до NULL)...
Ответ 4
В какой-либо не-const-членной функции С++ указатель this
имеет тип C * const
, где C
- тип класса - вы можете изменить то, на что оно указывает (т.е. его члены), но вы можете 't изменить его, чтобы указать на другой экземпляр C
. Для const
функций-членов this
имеет тип const C * const
. Существуют также (редко встречающиеся) функции-члены volatile
и const volatile
, для которых this
также имеет квалификатор volatile
.
Ответ 5
Одно использование - это низкоуровневый (драйвер устройства или встроенный) код, где вам нужно ссылаться на конкретный адрес, который сопоставляется с устройством ввода/вывода, например, с аппаратным выводом. Некоторые языки позволяют связывать переменные с определенными адресами (например, Ada имеет use at
). В C самый идиоматический способ сделать это - объявить постоянный указатель. Обратите внимание, что такое использование должно также иметь квалификатор volatile
.
В других случаях это просто защитное кодирование. Если у вас есть указатель, который не должен изменять его, чтобы объявить его таким, что он не может измениться. Это позволит компилятору (и инструментам линта) обнаруживать ошибочные попытки его модифицировать.
Ответ 6
То же, что и "const int"... если компилятор знает, что он не изменится, это могут быть предположения оптимизации на основе этого.
struct MyClass
{
char* const ptr;
MyClass(char* str) :ptr(str) {}
void SomeFunc(MyOtherClass moc)
{
for(int i=0; i < 100; ++i)
{
printf("%c", ptr[i]);
moc.SomeOtherFunc(this);
}
}
}
Теперь компилятор мог бы сделать немного, чтобы оптимизировать этот цикл - если он знает, что SomeOtherFunc() не изменяет значение ptr. С константой компилятор знает это и может делать предположения. Без этого компилятор должен предположить, что SomeOtherFunc изменит ptr.
Ответ 7
Я всегда использовал их, когда хотел избежать непреднамеренной модификации указателя (например, арифметики указателя или внутри функции). Вы также можете использовать их для шаблонов Singleton.
'this' является жестко запрограммированным указателем константы.
Ответ 8
Я видел некоторый OLE-код, в котором вы были объектом, переданным извне кода и для работы с ним, вам приходилось обращаться к определенной памяти, в которую она была передана. Таким образом, мы использовали указатели const, чтобы гарантировать, что функции всегда манипулировали значениями, чем через интерфейс OLE.
Ответ 9
В качестве ответов на эти вопросы были даны несколько веских причин (устройства с отображением памяти и просто старое защитное кодирование), но я готов поспорить, что большинство случаев, когда вы видите это, на самом деле являются ошибкой и что намерение должен был иметь значение item для указателя на константу.
У меня, конечно, нет данных для резервного копирования этой догадки, но я все равно сделаю ставку.
Ответ 10
Подумайте о типа * и const type * как о самих типах. Затем вы можете понять, почему вы, возможно, захотите иметь константу этих типов.
Ответ 11
всегда думают о указателе как int. это означает, что
object* var;
на самом деле можно считать
int var;
поэтому указатель const просто означает, что:
const object* var;
становится
const int var;
и, следовательно, u не может изменить адрес, на который указывает указатель, и все это. Чтобы предотвратить изменение данных, u должен сделать его указателем на объект const.