Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Использование ссылки вместо передачи по значению более эффективно, поскольку

не требует копирования параметров, что имеет значение при передаче структур данных большого объема.

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

Ссылочный параметр в прототипе функции определяется знаком &.

Написать функцию возведения числа в квадрат:

int VKv(int & a)

{

return a*a;

}

или

void VKv(int & a, & aa)

{

aa=a*a; a=1;

}

void main(void)

{

int a =2;

int b;

b = VKv(a); //b=4

VKv(a, c); //c=4

VKv(a, c); //c=4

}

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

void VKv(const int & a, int & aa) //int aa - ошибка

{

aa=a*a;

//a=2;

}

Если требуется запретить изменение параметра внутри функции, используется модификатор const. Рекомендуется использовать модификатор const перед всеми параметрами, изменение которых в функции не предусмотрено.

Например, функция для вычисления площади круга:

const double M_PI = 3.1415926;

float SKr(const float R)

{

return R*R*M_PI;

}

Входные данные — R. Выходные данные — то, что после return.

M_PI — неизменяемая переменная, типа double.

В резульате s=SKr(2) s=8.2548E08

НЕ нашли? Не то? Что вы ищете?

#include <iostream. h>

#include <iomanip. h>

int VKub(int * a)

{

return *a * *a * *a;

}

void VKub(const int * a, int * aa)//нельзя изменить значение

//переменной a

{

*aa = *a * *a * *a;

*a=2; //ошибка компиляции

}

void main(void)

{

int a =2;

int b, c;

b = VKub(&a); //b=8

VKub(&a, &c); //c=8

}

void VKub(const int * a, int * aa) //нельзя изменить значение переменной a

*a=0 - ошибка

a=....; //можно

void VKub(int * const a, int * aa) //нельзя изменить значение указателя a

a=222;-ошибка

*a=2; //можно

void VKub(const int * const a, int * aa)

Пример. Написать функцию для обмена элементов массива m с номерами i и j.

void Swap3(int * mi, int * mj) //можно по указателям на элементы

{

int tmp=*mi;

*mi=*mj;

*mj=tmp;

}

void Swap4(int m[], int i, int j) //можно по указателю на массив

{ //с нотацией массива

int tmp=m[i];

m[i]=m[j];

m[j]=tmp;

}

void Swap5(int *m, int i, int j) //можно по указателю на массив

{ //с нотацией указателя

int tmp=*(m+i);

*(m+i)=*(m+j);

*(m+j)=tmp;

}

Вызов этих функций осуществляется следующим образом

void main (void)

{

int m[6]={1,2,3,4,5,6};

Swap3(&m[2], &m[4]);

Swap3(m+2, m+4);

Swap4(m, 2, 4);

Swap5(m, 2, 4);

}

Перегрузка функций

------------------

В С++ имеется возможность определять несколько функций с одинаковым именем, если эти функции имеют разные типы параметров или разное их количество. Это удобно если функции имеют сходные задачи, но разные типы данных.

Например, в программе можно написать 2 функции для нахождения минимального среди 2 или трех чисел

#include <iostream. h>

double min(double a, double b)

{

if (a<b) return a;

else return b;

}

double min(double a, double b, double c)

{

if (a<=b) && (a<=c) return a;

if (b<=a) && (b<=c) return b;

if (c<=a) && (c<=b) return c;

}

void main(void)

{

int i=5, j=6, k=2;

cout << min(i, j); //5

cout << min(i, j, k); //2

cout << min(1, 6, k); //1

}

или

int kv(int k)

{

return k*k;

}

double kv(double y)

{

return y*y;

}

Ссылки

--------

Ссылка представляет собой синоним имени, указанного при

инициализации ссылки.

int kol;

int & pal = kol;

pal — ссылка, она всегда равно содержимому kol, поскольку pal и kol ссылаются на одну область памяти. В ходе выполнения программы ссылка pal будет всегда ссылаться на переменную kol (то есть ссылке не может быть присвоена другая переменная).

Если присвоить pal = 4;, то kol тоже будет равна 4 и наоборот.

Ссылки применяются чаще всего только в качестве параметров функций и типов, возвращаемых функциями значений.

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

Swap2 после компиляции — точный аналог Swap3.

void Swap2(int & mi, int & mj) //можно по ссылке на элементы

{

int tmp=mi;

mi=mj;

mj=tmp;

}

void Swap1(int mi, int mj) //нельзя - вызов по значению

{

int tmp=mi;

mi=mj;

mj=tmp;

}

void main ()

{

int m[10]={1, 2, 3}, i=2, j=4;

Swap1(m[i], m[j]); //нельзя

Swap2(m[i], m[j]); //можно

Swap3(&m[i], &m[j]); //можно

Swap4(m, i, j);

Swap5(m, i, j);

}

К третьему элементу массива

int m[5]

можно обращаться m[2] — нотация массива;

*(m+2) — нотация указателя.

*m ===== m[0] ==== *(m+0)

*(m+1) ==== m[1]

m[0]=1; m[1] = 2; m[3]=4;

m == &m[0] === 50000 - адрес ячейки памяти, где находится m[0].

&m[1] === m+1 ==== 50002.

&m[2] === m+2 ==== 50004.

То есть

int m[5];

cout << m; // 50000

++m;

cout << m; // 50002

++m;

cout << m; // 50004

и т. д.

double md[5];

cout << md; // 60000

++md;

cout << md; // 60008

++md;

cout << md; // 60016

Шаблоны функций

----------------

Шаблоны функций позволяют написать одну функцию таким

образом, чтобы она могла работать с переменными разных типов, например:

вместо функций

int sum(int & a, int & b)

{

return a+b;

}

double sum(double & a, double & b)

{

return a+b;

}

string sum(string & a, string & b)

{

return a+b;

}

complex sum(complex & a, complex & b)

{

return a+b;

}

можно написать всего одну функцию-шаблон с требующим уточнения типом

(Реализация шаблона-функции помещается в *.h файле.)

template <class T>

T sum(T & a, T & b)

{

return a + b;

}

Пример вызова шаблона-функции:

void main(void)

{

string a, b;

int i, j;

double d1, d2, d3;

complex c1, c2, c3;

cout << sum<string>(a, b) << endl;

//при необходимости или по желанию следует уточнять тип

cout << sum(i, j) << endl;

c3 = sum(c1, c2);

d3 = sum(d1, d2);

}

Например функция, меняющая значения двух переменных любых типов:

template <class T>

void swap(T & a, T & b)

{

T c;

c = a;

a = b;

b = c;

}

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

----------------------------

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

Чтобы передать массив в качестве аргумента в функцию достаточно указать имя массива.

Пример. Функция MassOut должна вывести на экран элементы массива:

#include <iostream. h>

#include <iomanip. h>

#include <stdlib. h>

void MassOut(double m[], int n)

{

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

cout << setprecision(3) << setiosflags(ios::fixed | ios::showpoint)

<< m[i] << " ";

}

void main(void)

{

double m[7]={2.0, 3.444, 5.43, 3.21};

MassOut(m, 7);

}

На экран будет выведено: 2.000 3.444 5.430 3.210 0.000 0.000 0.000

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

Написать функцию, увеличивающую все элементы массива в 2 раза:

void Mass2(double m[], int n)

{

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

m[i] *=2;

}

В данном примере переданный в функцию массив должен модифицироваться. Если модифицировать массив в функции не нужно, то лучше обезопаситься от ошибки и передать массив в функцию как const.

void MassOut(const double m[], const int n)

{

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

cout << setprecision(3) << setiosflags(ios::fixed | ios::showpoint)

<< m[i] << " ";

m[1] *=2; //ошибка при компиляции

}

Пример. Имеется массив с шестью элементами m[6]. Имея функцию

int SumMass(int m[], int n)

{

int s=0;

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

s += m[i];

}

найти сумму s1 = m[0] + m[1] + m[2] + m[3] и

s2 = m[3] + m[4] + m[5].

void main(void)

{

int m[6]= { 2, 2, 3, 4, 5, 6 };

SumMass(m, 4); //сумма s1

SumMass(&m[3], 3); //сумма s2 SumMass(m+3, 3);

}

Передача двумерного массива в функцию

Пример. Распечатать двумерный статический массив с помощью функции.

#include <iostream. h>

#include <iomanip. h>

void MassOut(int m[][3], int r)

{

int i, j;

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

{

cout << endl;

for(j=0; j<3; j++)

cout << setw(7) << m[i][j]; //Ни в коем случае не пишите [i, j]

}

cout << endl;

}

void main(void)

{

int mas1[2][3] = {{1}};

int mas2[3][3] = {{1, 2, 3},{4}};

MassOut(mas1, 2);

MassOut(mas2, 3);

}

1 0 0

0 0 0

1 2 3

4 0 0

0 0 0

Аргумент функции, соответствующий двумерному массиву, имеет вид int m[][3], то есть необходимо передавать массивы с 3 столбцами. Указывать количество столбцов при объявлении функции необходимо для правильного поиска элементов двумерном массиве.

Элементы массива расположены в памяти последовательно

m[0][0] m[0][1] m[0][2] m[1][0] m[1][1] m[1][2] m[2][0] m[2][1] m[2][2]

Таким образом, чтобы обратиться к элементу m[1][2] необходимо взять элемент шестой = 1*3+2. В общем случае элемент m[i][j] расположен в позиции i*<кол_во_столбцов>+j. То есть в формулу входит величина <кол_во_столбцов>, которая и сообщается функции в виде int m[][3].

Функция MassOut может выводить массив только с тремя столбцами, но любым количеством строк. То есть функция не универсальная.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18