Об основах указателя в C - PullRequest
0 голосов
/ 16 марта 2011

Что касается указателей (в структурах для этого случая), я понимаю, что если бы 'a' была структурой, а 'b' объявлена ​​внутри структуры, то мы можем получить доступ к данным через:

a->b

А теперь я недавно обнаружил, что в С есть много горячих клавиш для указателей, одним из которых будет оператор стрелки, как указано выше.

Я видел, как 'a-> b' было написано как '[a] + b', например:

a->b <=> [a] + b //meaning that they are interchangeable

Однако у меня возникают проблемы с пониманием того, что на самом деле означает «[a] + b», и я был бы очень признателен за то, что кто-то выложил мне детали (или, возможно, я неправильно понял, а вышесказанное - чушь!) Большое спасибо заранее!

Ответы [ 2 ]

3 голосов
/ 16 марта 2011

На языке C [a] + b ничего не значит. Это синтаксическая ошибка. Ваша книга, вероятно, использует эту запись, чтобы объяснить что-то, но вне контекста это ничего не значит. Тем не менее, он похож на несколько других сочетаний клавиш, чтобы вызвать путаницу. Итак, чтобы развеять эту путаницу, вот все сочетания клавиш, о которых я могу подумать:

  • a->b является синонимом для (*a).b, то есть для доступа к элементу указателя на тип struct.
  • a[b] является синонимом для *(a + b), то есть для доступа к элементу массива путем выполнения арифметики указателя с указанным смещением.
    • Обратите внимание, что из-за вышеизложенного a[b] является синонимом b[a], потому что a[b] <=> *(a + b) <=> *(b + a) <=> b[a]. Злые обманщики будут делать такие вещи, как 0[x] или 5["string"], чтобы сбить вас с толку. Не бойся, пока ты знаешь ответ.
  • *&a - это синоним a, то есть разыменование адреса. Он создает указатель, а затем немедленно разыменовывает его, получая исходный объект.
    • Обратите внимание, что &a[b] означает &*(a + b), что означает a + b. И &a[b], и a + b создают указатели на элемент массива одинаково. Какой путь является «лучшим», зависит от личных предпочтений, места работы и фазы луны.
    • Обратите внимание, что &*a отличается от *&a. Последний создает указатель, затем разыменовывает его, получая исходный объект. Первый предполагает, что a является указателем, разыменовывает его, затем получает адрес результата, получая исходный указатель. Стандарт &*a предписывает не разыменовывать указатель и может безопасно использоваться для указателя NULL.
  • *(type *)&a - это злой хак, который вы можете время от времени видеть. Он берет адрес a, приводит указатель к указателю на type и разыменовывает его. Это обычно неопределенное поведение *, но на практике биты объекта a будут интерпретироваться как объект type. Это позволяет вам получить, например, побитовое представление float s или других объектов. Возможно, есть более эффективные способы достижения этой цели, но если вы когда-нибудь наткнетесь на эту строку кода, вы, по крайней мере, будете знать, что авторы намеревались сделать.

Я добавлю больше, если подумаю о них.

* Я говорю не определено, потому что, если вы сделали int i = -1; printf("%u\n", *(unsigned int)&i);, стандарт C не предписывает, будет ли печататься значение UINT_MAX (для дополнения до двух), UINT_MAX - 1 (для дополнения до одного) или (unsigned int)INT_MAX + 2 (для знака и величины).

0 голосов
/ 16 марта 2011

Как уже указывалось, [a]+b недействительно C. Может, он имел в виду

a->b <=> a[0].b
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...