- •7. Указатели, массивы
- •7.1. Понятие адреса
- •7.2. Указатели
- •7.3. Арифметические операции и операции сравнения
- •7.4. Указатели и одномерные массивы
- •7.5. Возвращение функцией нескольких значений
- •7.6. Указатели на указатели
- •7.7. Массивы указателей и двумерные массивы
- •7.8. Массивы динамической памяти Одномерные динамические массивы
- •Двумерные динамические массивы
- •8. Строки
- •9. Структуры
- •9.1. Объявление структуры
- •9.2. Вложенные структуры
- •9.3. Статические массивы в структурах
- •9.4. Статический массив структур
- •9.5. Структуры и указатели
- •9.6. Динамический массив структур
- •9.7.Ссылка на структуру
- •9.8. Структуры и функции
7.5. Возвращение функцией нескольких значений
Функции в языке Си++ имеют ряд ограничений. Во-первых, если аргументы передаются в функцию по значению, то изменения, внесенные в аргументы во время выполнения функции, не влияют на переменные, значения которых передаются в функцию. Во-вторых, возвращать функция может только одно значение скалярного типа. Преодолеть эти два ограничения можно путем использования указателей или ссылок в качестве параметров функции.
Рассмотрим часто используемую задачу обмена значениями двух целочисленных переменных. Процесс обмена значениями оформим в виде функции Change.
#include <iostream.h>
void Change (int , int );
int main()
{
int x = 10, y = 5;
cout << "Значения переменных до перестановки (main)\n";
cout << "x = " << x << "y = " << y << endl;
Change (x,y);
cout << "Значения переменных после перестановки (main)\n";
cout << "x = " << x << "y = " << y << endl;
}
void Change (int x, int y)
{
cout << "Значения переменных до перестановки (Change )\n";
cout << "x = " << x << "y = " << y << endl;
int z = x;
x = y;
y = z;
cout << "Значения переменных после перестановки (Change )\n";
cout << "x = " << x << "y = " << y << endl;
}
В результате работы приведенной программы получим:
Значения переменных до перестановки (main)
x = 10, y = 5
Значения переменных до перестановки (Change )
x = 10, y = 5
Значения переменных после перестановки (Change )
x = 5, y = 10
Значения переменных после перестановки (main)
x = 10, y = 5
В функцию Change переменные x и y передаются по значению. Копии их значений присваиваются локальным переменным x, y функции Change . Очевидно, что изменение значений локальных переменных x и y в функции Change не влияет на значения переменных x и y функции main.
Если же в качестве аргументов в функцию Change передавать не значения переменных, а их адреса, то описание функции Change в этом случае запишется в виде:
void Change (int* x, int* y)
{
cout << "Значения переменных до перестановки (Change )\n";
cout << "x = " <<* x << "y = " << *y << endl;
int z = *x;
*x = *y;
*y = z;
cout << "Значения переменных после перестановки (Change )\n";
cout << "x = " << *x << "y = " << *y << endl;
}
Изменятся и прототип,
void Change (int* x, int* y);
и вызов функции:
Change (&x,&y);
В результате работы измененной программы на экран будет выведена следующая информация:
Значения переменных до перестановки (main)
x = 10, y = 5
Значения переменных до перестановки (Change )
x = 10, y = 5
Значения переменных после перестановки (Change )
x = 5, y = 10
Значения переменных после перестановки (main)
x = 5, y = 10
Если же в качестве аргументов в функцию Change передавать не значения переменных, а ссылки на них, то описание функции в этом случае запишется в виде:
void Change (int &x, int &y)
{
cout << "Значения переменных до перестановки (Change )\n";
cout << "x = " << x << "y = " << y << endl;
int z = x;
x = y;
y = z;
cout << "Значения переменных после перестановки (Change \n";
cout << "x = " << x << "y = " << y << endl;
}
В этом случае прототип функции будет иметь вид:
void Change (int & x, int & y);
а вызов функции:
Change ( x , y );
В результате работы измененной программы на экран будет выведена следующая информация:
Значения переменных до перестановки (main)
x = 10, y = 5
Значения переменных до перестановки (Change )
x = 10, y = 5
Значения переменных после перестановки (Change )
x = 5, y = 10
Значения переменных после перестановки (main)
x = 5, y = 10
Таким образом, передавая в функцию ссылки или указатели, можно менять в вызываемой функции значения переменной из вызывающей функции.
Пример 7.1. Расположить значения целочисленных переменных а , в , с в порядке возрастания, используя функцию перестановки значений двух переменных Change. Использовать указатели.
Текст программы:
#include <iostream.h>
#include <conio.h>
void Change ( int *, int *);
int main()
{
int a, b, c;
cout<<" a= "; cin>>a;
cout<<" b= "; cin>>b;
cout<<" c= "; cin>>c;
if ( a > b ) Change (& a, & b );
if ( b> c ) Change ( & b, & c );
if ( a > b ) Change (& a, &b );
cout<<" a = " << a << " b = "<< b <<" c = "<< c;
while (! kbhit());
return 0;
}
void Change ( int * x , int * y)
{
int temp = *x;
*x = *y;
*y = temp;
}
Пример 7.2. Дан одномерный целочисленный массив. Поменять местами минимальный и максимальный элементы массива. Основные этапы решения задачи оформить в виде функций.
#include <iostream.h>
#include <stdlib.h>
void InitArray (int *, int);
void DisplayArray (int *, int);
void MaxMin (int *, int);
int main()
{
const int DIM = 100;
int A[DIM];
int n;
cout << "Введите размер массива (n):";
cin >> n;
InitArray(A, n);
cout << "\n\tИсходный массив\n";
DisplayArray(A, n);
MaxMin (A, n);
cout << "\n\tПолученный массив\n";
DisplayArray(A, n);
system("pause");
return 0;
}
void InitArray(int * A, int n)
{
for(int * p = A; p < A + n; p++)
*p = random(20) - random(20) ;
}
void DisplayArray (int * A, int n)
{
for (int * p = A; p < A + n; p++)
cout << *p << ' ';
}
void MaxMin (int * A, int n)
{
int iMin=0, iMax=0;
for(int i = 0; i < n ; i++)
{
if (*(A +i) < *(A +iMin ) ) iMin=i;
if (*(A +i) > *(A +iMax ) ) iMax=i;
}
int temp = A[iMin];
A[iMin] = A[iMax];
A[iMax] = temp;
}
Пример 7.3. Дан одномерный вещественный массив. Отсортировать массив по неубыванию методом "пузырька". Массив и его размер ввести с клавиатуры. Основные этапы решения задачи оформить в виде функций.
Текст программы.
#include <iostream.h>
#include <stdlib.h>
void InitArray (double *, int);
void DisplayArray (double *, int);
void BubbleSort (double *, int);
int main()
{
const int n = 10;
double A[n];
InitArray(A,n);
cout << "\n\tИсходный массив\n";
DisplayArray(A,n);
BubbleSort(A,n);
cout << "\n\tОтсортированный массив\n";
DisplayArray(A,n);
system("pause");
return 0;
}
void InitArray(double* A, int n)
{
for(double* p = A; p < A + n; p++)
*p = rand() / 10.;
}
void DisplayArray (double * A, int n)
{
for(double* p = A; p < A + n; p++)
cout << *p << ' ';
}
void BubbleSort (double * A, int n)
{
int flag=1;
while(flag)
{ flag=0;
for(int j =0;j<n-1;j++)
if (*(A+j) > *(A+j+1) )
{
double x=*(A+j);
*(A+j)=*(A+j+1);
*(A+j+1)=x;
flag=1;
}
}
}