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





Обратите внимание, что слово «статический» имеет другие значения в C. Кажется, вы спрашиваете о разнице между объявлением массива с постоянным размером, например int a[40], и объявлением массива с переменной длиной, например int a[n], где n - это известно во время выполнения, но обычно не во время компиляции.
В этом случае общим правилом является использование статического размера, когда вы можете:
В общем, использование статического размера более эффективно, потому что компилятор имеет больше информации и, следовательно, имеет больше возможностей для оптимизации. Когда компилятор компилирует операции с индексами адресов, он должен сгенерировать инструкции для вычисления адресов. Если он знает размер массива, у него могут быть возможности для выполнения некоторых вычислений во время компиляции (например, для int a[40]; a[13] = 2; компилятор может вычислить, что a[13] составляет 13 • 4 = 52 байта от начала a (при условии четырехбайтового int, конечно) или включить размер массива в качестве непосредственного операнда в инструкции (это означает, что он встроен в код и его не нужно искать в памяти или иным образом получать во время выполнения).
Если компилятор не знает размер массива, он должен сгенерировать полный код для вычисления адресов во время работы программы. В сегодняшних типичных средах программирования это обычно не требует больших затрат, но может иметь значение.
Кроме того, если массив имеет статический размер, он может быть внешним объектом (определенным вне какой-либо функции). Внешние объекты имеют статическую продолжительность хранения, что означает, что они существуют в течение всего времени жизни запущенной программы. (Здесь «статический» используется в смысле C, в отличие от значения фиксированного размера.) Когда компилятор знает размер массива, он может спланировать для него хранилище, которое предоставляется при запуске программы. Это позволяет массиву со статическим размером иметь статический срок хранения. Для массива с динамическим размером компиляторы обычно не могут спланировать для них необходимое хранилище, поэтому они не могут быть внешними объектами.
Спасибо за понимание, это было то, что я искал. Вы порекомендуете какую-либо конкретную документацию или книгу для более глубокого понимания этой темы? Я начинаю работать с C, исходя из java, и мне действительно интересно, как в целом работает память.
@ZezePinto: C - это больше язык «сделай сам» по сравнению с Java. По большому счету, проще делать вещи лучше - фиксированный размер лучше, чем переменный. C все еще можно выучить из книги Кернигана и Ричи в качестве отправной точки.
Да, это то, что я понял за последние недели. Еще раз спасибо за ваш вклад, очень признателен
Это зависит от варианта использования и реализации.