Указатели в качестве параметров функций

Многомерные массивы

Массивы

Массивы являются набором однотипных данных, последовательно размещённых в памяти.

Одномерный массив можно объявить так:

тип_данного имя_массива[размер];

Например: int x[5];

Обращение к элементам массива происходит через операцию []. Минимальный индекс всегда ноль. Максимальный индекс – на единицу меньше размера массива.

ВНИМАНИЕ Автоматический контроль границ отсутствует.

Возможно создать массив требуемого размера во время выполнения программы. Например, в библиотеке mem.h определены функции malloc для выделения памяти и free для её освобождения.

Пример:

int *x;

x = (int*)malloc(10*sizeof(int)); // выделение памяти для 10 элементов типа «int»

… // некоторый код по работе с массивом

free(x); // освобождение памяти

Более подробно данные функции будут рассмотрены ниже.

В «С++» для выделения памяти под массив элементов определены операции new[] и delete[].

Пример (аналогичный по функциональности предыдущему):

int *x;

x = new int[10];

delete []x;

Возможны по крайней мере три варианта реализации многомерных массивов.

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

Пример:

int x[4][4][3];

x[0][0][0] = 5;

Массивы могут инициализироваться значениями в фигурных скобках, при этом допустимо не указывать последнюю (самую левую) размерность. Если заданная размерность меньше инициализирующих аргументов, часть элементов останется неопределенна. Обратная ситуация вызовет ошибку.

Примеры:

int x[3][2]={{1,2},{3,4},{5,6}}; //заданы и размеры массива, и инициализирующие значения

long y[] = {1,2,3,4}; // размер массива определяется фактическому по количеству // значений (4)

char t[][4] = {{1,2,3,4},{5,6}}; // последняя размерность определяется по числу значений (2) и // элементы t[1][2] и t[1][3] не определены

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

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

Пример:

int **x;

x = new int*[3];

for(int i=0;i<3;i++) x[i] = new int[i];

x[0][0] = 0; x[1][0] = 1; x[1][1] = 2; x[2][0] = 3; x[2][1]=4; x[2][2] = 5;

Получаем массив вида

В этом случае в памяти отдельно хранится массив указателей на строки и отдельно сами строки.

3. Хранение многомерного массива в одномерном.

Например, переход от двух индексов (i,j) можно осуществить по формуле i*m+j, где m – максимальная размерность по j (количество столбцов).

В списке формальных параметров функций указатели могут указываться как с использованием символа *, так и с использованием квадратных скобок. Данные определения равнозначны.

void f(char *x, double []y) {…}

Для передачи многомерных массивов удобно использовать определение типа (служебное слово typedef).

Пример.

typedef int myarray[5][5];

void f(myarray t)

{

}

void main()

{

myarray x;

f(x);

}

Для передачи в функцию константного указателя используется служебное слово const. Данные, на которые указывают такие указатели не могут быть переопределены, а также нельзя освободить память, занимаемую ими.

void f2(const char *t)

{

t[0] = ‘x’; /недопустимо

free(t); //недопустимо, но можно выполнить free((char *)t)

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: