Здравствуйте.Помогите решить задачу минимум 4 чисел.Условие такое:"Напишите функцию int min (int a, int b, int c, int d) (C/C++)"находящую наименьшее из четырех данных чисел."Заранее спасибо! |
Функции
Параметры функции
Механизм параметров является основным способом обмена информацией между вызываемой и вызывающей функциями. В операторе вызова функции записывают аргументы функции, а в заголовке описания функции перечисляют параметры. В С++ передача параметров осуществляется двумя способами: по значению и по ссылке. Это определяется видом объявления параметра в заголовке функции.
При передаче по значению объявление параметра похоже на объявление переменной:
тип имя
Такой параметр считается отдельной локальной переменной в теле функции. Ни в заголовке, ни в теле функции не должно быть других параметров или переменных с таким же именем. При вызове функции для параметров, передаваемых по значению, неявно выполняется операция присваивания:
параметр = выражение
Выражение вычисляется; если тип полученного значения не соответствует типу параметра, то выполняется (если это возможно) преобразование типов, и значение присваивается параметру. В частности, если в качестве аргумента задана константа или переменная, совпадающая по типу с параметром, то значение просто копируется в параметр. Копирование требует времени, поэтому способ передачи параметров по значению обычно применяется для данных встроенных типов, время копирования которых мало.
Никакие изменения значения параметра внутри функции не отражаются на значении переменной-аргумента, так как параметр является локальной переменной.
При передаче по ссылке объявление параметра представляет собой объявление ссылки без инициализации:
тип &имя
Параметр-ссылка локальна в функции: ни в заголовке, ни в ее теле не должно быть объявлено других параметров и переменных с таким же именем. Инициализация параметра-ссылки выполняется во время вызова функции. При этом способе передачи параметров в качестве аргумента может задаваться только L -значение.
В самом простом варианте на месте аргумента, соответствующего параметру-ссылке, задается имя переменной. Тип переменной-аргумента должен совпадать с типом параметра-ссылки. Ссылка становится альтернативным именем аргумента, поэтому любые действия, выполняемые со ссылкой в теле функции, мгновенно отражаются на состоянии аргумента.
Этот способ передачи параметра используется, если функция должна возвратить не один результат, а несколько. Например, передача параметров по ссылке может использоваться в функции обмена значений двух переменных:
void swap( int &a, int &b ) // определение функции обмена { int t = a; a = b; b = t; } // ... int x = 5, y = 6; swap( x, y ); // вызов функции обмена
Функция swap фактически работает с исходными переменными x и y. Изменение функцией нелокальных переменных называется побочным эффектом.
Использование параметров-ссылок вместо передачи по значению более эффективно, поскольку не требует времени и памяти для копирования аргументов в локальные переменные. Это имеет значение при передаче структур данных большого объема.
Пример передачи параметров:
#include <iostream> using namespace std; void f(int i, int* j, int& k); int main() { int i = 1, j = 2, k = 3; cout <<"i j k\n"; cout << i <<' ' << j <<' '<< k <<'\n'; f(i, &j, k); cout << i <<' ' << j <<' '<< k; } void f(int i, int* j, int& k) { i++; (*j)++; k++; }
Результат работы программы:
i j k 1 2 3 1 3 4
Первый параметр ( i ) передается по значению. Его изменение в функции не влияет на исходное значение. Второй параметр ( j ) передается по адресу с помощью указателя, при этом для передачи в функцию адреса фактического параметра используется операция взятия адреса, а для получения его значения в функции требуется операция разыменования. Третий параметр ( k ) передается по адресу с помощью ссылки.
Если требуется запретить изменение параметра, используется модификатор const:
int f(const char*); char* t(char* a, const int* b);
СОВЕТ
Рекомендуется указывать const перед всеми параметрами, изменение которых в функции не предусмотрено. Это облегчает отладку. Кроме того, на место параметра типа const& может передаваться константа.
Параметры, передаваемые в функцию, могут быть любого типа (например, вещественного, структурой, перечислением, объединением, указателем), кроме массива или функции, которые передаются с помощью указателей.
Передача массивов в качестве параметров
Массив всегда передается по адресу. При этом информация о количестве элементов массива теряется, и следует передавать его размерность через отдельный параметр:
#include <iostream> using namespace std; int sum(const int* mas, const int n); int const n = 10; void main() { int marks[n] = {3, 4, 5, 4, 4}; cout << "Сумма элементов массива: " << sum(marks, n); } 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 известна на этапе компиляции, под массив a память выделяется динамически:
#include <cstdio> using namespace std; int sum(const int *a, const int nstr, const int nstb); void main() { int b[2][2] = {{2, 2}, {4, 3}}; /* имя массива передавать нельзя из-за несоответствия типов */ printf("b %d\n", sum(&b[0][0], 2, 2)); int i, j, nstr, nstb, *a; printf("Введите количество строк и столбцов: \n"); scanf("%d%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("a %d\n", sum(a, nstr, nstb)); } 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> using namespace std; int sum(const int **a, const int nstr, const int nstb); void main() { int nstr, nstb; cin >> nstr >> nstb; int **a; a = new int* [nstr]; for (int i = 0; i<nstr; i++) a[i] = new int [nstb]; /* * формирование матрицы a */ cout << sum(a, nstr, nstb); } 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][j]; return s; }
В этом случае память выделяется в два этапа: сначала под столбец указателей на строки матрицы, а затем в цикле под каждую строку. Освобождение памяти выполняется в обратном порядке.
Передача имен функций в качестве параметров
Функцию можно вызвать через указатель на нее. Для этого объявляется указатель соответствующего типа и ему с помощью операции взятия адреса присваивается адрес функции:
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, &open, &save} menu[1](10); //вызов функции open
Указатели на функции передаются в подпрограмму таким же образом, как и параметры других типов:
void fun(PF pf) /* функция fun получает в качестве*/ /* параметра указатель типа PF */ {* pf(10); *} //вызов функции, переданной через указатель
Тип указателя и тип функции, которая вызывается посредством него, должны совпадать в точности.
Параметры со значениями по умолчанию
Чтобы упростить вызов функции, в ее заголовке можно указать значения параметров по умолчанию. Эти параметры должны быть последними в списке и могут опускаться при вызове функции. В качестве значений параметров по умолчанию могут использоваться константы, глобальные переменные и выражения:
int f(int a, int b = 0); void f1(int, int = 100, char* = 0); void err(int errValue = errno); // errno - глобальная переменная f(100); f(a, 1); // варианты вызова функции f // варианты вызова функции f1 f1(a); f1(a, 10); f1(a, 10, "Vasia"); f1(a,,"Vasia") // неверно!