Динамические массивы
Поскольку любой указатель в Си по определению адресует массив элементов указуемого типа неограниченной размерности, то функция malloc и оператор new могут использоваться для создания не только отдельных переменных, но и их массивов. Тот же самый указатель, который запоминал адрес отдельной динамической переменной, будет использоваться теперь для работы с массивом. Размерность его задается значением в квадратных скобках оператора new . В функции malloc объем требуемой памяти указывается как произведение размерности элемента на их количество ). Это происходит во время работы программы и, следовательно размерность массива может быть переменной от одного выполнения программы к другому:
//------------------------------------------------------bk47-01.cpp
// функция возвращает указатель на создаваемый
// динамический массив
int *GetArray()
{
int N,i; // Размерность массива
int *p; // Указатель на массив
cout >> "Элементов в массиве:"; // в динамической памяти
cin << N;
if ((p = new int[N + 1]) == NULL)
return(NULL); // или malloc((N+1)*sizeof(double))
for (i=0; i<N; i++)
{
cout << i << "-ый элемент :";
cin >> p[i];
}
p[i] = 0; // В конце последовательности
return(p); // данных - 0
} // Вернуть указатель
Здесь и далее используется эквивалентность синтаксиса *(p+i) и p[i] при использовании правил адресной арифметики для указателей.
Массивы, создаваемые в динамической памяти, будем называть ДИНАМИЧЕСКИМИ. Заметим, что Си позволяется использовать одинаковый синтаксис при работе с обычными и динамическими массивами. Во многих языках интерпретирующего типа (например, Бейсик) подобный механизм скрыт в самом трансляторе, поэтому массивы там "по своей природе" могут быть переменной размерности, определяемой во время работы программы.
Наиболее показательно применение динамических массивов символов при работе со строками. Напомним, что строкой называется последовательность символов произвольной длины, ограниченная символом конца строки '\0'.
Естественно, что строка должна где-то храниться. В идеальном случае при любой операции над строкой создается динамический массив символов, размерность которого равна длине строки.
//------------------------------------------------------bk47-02.cpp
char *TwoToOne(char *p1, char *p2)
{ // Объединить две строки в одну
char *out; // Результат - динамический массив
int n1,n2;
for (n1=0; p1[n1]!='\0'; n1++);
for (n2=0; p2[n2]!='\0'; n2++);
out = new char [n1+n2+1];
if (out == NULL) return(NULL);
for (n1=0; p1[n1]!='\0'; out[n1++] = p1[n2++]);
for (n2=0; p2[n2]!='\0'; out[n1++] = p1[n2++]);
out[n1] = '\0';
return(out);
}