Указатель = & буфер [0] избыточен? - PullRequest
0 голосов
/ 26 января 2019

Я недавно читал некоторый исходный код и прочитал следующее в начале функции:

char buffer[ 1000 ];
char *pointer;
pointer = &buffer[0];

Полагаю, я этого не понимаю. Почему бы просто не написать:

pointer = buffer;

Есть ли какое-то тайное значение, которое я здесь упускаю?

Ответы [ 4 ]

0 голосов
/ 26 января 2019

Из стандартов C # 6.5.2.1

Определение оператора индекса [] заключается в том, что E1 [E2] идентичен (* ((E1) + (E2))) ..

Итак,

&buffer[0]

можно записать как

&(*(buffer + 0))

Обратите внимание, что оператор & используется для получения адреса, а оператор * используется для разыменования.Эти операторы отменяют влияние друг друга при использовании один за другим.Таким образом, это эквивалентно

(buffer + 0)

, что является ничем иным, как

buffer

Итак, &buffer[0] эквивалентно buffer.

0 голосов
/ 26 января 2019

Они абсолютно одинаковые.Я также предпочитаю более простую версию

pointer = array; // implicit conversion from array to address of its 1st element
pointer = &array[0]; // explicitly set pointer to the address of array's 1st element

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

0 голосов
/ 26 января 2019

Оба выражения дают одинаковое значение результата. Так что в вашем конкретном случае это в основном вопрос предпочтительного стиля.

Но есть разница, если вы используете выражения, например, при вызове функции. Инструмент статического анализа кода должен жаловаться на

memcpy (& buffer [0], src, 2 * sizeof (buffer [0]));

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

memcpy (& buffer, src, 2 * sizeof (buffer [0]));

или

memcpy (буфер, src, 2 * sizeof (буфер [0]));

потому что теперь вы говорите, что хотите записать в полный массив.

Соответствующие детали в стандарте :

6.3.2.1 L-значения, массивы и функциональные обозначения
3 За исключением случаев, когда это операнд оператора sizeof или унарный оператор &, или строковый литерал, используемый для инициализации массива, выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип», который указывает на начальный элемент объекта массива и не является lvalue. [...]

6.5.3.2 Операторы адреса и переадресации

Семантика 3 Унарный оператор & выдает адрес своего операнда. Если операнд имеет тип «тип», результат имеет тип «указатель на тип». [...] Аналогично, если операнд является результатом оператора [], ни оператор &, ни унарный *, подразумеваемый [], не оцениваются, и результат такой, как если бы оператор & был удален, а [ ] оператор был заменен на оператор +. В противном случае результатом является указатель на объект или функцию, обозначенный его операндом.

0 голосов
/ 26 января 2019

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

Кто-то может сказать, что когда вы используете pointer = buffer;, вы намереваетесь использовать указатель в качестве буфера,

, а есливы используете pointer = &buffer[0]; вы намерены использовать указатель в качестве указателя или элемента буфера.

Бывает, что эти два случая указывают на один и тот же адрес.

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