Указатели и одномерные массивы

Рассматриваемые выше вопросы усложняются ещё и тем, что для массивов они решаются по-другому. Пусть мы объявили статический массив: const m=10; int a[m]; Этим самым мы не только выделили память для размещения m целых чисел. Без какого-либо дополнительного объявления, без использования символа “*” мы объявили и переменную-указатель с именем a. В этой переменной находится адрес начала массива, т. е. номер первого байта элемента a[0]. Этот адрес можно в программе обозначить ещё и как &a[0].

Идентификатор массива определяется не просто как указатель, а как константный указатель на первый элемент массива. Это означает, что нельзя изменить адрес начала массива, то есть нельзя, например, переменной a присвоить значение другого адреса. Если int *q, то запись a=q; недопустима, а обратное присваивание q=a; или q=&a[0]; разрешено. После этого элементы массива можно обозначать не только a[i], но и q[i], где i =0, 1, 2, …, m-1. Если q=&a[5], то q[0] — это a[5], q[1] — это a[6], и т. д., q[4] — a[9].

При использовании одномерного массива в качестве параметра функции заголовок функции можно записать по-разному. Например, функцию сортировки можно объявить двумя способами:

a) void MySort(int x[], int size); или

b) void MySort(int *x, int size);

В любом случае в качестве параметра передаётся адрес начала массива. Более того, в прототипе можем записать int x[], а в заголовке при определении этой же функции — int * x или наоборот. В тексте функции для доступа к элементу массива можно использовать обычную индексированную переменную x[i]. Но вызов такой функции выполняется одинаково и не зависит от вариантов (a) или b)). В вызывающей функции объявляем статический массив обычным образом, например, const m=10; int a[m]; При вызове функции в качестве фактического параметра надо записать адрес начала массива, если обрабатываем его с самого начала. Поэтому в скобках в таком случае записываем только имя массива a или адрес его первого элемента &a[0], что одно и тоже. Будет ошибка, если при вызове функции в качестве фактического параметра запишем, например, a[i] (так можно писать внутри функции), или a[m] (так объявляем массив), или a[] (так можно определить формальный, а не фактический параметр). Таким образом, функцию можно вызвать одним из следующих способов:

a) MySort (a, m); или MySort (&a[0], m); для сортировки всех m элементов массива;

b) MySort (a, m/2); или MySort (&a[0], m/2); для сортировки m/2 первых элементов массива;

c) Пусть надо рассортировать массив не с самого начала, а, например, с его середины и до конца. Тогда в качестве фактического параметра при вызове такой функции указываем адрес элемента a[m/2], а количество обрабатываемых элементов уменьшаем в два раза: MySort (&a[m/2], m%2? m/2+1: m/2).

Заметим, что в вариантах b) и c) требуется уточнение и пояснение в случае, если m — нечётное. Если, например, m=15, то в варианте b) рассортируем первые 7 элементов массива, то есть меньше половины. В варианте c), начав с a[7], мы должны рассортировать 8= n/2+1 элементов, то есть больше половины. При n чётном (n%2=0, что соответствует false) рассортируем n/2 элементов.

В [1] смотри объяснение, как передаётся одномерный массив в качестве параметра функции.


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



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