Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Передача имен функций в качестве параметров




Передача массивов в качестве параметров

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

#include <iostream.h>

int sum(const int* mas, const int n);

int const n = 10;

int main(){

int marks[n] = {3, 4, 5, 4, 4};

cout << "Сумма элементов массива: " << sum(marks, n);

return 0;

}

int sum(const int* mas, const int n){

// варианты: int sum(int mas[], int n)

// или int sum(int mas[n], int n)

// (величина n должна быть константой)

int s = 0;

for (int i = 0; i<n; i++) s += mas[i];

return s;

}

При передаче многомерных массивов все размерности, если они не известны на этапе компиляции, должны передаваться в качестве параметров. Внутри функции массив интерпретируется как одномерный, а его индекс пересчитывается в программе. В приведенном ниже примере с помощью функции подсчитывается сумма элементов двух двумерных массивов. Размерность массива b известна на этане компиляции, под массив а память выделяется динамически:

#include <stdio.h>

#include <std1ib.h>

int sum(const int *a, const int nstr, const int nstb);

int main(){

int b[2][2] = {{2, 2}. {4, 3}};

printf("Cyммa элементов b: %d\n", sum(&b[0][0], 2, 2));

// имя массива передавать в sum нельзя из-за несоответствия типов

int i, j, nstr, nstb, *a;

printf("Bведитe количество строк и столбцов: \n");

scanf("%d", &nstr, &nstb);

a = (int *)malloc(nstr * nstb * sizeof(int));

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

for (j - 0; j<nstb; j++)scanf("*d", &a[i * nstb + j]);

printf("Cyммa элементов a: %d\n", sum(a, nstr, nstb));

return 0;}

int sum(const int *a, const int nstr, const int nstb){

int i, j, s = 0;

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

for (j = 0; j<nstb; j++)s += a[i * nstb + j];

return s;

}

Для того чтобы работать с двумерным массивом естественным образом, можно применить альтернативный способ выделения памяти:

#include <iostream.h>

int sum(int **a, const int nstr, const int nstb);

int main(){

int nstr, nstb;

cin >> nstr >> nstb;

int **a, i, j;

// Формирование матрицы а:

a = new int* [nstr];

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

a[i] = new int [nstb];

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

for (j = 0; j<nstb; j++)cin >> a[i][j];

cout << sum(a, nstr, nstb);

return 0;

}

int sum(int **a, const int nstr, const int nstb){

int i, j, s = 0;

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

for (j - 0; j<nstb; j++)s += a[i][j];

return s;

}

В этом случае память выделяется в два этапа: сначала под столбец указателей на строки матрицы, а затем в цикле под каждую строку, как показано на рис. 1.10. Освобождение памяти должно выполняться в обратном порядке.

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

void f(int a){/*...*/} // определение функции

void (*pf)(int); // указатель на функцию

pf = &f; // указателю присваивается адрес функции

// (можно написать pf = f;)

pf(10); // функция f вызывается через указатель pf

// (можно написать (*pf)(10))

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

// Описание типа PF как указателя

// на функцию с одним параметром типа int:

typedef void (*PF)(int);

// Описание и инициализация массива указателей:

PF menu[] = {&new, Sopen, &save}:

menu[l](10); // Вызов функции open

Здесь new, open и save — имена функций, которые должны быть объявлены ранее.

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

#include <iostream.h>

typedef void (*PF)(int);

void f1(PF pf){ // функция f1 получает в качестве параметра указатель типа PF

pf(5); // вызов функции, переданной через указатель

}

void f(int i){cout << i;}

int main(){

f1(f);

return 0;

}

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




Поделиться с друзьями:


Дата добавления: 2015-05-26; Просмотров: 578; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.