Лекции 2021 / OIT_lek_sem_06_10_2021
.docx5.3. Передача значений через глобальные переменные
Глобальные переменные описываются до объявления любых функций в программе. Поэтому они доступны в любом месте кода программы. Для иллюстрации вернёмся к условию задачи примера 12 (составить программу нахождения наибольшего значения из трёх величин ‒ max(a,b,c)). Изменим программу (пример 16) с целью передачи результата с помощью глобальной переменной z.
Пример 16.
#include "stdafx.h"
#include <iostream>
using namespace std;
//описание глобальной переменной z
int z;
// описание вспомогательной функции MAX
void MAX(int x, int y) {
if (x > y) z = x;
else z = y;
}// конец описания функции MAX
// основная функция main
void main() {
int a, b, c;
cout << "input a,b,c:";
cin >> a >> b >> c;
MAX(a, b);
MAX(z, c);
cout << "\nmax(a,b,c)=" << z << endl;
}// конец функции main
Областью действия переменной z являются функции MAX и main. После первого обращения к вспомогательной функции (MAX(a,b);) результат заносится в глобальную переменную z (z=x; или z=y;). Это значение далее используется во втором обращении (MAX(z, c);). Результат снова возвращает переменная z, значение которой затем выводится.
Пример 17 (использование глобальной переменной).
Составить программу для вычисления выражения: . Возведение в степень оформить в виде вспомогательной функции; – определить как минимальный элемент массива (а0, а1, ... , а7).
#include "stdafx.h"
#include <iostream>
using namespace std;
//описание глобальной переменной P
double P;
// описание вспомогательной функции PS
void PS(double x, int n) {
if (n == 0) P = 1.0; else P = x;
for (int i = 1;i < n;i++)
P *= x; // P=P*x;
}// конец описания функции PS
// основная функция main
void main() {
int a[8], i, amin; double x, z;
cout << "\nx="; cin >> x;
for (i = 0;i < 8;i++){
cout << "a[" << i << "]="; cin >> a[i];
}
cout << "\n";
amin = a[0];
for (i = 1;i < 8;i++)
if (a[i] < amin) amin = a[i];
PS(x, 5);
z = P*amin;
cout << "z=" << z;
}// конец функции main
Глобальная переменная P возвращает в главную функцию результат возведения в степень – x5.
6. Указатели
6.1. Общие положения
Значение переменной записывается в ячейку памяти, на которую может ссылаться другая переменная. Указатель – это целочисленная переменная, содержащая адрес (номер ячейки памяти) иной переменной. Если переменная занимает не одну ячейку (например, массив), её адресом считается адрес первой ячейки.
Указатель в программе должен быть объявлен:
double d,*dP;
int i, *iP;
char c,*cP;
Описаны переменные вещественного, целого, символьного типов d, i, c и указатели на переменные этих же типов dP, iP, cP. Знак * показывает, что объявляется указатель, и относится только к следующему за ним идентификатору.
Указатель не может быть инициализирован непосредственно, потому что представляет собой адрес, а распределением адресов занимается сам компьютер. Возможна операция адресации, состоящая в присваивании объявленному указателю адреса переменной:
double d=7.,*dP;
dP=&d; // адресация
int i=2, *iP;
iP=&i; // адресация
char c='A',*cP;
cP=&c; // адресация
Знак & перед переменной возвращает её адрес.
Для того чтобы получить значение переменной, производится операция разыменования. Знак * перед указателем возвращает значение переменной, на которую ссылается указатель. С учётом предыдущей адресации получим:
double d1;
d1=*dP; // разыменование
/* d1=7. */
int i1;
i1=*iP; // разыменование
/* i1=2 */
char c1;
c1=*cP; // разыменование
/* c1='A' */
Необходимо следить за тем, чтобы указатель ссылался на переменную того типа, для которого он объявлен.
Над указателями возможно проведение арифметических действий (операции инкремента и декремента; сложение и вычитание указателей с другими целыми числами, вычитание одного указателя из другого (только для указателей на один тип)).
6.2. Указатели и массивы
Указателем на массив является само имя массива, а также указатель на его первый (с индексом 0) элемент:
double array[10], *mP;
mP=array; // адресация
// или
mP=&array[0]; // адресация
Проиллюстрируем арифметику указателей применительно к массивам.
Использование операции инкремента:
mP++; // приводит к смещению на второй элемент массива array[1]
Далее сложение mP с целым числом 7:
mP+=7; // переводит указатель на элемент массива array[8]
Затем операция декремента:
--mP; // сместит указатель на элемент массива array[7]
Разность указателей определит разность между номерами элементов, на которые они указывают:
int i=mP‒ array; // i=7
Указатели на один и тот же тип могут быть собраны в массив:
// array[10] – массив вещественных чисел;
// mP – указатель на массив array[10];
// mmP[10] – массив указателей на действительный тип
double array[10], *mP, *mmP[10];
// ввод элементов массива array[10] и массива указателей mmP[10]
for(int i=0; i<10; i++) {
array[i]=3.14*i*i+1;
mmP[i]=&array[i];
}
mP=&array[0]; // адрес элемента массива с индексом 0
// вывод элементов массива array[10]
for(int i=0; i<10; i++) {
// по значению array[i]
cout<<array[i]<<' ';
/*по указателю на массив с последующим смещением на один элемент */
cout<<*mP++<<' '; // с операцией разыменования
/* по указателю-имени массива со смещением на значение индекса */
cout<<*(array+i)<<' '; // с операцией разыменования
/* по указателю на каждый элемент из массива указателей */
cout<<*mmP[i]<<' '; // с операцией разыменования
cout<<"\n";
}
6.3. Указатель – аргумент функции
Аргумент в функцию может быть передан с помощью аргумента-указателя. Выше в примерах 14 и 15 была использована функция swop с аргументами-ссылками для обмена значениями между переменными. Рассмотрим другой вариант ‒ с указателями в качестве аргументов:
void swop(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
Вызов функции swop программно оформляется следующим образом:
swop(&x, &y);
Указатель представляет собой адрес переменной, поэтому в качестве фактических параметров в функцию swop передаются адреса &x, &y переменных x и y. Для того чтобы получить значения x и y, производятся операции разыменования (t=*x; *x=*y; *y=t;), т.е. действия выполняются с собственно переменными x и y, которые после выхода из функции сохраняют изменённые значения.
Для объявления функции swop в программе может также использоваться и прототип:
void swop(int *, int *);
Тогда описание функции swop будет следовать после основной ‒ main.