Каковы используются константные указатели (в отличие от указателей на объекты 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.