В чем разница между этими двумя определениями массива, а какая из них правильнее и почему?
#include <stdio.h>
#define SIZE 20
int main() {
// definition method 1:
int a[SIZE];
// end definition method 1.
// defintion method 2:
int n;
scanf("%d", &n);
int b[n];
// end definition method 2.
return 0;
}
Я знаю, если мы читаем размер, переменную n
, из stdin
, правильнее определить наш (блок памяти, который мы будем использовать) в качестве указателя и использовать stdlib.h
и array = malloc(n * sizeof(int))
, а не decalring его как int array[n]
, но опять же почему?
Q1: Первое определение - это объявление статического массива. Совершенно верно. Это когда вы знаете размер, поэтому никакого сравнения с VLA или malloc().
Q2: что лучше при принятии размера в качестве входа от пользователя: VLA или malloc.
VLA: они ограничены границами окружения размером автоматического распределения. А автоматические переменные обычно выделяются в стеке, что относительно
small.The ограничение является специфичным для платформы. Кроме того, это только в c99 и выше. Некоторая простота использования при объявлении многомерных массивов получена VLA.
Malloc: выделяет из кучи. Таким образом, для больших размеров определенно лучше. Для многомерных указателей массивов задействованы так много сложной реализации.
Проверьте http://bytes.com/topic/c/answers/578354-vla-feature-c99-vs-malloc
Это не "более правильно" или "менее корректно". Это либо есть исключающий не является правильным. В частности, это работает на C, но не в C++.
malloc()
, поэтому я бы предпочел подход VLA. Если вам нужно вернуть его из функции, то вы не можете использовать локальный массив, потому что он уничтожается при возврате, поэтому вам нужен malloc()
.
Вы объявляете динамические массивы. Лучший способ объявить динамические массивы как
int *arr; // int * type is just for simplicity
arr = malloc(n*sizeof(int*));
это связано с тем, что массивы переменной длины разрешены только на C99, и вы не можете использовать это в c89/90.
malloc()
. std::vector
или самое большее new[]
. Кроме того, я не вижу причин в данном конкретном случае для использования malloc()
- переменная используется только локально, внутри функции.
malloc
в C ++. Но VLA разрешены только в C99, поэтому я считаю, что malloc
лучше.
Если вы знаете SIZE
во время компиляции:
int ar[SIZE];
Если вы этого не сделаете:
std::vector<int> ar;
Я не хочу видеть malloc
любом месте вашего кода C++. Тем не менее, вы в корне верны, и для C это то, что вы сделали бы:
int* ptr = malloc(sizeof(int) * SIZE);
/* ... */
free(ptr);
Массивы переменной длины - это расширение GCC, которое позволяет:
int ar[n];
но у меня были проблемы, когда VLA были отключены, но GCC не смог обнаружить, что я пытался их использовать. Наступает Хаос. Просто избегайте этого.
malloc()
в C (> = 99), если нет необходимости использовать массив вне функции. Кроме того, «Массивы переменной длины являются расширением GCC» верно только для C ++ (и это не ясно из вашего ответа).
В (pre-C99) C и C++ все типы имеют статический размер. Это означает, что массивы должны быть объявлены с размером, который является постоянным и известен компилятору.
Теперь многие компиляторы C++ предлагают массивы с динамическим размером как нестандартное расширение, и C99 явно разрешает их. Поэтому int b[n]
, скорее всего, будет работать, если вы попробуете его. Но в некоторых случаях это не будет, и компилятор не ошибается в этих случаях.
Оба правильные. используемая вами декларация зависит от вашего кода.
Первая декларация, т.е. int a[size];
создает массив с фиксированным размером 20 элементов. Это полезно, когда вы знаете точный размер массива, который будет использоваться в коде. например, вы генерируете таблицу числа n
до 20-го числа.
Второе объявление позволяет вам создать массив требуемого размера. Это полезно, когда вам понадобится массив разных размеров, каждый раз, когда код выполняется, например, вы хотите сгенерировать серию фибоначчи до n
. В этом случае размер массива должен быть n
для каждого значения n
. Итак, скажем, что у вас есть n = 5
, в этом случае int a [20]
потеряет память, потому что для серии фибоначчи будут использоваться только первые пять слотов, а остальные будут пустыми. Аналогично, если n = 25
то ваш массив int a[20]
станет слишком маленьким.
Я думаю, что metod1 может быть немного быстрее, но оба они верны в C.
В C++ сначала будет работать, но если вы хотите использовать вторую, вы должны использовать:
int size = 5;
int * array = new int[size];
и не забудьте удалить его:
delete [] array;
Я думаю, это дает вам больше возможностей для использования во время кодирования.
Если вы используете malloc
или другое динамическое распределение, чтобы получить указатель. Вы будете использовать как p + n..., но если вы используете массив, вы можете использовать array[n]
. Кроме того, указав указатель, вам нужно его освободить; но массив не нужно free
.
И в C++ мы могли бы определить пользовательский класс для выполнения таких вещей, а в STL существует std :: vector, который делает массив-вещи и многое другое.
Разница, если вы определяете массив с помощью malloc, заключается в том, что вы можете передавать размер массива динамически, т.е. Во время выполнения. Вы вводите значение, которое ваша программа имеет во время выполнения. Еще одно отличие состоит в том, что массивы, созданные с использованием malloc, выделяются в кучу. Таким образом, они сохраняются в функциональных вызовах, в отличие от статических массивов.
example-
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
int *a;
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
return 0;
}
malloc()
.