В C это нормально использовать & и [] вместе, чтобы быстро получить указатель на объект в массиве? - PullRequest
0 голосов
/ 15 мая 2019

Я знаю, что это работает, чтобы получить индекс (и автоматически выполнять арифметику указателей):

struct Obj *c = &p[i];

Однако, имеет ли это снижение производительности по сравнению с выполнением арифметики с указателем вручную?

struct Obj *c = p+i;

Есть ли причины, по которым следует избегать первого?

Ответы [ 4 ]

5 голосов
/ 15 мая 2019

Однако имеет ли это снижение производительности по сравнению с выполнением арифметики с указателем вручную?

Выражения, использующие оператор индексирования, определены , чтобы быть эквивалентными соответствующим операциям, включающим арифметику указателя и разыменование, поэтому

&p[i]

в точности эквивалентно

&(*(p + i))

Кроме того, в стандарте указывается, что когда операнд оператора & является результатом оператора *, ни один из них не оценивается, и результат такой, как если бы оба опущены, что, в свою очередь, эквивалентно

p + i

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

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

Есть ли причины, по которым следует избегать первого?

Не очень. Последний имеет меньшую когнитивную нагрузку и его легче читать, поскольку (синтаксически) он включает только одну операцию, а не две. Я склонен предпочесть это сам по этой причине. С другой стороны, понимание может быть немного менее интуитивным.

2 голосов
/ 15 мая 2019

Да, все в порядке. Фактически, когда вы используете p, оно фактически совпадает с & p [0] с точки зрения компилятора. Всегда позволяйте компилятору делать математику указателей за вас, используйте первую форму.

2 голосов
/ 15 мая 2019

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

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

struct Mobj *c = p + i * sizeof(struct Obj);

Там, где вы забыли обновить часть sizeof, и теперь ваш код очень поврежден.

Это, конечно, упускает из виду тот факт, что когдаделая указатель по математике, он все равно будет автоматически увеличиваться на размер структуры, то есть:

p[i] == *(p + i)

Но в вашем случае вы фактически делаете следующее:

p[i * sizeof(Obj)]

Чтоэто не то, что вы намереваетесь.

Меньше значит больше.Кодирование достаточно сложно, не переусердствуйте.

0 голосов
/ 15 мая 2019

Стандарт C гласит, что &array[index] в точности эквивалентно array + index. Это означает, что оба делают арифметику указателей, поэтому они не должны быть одинаковыми.

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

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