определение типа массива по сравнению с использованием структуры в C++

Нашел интересное использование typedef, в котором я действительно не видел необходимости.

typedef int Color[3];

Итак, тогда использование будет:

Color pants;
pants[0] = 0;
etc.

Использование typedef через ptrs создавало странный непонятный код.

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

struct Color {
int r;
int g;
int b;
};

Color pants;
pants.r = 0;
etc.

Вы можете использовать объединение для выражения переменных в виде массива или по отдельности, что шатко, но все же ясно, что это как-то сложнее, чем одно значение.

Может ли кто-нибудь дать представление о достоинствах использования массива typedef и структуры?


person Community    schedule 13.09.2009    source источник


Ответы (6)


Возможно, структура не была выровнена так, как хотел исходный кодер. возможно, он был дополнен до 16 или 32 бит. Создание массива гарантирует отсутствие заполнения структуры. Было ли это передано в драйвер или на какое-то аппаратное устройство?

person Gregor Brandt    schedule 13.09.2009
comment
Хороший. Работает, не беспокоясь о флагах компиляции или pragmas - person dmckee --- ex-moderator kitten; 13.09.2009

Использование простого массива — плохая идея по нескольким причинам.

  • Тип int[] затухает до int * при использовании в списке параметров.
  • Вы не можете использовать operator= для назначения массивов.

Либо struct, либо boost::array подойдут для этой цели гораздо лучше.

person avakar    schedule 13.09.2009
comment
+1 За исключением того, что он не будет распадаться при передаче по ссылке, чтобы добавить путаницы. - person UncleBens; 13.09.2009
comment
UncleBens: проголосовал за ваш комментарий: очень верно. Более подробное обсуждение можно найти здесь: stackoverflow. ком/вопросы/1328223/ - person LaszloG; 13.09.2009
comment
Если аппаратные требования не требуют специальной настройки. Тогда это работает отлично. - person Gregor Brandt; 15.08.2012
comment
@GregorBrandt, можешь уточнить? - person avakar; 16.08.2012
comment
Конечно, когда речь идет об оборудовании, у вас обычно есть ячейки памяти, которые сопоставляются с регистрами или контактами на чипе. Они должны быть в определенном порядке и не иметь заполнения. Например, в исходном вопросе. Возможно, он разговаривает с каким-то видеочипом, которому нужны RGB именно в таком порядке и такого же размера. Таким образом создается массив, а не структура. - person Gregor Brandt; 17.08.2012

Еще одно преимущество формы struct: если вам когда-нибудь понадобится передать Color функции, а затем взять ее размер:

void foo (Color c)
{
    size_t s = sizeof(c);
}

Если вы используете форму массива, c будет интерпретироваться как Color * (массивы передаются через указатель на их первый элемент), а sizeof(c) будет равно sizeof(int*). Был там, сделал это, был укушен там.

Изменить: форма структуры будет вести себя так, как (наивно) ожидалось.

person LaszloG    schedule 13.09.2009
comment
почему бы просто не сделать sizeof(Color)? - person newacct; 13.09.2009
comment
Если вы когда-нибудь измените тип переменной, вам не придется обновлять код в двух (или более) местах. Да, я знаю, что многофайловый поиск-замена, sed и Visual Assist — ваши друзья, но все же предпочитаю не переживать по этому поводу. - person LaszloG; 14.09.2009

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

Поэтому, если вам должны быть формы [rgb], вы используете союз, но это требует больше ввода.

::вздох::

person dmckee --- ex-moderator kitten    schedule 13.09.2009

Возможное заполнение может стать проблемой при использовании массива структур, поскольку у вас могут возникнуть проблемы с преобразованием между этим и целевыми объектами, ожидающими плотно упакованные RGB. В этом случае убедитесь, что заполнение именно то, что вы ожидаете, используя, например, pragma pack().

Что касается того, что лучше .x или [], вы можете перегрузить operator[] для структуры (используя переключатель в этом случае). Любой приличный компилятор оптимизирует это, чтобы оно было эквивалентно static_cast<int*>(this)[index], поэтому потери производительности нет. Можно конечно пойти с профсоюзом, но это мало поможет. Другая возможность — реализовать .x() и т. д. в терминах [].

В любом случае, я бы порекомендовал использовать структуру, так как вы ничего не потеряете (вы все еще можете преобразовать массив из Color в int*, но вы можете писать алгоритмы проще при использовании структуры, чем при использовании int* — например, если вы хотите яркость, проще IMAO иметь хорошую функцию-член/свободу, принимающую цвет вместо int *, потому что с int вы никогда не можете быть уверены, является ли это RGB, RGBA, YoCoCg, а с цветом, вы можете принудительно это сделать.

И последнее, но не менее важное: структура дает вам возможность инициализировать все элементы допустимыми/нормальными/отладочными значениями, если это необходимо.

person Anteru    schedule 13.09.2009

Я предполагаю, что массив использовался как кортеж, поэтому boost::tuple можно рассматривать как альтернативу, которая лучше показывает намерение.

person stefaanv    schedule 13.09.2009