указатель на const и нормальный указатель можно смешивать? - PullRequest
5 голосов
/ 03 мая 2011

Значение * b не определено при вызове printf ()?

void foo(int *a) {
  const int *b = a;
  int *c = a;
  *c = 2;
  printf("%d\n", *b); // what must be *b? 1, 2 or undefined?
}

int d = 1;
foo(&d);

Ответы [ 6 ]

11 голосов
/ 03 мая 2011

Будет напечатано 2. const int *b буквально означает:

Указатель на целое число, значение которого нельзя изменить путем его разыменования.

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

Представьте себе драйвер или аналогичный объект, который раздает отображение памяти только для чтения любых данных, которые доставило устройство: адресотображение не является постоянным, но, поскольку это отображение только для чтения, пользовательская программа может не записывать в него.OTOH, когда устройство обновляет данные, содержимое буфера изменится, но не обязательно адрес сопоставления.

2 голосов
/ 03 мая 2011

Стандарт говорит (мой акцент)

6.7.3 / 5

Если предпринята попытка изменить объект , определенный с квалифицированный const тип через использование lvalue с не квалифицированный const тип, поведение не определено.

Это не относится к вашей ситуации (наоборот).
Данный объект был определен с простым (int) типом.

В вашей ситуации только изменения объекта через b недопустимы; изменения через a или c совершенно законны

0 голосов
/ 03 мая 2011

Объявление const int *b = a; означает, что b относится к постоянному значению int.Это означает, что он обрабатывает свое значение как постоянное значение.

Таким образом,

*b = 10;

неверно, но:

a = 10;

хорошо, так какне постоянное значение, но при разыменовании b мы рассматриваем его как константу.

Итак, b определенно определено, так как вы изменили значение, на которое оно указывало:

c = 2;

, то есть то же самоекак пример выше.Проще говоря, указатель на значение const не может изменить значение посредством разыменования, но в противном случае значение, на которое он указывает, может быть изменено.

0 голосов
/ 03 мая 2011

b должно быть 2 в printf ().Вы обрабатываете указатель все время в b и c.

0 голосов
/ 03 мая 2011

*b будет 2, потому что последняя строка перед printf, которая устанавливает значение, является *c = 2.

a, b и c все указывают на одно и то жецелочисленное значение.Поэтому последний, кто установит его, будет определять его текущее значение.

0 голосов
/ 03 мая 2011

Поскольку b указывает на ту же память, что и a, значение, конечно, изменится.Не уверен, почему вы также ввели c, но это ничего не добавляет.Будет напечатано 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...