| Здравствуйте.Помогите решить задачу минимум 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") // неверно!