Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЗФ_ОАиП / Лекции ГГУ Скорины - Программирование.doc
Скачиваний:
179
Добавлен:
21.03.2016
Размер:
2.27 Mб
Скачать

23. Передача в функции массивОв

23.1. Передача одномерных массивов в функции

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

В программе ниже в func() передается указатель на массив mas:

void main(void) {

int mas[10];

...

func(mas);

...

}

Если в функцию передается указатель на одномерный массив, то в самой функции его можно объявить одним из трех вариантов: как указатель, как массив определенного размера и как массив неопределенного размера.

void func(int *x) { // указатель

...

}

void func(int x[10]) { // массив определенного размера

...

}

void func(int x[]) { // массив неопределенного размера

...

}

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

В последнем примере форма объявления массива сообщает компилятору, что в функцию будет передан массив неопределенной длины. Длина массива не имеет для функции никакого значения, потому что в языке С проверка границ массива не выполняется. Эту функцию можно объявить даже так:

void func(int x[50]) {

...

}

Программа все равно будет работать правильно, потому что компилятор не создает массив из 50 элементов, а только подготавливает функцию к приему указателя.

Обратить внимание! Поскольку массив передается как указатель на его начало, то размер массива в объявлении аргумента можно не указывать. Это позволяет одной функцией обрабатывать массивы разной длины.

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

void f1(int m) {

m++;

}

void f2(int m[]) {

m[0]++;

}

void main() {

int mas[2] = {1, 1};

f1(mas[0]);

printf("%d\n", mas[0]); // mas[0] осталось равно 1

f2(mas);

printf("%d\n", mas[0]); // mas[0] стало равно 2

}

В f1() в качестве аргумента передается копия элемента mas[0]. Изменение этой копии не приводит к изменению самого массива, т.к. аргумент m является локальной переменной в функции f1(). В функции f2() локальным является адрес массива mas, но не сам массив. Поэтому m[0]++ изменяет сам массив mas (в то же время, например, m++ внутри f2() изменило бы лишь локальный указатель m, но не адрес массива mas).

Для обработки массива, кроме адреса начала массива функция должна знать и количество элементов в массиве. Поэтому, если массив, для обработки которого используется функция, может иметь разный размер, в функцию дополнительно следует передавать и реальную размерность массива (точное число элементов в массиве). Тогда она сможет менять указатель в безопасных пределах и получит полный доступ к любому элементу массива.

Задача. Разработать функцию для нахождения максимального элемента в одномерном массиве целых чисел.

int f_max(int *m, int n) {

int max, i;

max = m[0];

for (i=1; i<n; i++)

if (m[i] > max) max = m[i];

return max;

}

void main() {

int mas[100], n, i, n2, k, *p, max2;

printf(“Введите размерность массива\n”);

scanf(“%d”, &n);

printf(“Введите массив\n”);

for (i=0; i<n; i++)

scanf(“%d”, &mas[i]);

printf(“Максимальный элемент = %d\n”, f_max(mas,n));

// находим максимум во второй половине массива

k = n2 = n / 2; // k – смещение второй половины

if (n&1) n2++; // n2 – количество элементов во второй половине

// при нечетном n средний элемент относим ко второй половине

printf(“Максимальный элемент второй половины = %d\n”,

f_max(mas+k,n2));

// можно и так вызвать функцию: p = mas+k; max2 = f_max(p,n2);

}

Задача. Разработать функцию для нахождения номера минимального элемента и суммы элементов одномерного массива целых чисел.

int func(int *m, int n, int *sum) {

int i, min, n_min;

min = *m; n_min = 0;

*sum = m[0];

for (i=1; i<n; i++) {

if (m[i] < min) {

min = *(m+i); n_min = i; // находим номер минимального

}

*sum += m[i]; // находим сумму элементов

}

return n_min; // возвращаем номер минимального элемента

}

void main() {

int mas[100], n, i, sum;

printf("Введите размерность массива\n");

scanf("%d", &n);

printf("Введите массив\n");

for (i=0; i<n; i++)

scanf("%d", &mas[i]);

printf("Номер минимального = %d\n", func(mas, n, &sum));

printf("Сумма = %d\n", sum);

}

Задача. Разработать функцию для замены всех нулевых элементов массива заданным числом.

void f(int *m, int n, int k) {

int i;

for (i=0; i<n; i++)

if (m[i] == 0)

*(m+i) = 100; // m[i] = 100;

}

void main() {

int mas[100], n, i;

printf("Введите размерность массива\n");

scanf("%d", &n);

printf("Введите массив\n");

for (i=0; i<n; i++)

scanf("%d", &mas[i]);

f(mas, n, 100); // заменить все 0 на 100

printf("Массив после замены\n");

for (i=0; i<n; i++)

printf("%d ", mas[i]);

printf("\n");

}