Действительно ли это - лучшая практика для обертывания массивов и их переменной длины в структуре в C?

Он остается внутри текущей области видимости, самой внешней области блока (или глобальной области видимости, которую так хорошо упоминает Берги), так что это будет работать

<script>
let world = 'world';
</script>
<script>
console.log( `hello ${world}` );
</script>
[112 ]

Где бы это не было

<script>
{
  let world = 'world';
}
</script>
<script>
console.log( `hello ${world}` );
</script>

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

5
задан unwind 19 March 2009 в 13:34
поделиться

10 ответов

Несомненно, можно сделать это. Не уверенный, если я назвал бы это лучшей практикой, но это - конечно, хорошая идея сделать C довольно элементарными массивами немного более управляемый. При необходимости в динамических массивах это - почти требование для группировки, различные поля должны были сделать бухгалтерию вместе.

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

Много раз массивы только используются локально и имеют статический размер, который является почему sizeof оператор так удобен для определения числа элементов. Ваш синтаксис немного выключен с этим, между прочим, вот то, как это обычно смотрит:

int array[4711];
int i;

for(i = 0; i < sizeof array / sizeof *array; i++)
{
  /* Do stuff with each element. */
}

Помните это sizeof не функция, круглая скобка не всегда необходимы.

Править: Один реальный пример обертывания точно, поскольку то, что Вы описываете, является типом GArray, обеспеченным бойким. Видимая пользователем часть объявления точно, что Вы описываете:

typedef struct {
  gchar *data;
  guint len;
} GArray;

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

3
ответ дан 18 December 2019 в 09:10
поделиться

Да это - большая практика, чтобы иметь в C. Абсолютно логично перенести связанные значения в содержание структуры.

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

5
ответ дан 18 December 2019 в 09:10
поделиться

Для общедоступного API я пошел бы с массивом и разделенным значением размера. Это - то, как это обрабатывается в большинстве (если не все) c библиотека, которую я знаю. Как Вы обрабатываете его внутренне, это полностью ваше дело. Так с помощью структуры плюс некоторые функции/макросы помощника, которые, хитрые части для Вас являются хорошей идеей. Это всегда делает меня головной болью, чтобы заново обдумать, как вставить объект или удалить один, таким образом, это - хороший источник проблем. Решение, что однажды и универсальный, помогает Вам получающий ошибки с начала низко. Хорошая реализация для динамических и универсальных массивов является kvec.

2
ответ дан 18 December 2019 в 09:10
поделиться

Существует три пути.

  1. Для статического массива (не динамично выделенный и не передал как указатель) размер, знает во время компиляции, таким образом, Вы можете используемый sizeof оператор, как это: sizeof(array)/sizeof(array[0])
  2. Используйте разделитель (специальное значение для последнего элемента массива, который не может использоваться в качестве значения эквидистантной антенной решетки), как завершенные пустым указателем строки
  3. Используйте отдельное значение, или как участник структуры или как независимая переменная. Это действительно не имеет значения, потому что все стандартные функции, которые работают с массивами, берут отдельную переменную размера, однако присоединяясь к указателю массива, и размер в одну структуру увеличит удобочитаемость кода. Я предлагаю использовать, чтобы иметь более чистый интерфейс для Ваших собственных функций. Обратите внимание на то, что при передаче структуры значением вызванная функция сможет изменить массив, но не переменную размера, таким образом, передающий указатель структуры был бы более оптимальным вариантом.
3
ответ дан 18 December 2019 в 09:10
поделиться

Я сказал бы, что это - хорошая практика. На самом деле это достаточно хорошо, что в C++ они поместили его в стандартную библиотеку и назвали его vector. Каждый раз, когда Вы говорите о массивах на форуме C++, Вы будете наводнены ответами, которые говорят для использования vector вместо этого.

2
ответ дан 18 December 2019 в 09:10
поделиться

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

1
ответ дан 18 December 2019 в 09:10
поделиться

При использовании статических массивов, у Вас есть доступ к размеру массива с помощью sizeof оператор. При помещении его в структуру можно передать его для функционирования значением, ссылкой и указателем. Передающим аргументом ссылкой и указателем является то же на уровне ассемблера (я почти уверен в нем).

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

struct Foo {
  int *myarray;
  int size;
};

Таким образом, можно передать эту структуру значением, но что Вы действительно делаете передает указатель на интервал (указатель на массив) и интервал (размер массива).

По-моему, это не поможет Вам очень. Единственная вещь, которая находится в плюс, состоит в том, что Вы храните размер и массив в одном месте, и легко получить размер массива. При использовании большого количества динамических массивов, можно сделать это этот путь. Но если Вы будете использовать немного массивов, легче не должен будет использовать структуры.

1
ответ дан 18 December 2019 в 09:10
поделиться

Я не вижу ничто плохого с выполнением этого, но я думаю причина, что это обычно не делается, из-за издержек, понесенных такой структурой. Большая часть C является кодом без операционной системы по причинам производительности и как таковой, абстракций часто избегают.

1
ответ дан 18 December 2019 в 09:10
поделиться

Я никогда не видел сделанный тот путь, но я не выполнил в работе уровня ОС более чем десятилетие... :-) Походит на разумный подход на первый взгляд. Только беспокойство состояло бы в том, чтобы удостовериться, что размер так или иначе остается точным... Вычисление по мере необходимости не имеет того беспокойства.

0
ответ дан 18 December 2019 в 09:10
поделиться

рассмотрение Вас может вычислить длину массива (в байтах, то есть, не # элементов), и компилятор заменит sizeof () вызовы с фактическим значением (не функция, вызовы к нему заменяются компилятором со значением, которое это 'возвращает'), затем единственная причина, которую Вы хотели бы перенести, это в структуре для удобочитаемости.

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

0
ответ дан 18 December 2019 в 09:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: