Когда использовать статические массивы против динамических массивов C

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

Это зависит от варианта использования и реализации.

MayurK 07.01.2019 12:10

Есть два больших вопроса: 1) Вам нужно изменять размер массива во время выполнения? И 2) Где вы хотите массив (в куче или в «автоматическом» (стековом) хранилище)?

Some programmer dude 07.01.2019 12:15

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

Yakov Dan 07.01.2019 12:31

@Someprogrammerdude: разница между «статическим» и «динамическим» в этом использовании заключается либо в объявлении int a[3] по сравнению с int a[n] в блоке (в этом случае оба находятся в стеке), либо в объявлении измерений как части чего-то еще, например, динамического распределения, например int (*p)[2][3] = malloc(…); по сравнению с int (*p)[a][b] = malloc(…);, и в этом случае выделяются оба, а разница только в генерации кода (жестко заданные вычисления адресов в сравнении с умножением во время выполнения на размер. Изменение размера со статического (постоянного) на динамический (переменная длина) обычно не меняет место хранения.

Eric Postpischil 07.01.2019 14:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
568
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обратите внимание, что слово «статический» имеет другие значения в C. Кажется, вы спрашиваете о разнице между объявлением массива с постоянным размером, например int a[40], и объявлением массива с переменной длиной, например int a[n], где n - это известно во время выполнения, но обычно не во время компиляции.

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

  • когда точный размер известен во время компиляции, или
  • когда известна верхняя граница, и использование верхней границы не приведет к потере слишком много места.

В общем, использование статического размера более эффективно, потому что компилятор имеет больше информации и, следовательно, имеет больше возможностей для оптимизации. Когда компилятор компилирует операции с индексами адресов, он должен сгенерировать инструкции для вычисления адресов. Если он знает размер массива, у него могут быть возможности для выполнения некоторых вычислений во время компиляции (например, для int a[40]; a[13] = 2; компилятор может вычислить, что a[13] составляет 13 • 4 = 52 байта от начала a (при условии четырехбайтового int, конечно) или включить размер массива в качестве непосредственного операнда в инструкции (это означает, что он встроен в код и его не нужно искать в памяти или иным образом получать во время выполнения).

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

Кроме того, если массив имеет статический размер, он может быть внешним объектом (определенным вне какой-либо функции). Внешние объекты имеют статическую продолжительность хранения, что означает, что они существуют в течение всего времени жизни запущенной программы. (Здесь «статический» используется в смысле C, в отличие от значения фиксированного размера.) Когда компилятор знает размер массива, он может спланировать для него хранилище, которое предоставляется при запуске программы. Это позволяет массиву со статическим размером иметь статический срок хранения. Для массива с динамическим размером компиляторы обычно не могут спланировать для них необходимое хранилище, поэтому они не могут быть внешними объектами.

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

Zeze Pinto 12.01.2019 04:29

@ZezePinto: C - это больше язык «сделай сам» по сравнению с Java. По большому счету, проще делать вещи лучше - фиксированный размер лучше, чем переменный. C все еще можно выучить из книги Кернигана и Ричи в качестве отправной точки.

Eric Postpischil 12.01.2019 04:40

Да, это то, что я понял за последние недели. Еще раз спасибо за ваш вклад, очень признателен

Zeze Pinto 12.01.2019 05:06

Другие вопросы по теме