хитрая арифметика с указателями в C: ** k - PullRequest
0 голосов
/ 20 февраля 2019

Предположим, что k является указателем на целое число в C.

Для выражения ** k, когда мы попытаемся оценить это справа от оператора присваивания ("="), будет ли значениебыть незаконным?

Вот моя мысль:

** k на самом деле * (* k).Когда мы разыменовываем k, мы получаем значение целого числа.Затем мы пытаемся разыменовать целое число, что является недопустимой операцией.

Но в моем учебнике говорится, что это выражение на правой стороне действительно допустимо.

Почему так?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Помимо того, что стандарт говорит, разыменование int принципиально не имеет смысла.Допустим, компилятор готов предположить, что целые числа могут быть преобразованы непосредственно в указатели (БОЛЬШОЕ предположение).Какой тип указателя будет предполагать компилятор?Единственное безопасное предположение - void*.И разыменование void* не имеет смысла, потому что даже при назначении на известный тип указатель типа все еще имеет значение:

  unsigned int n = 0xFFFFFFFF;
  void *pN = &n;
  unsigned int fromIntPtr = *(unsigned int*)pN;
  unsigned int fromCharPtr = *(unsigned char*)pN;
  printf("%X\n", fromIntPtr);
  printf("%X\n", fromCharPtr);

Вывод:

FFFFFFFF
FF

Не имея указателя типа, компилятор может вывести unsigned int* на основе выражения LHS.Это 1) дико глупый умозаключение и 2) C на самом деле не выводит типы.(Вставка набранного RHS в другое значение LHS не является логическим выводом:))

0 голосов
/ 20 февраля 2019

Стандарт C 2018 гласит, в пункте 6.5.3.2, параграф 2: «Операнд унарного оператора * должен иметь тип указателя». Если k - указатель на целое число, то *k -целое число, не являющееся типом указателя, поэтому оно не может быть операндом унарного оператора *.Таким образом, такое выражение, как x = **k нарушает это правило.

Правило ins 6.5.3.2 2 является ограничением, означающим, что для создания диагностического сообщения требуется соответствующий компилятор, а стандарт C не определяетповедение.

Технически, компилятор C мог бы, в дополнение к выдаче диагностического сообщения, принять выражение и определить, как пожелает.Я не знаю ни одного, кто это делает, и ни один из распространенных компиляторов не делает этого.

Возможно, символы **k могут появиться в каком-то большем выражении, где они оба не действуют как унарные операторы *,например, в x = y**k, что эквивалентно x = y * *k, в котором первый * является оператором двоичного умножения.Вы должны показать точный текст , показанный в вашем учебнике.

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