Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика. Базовый курс. Ч.3. Основы алгоритмизации и про- граммирования в среде Visual C++ 2005.pdf
Скачиваний:
51
Добавлен:
05.02.2023
Размер:
3.81 Mб
Скачать

80

case 2 : m2=feb; break; case 3 : m2=mar; break; case 4 : m2=apr; break; case 5 : m2=may; break; case 6 : m2=jun; break; case 7 : m2=jul; break; case 8 : m2=aug; break; case 9 : m2=sep; break; case 10 : m2=oct; break; case 11 : m2=nov; break; case 12 : m2=dec; break;};

AnsiToOem(" предшествует \n", str); AnsiToOem("не предшествует \n", str1);

if (m1<m2) cout<<str; else

if ((m1==m2)&&(d1<d2))cout<<str; else cout<<str1; return(0); }

12.УКАЗАТЕЛИ

12.1.Понятие об указателях

Указатель – это целочисленная переменная, содержащая адрес (номер ячейки памяти) другой переменной.

Описание:

тип *имя , т.е перед именем указателя ставится знак *

Например, float a, *aP;

Так как указатель есть адрес, а адреса распределяет сам компьютер, то указатель не может быть инициализирован непосредственно. Операция адресации, т.е. присваивание объявленному указателю адреса переменной, производится, например, следующим образом:

float a, *aP; aP=&a;

Знак & перед именем переменной возвращает ее адрес, или, как говорят, дает ссылку.

Для того чтобы получить значение переменной, производится операция разыменования. Знак * перед указателем возвращает значение переменной, на которую указатель ссылается. Например,

float a1, a=6.0, *aP; aP=&a; a1=*aP;

Здесь в результате a1 примет значение 6.0

81

Операции адресации и разыменования взаимно компенсируют друг друга при их применении к указателю последовательно и в любом порядке:

&*aP; эквивалентно *&aP;

Пример 12.1. Проведем манипулирование данными с помощью указателей: переменной a присваивается значение 5, указателю aP присваивается ее адрес, затем по адресу указателю присваивается значение 7. В результате оказывается, что значение переменной a изменилось на 7, хотя непосредственно к ней никто не обращался. И далее изменим непосредственно значение a на 9 и при обращении к ней, как непосредственно, так и через указатели увидим, что значение изменилось на 9.

// использование указателей

#include <iostream> #include <windows.h> using namespace std;

int a, *aP; char str[256]; int main()

{a=5; cout<<"\n a= "<<a; aP=&a; cout<<"\n *aP= "<<*aP;

AnsiToOem("\n присваиваем *aP значение 7 ", str); cout<<str;

*aP=7; cout<<"\n *aP= "<<*aP; cout<<" a= "<<a; AnsiToOem("\n присваиваем a значение 9 ", str); cout<<str;

a=9; cout<<"\n a= "<<a; cout<<" *aP= "<<*aP; cout<<"\n";

return (0); }

В результате получим (рис. 8.26):

Рис. 8.26. Результат работы программы примера 12.1

82

12.2. Указатели и функции

Как известно, при обращении к функции параметры, передаваемые функции, являются локальными переменными данной функции. Изменения, внесенные в аргументы во время выполнения функции не влияют на переменные, значения которых передаются функции. (Это одна из причин, почему функция по результатам ра-

боты выдает только одно значение.)

Проиллюстрируем это на примере.

Пример 12.2. Создать функцию swap(x, y), которая меняет значения переменных x, y местами и проверить значения переменных до обращения к функции, внутри функции и после обращения к функции.

// передача параметров в функцию (по значению) #include <iostream>

#include <iomanip> #include <windows.h> using namespace std; char str[256];

void swap(int x, int y); int main()

{int x,y; x=5, y=10;

AnsiToOem("\n x,y до обращения", str);

cout<<str <<setw(3)<<x<<setw(3) <<y; swap(x,y); AnsiToOem("\n x,y после обращения", str); cout<<str<<setw(3)<<x<<setw(3) <<y<<"\n";

return(0);}

void swap(int x, int y)

{int z;

AnsiToOem("\n x,y внутри функции до преобразования", str); cout<<str<<setw(3)<<x<<setw(3)<<y; z=x; x=y; y=z; AnsiToOem("\n x,y внутри функции после преобразования", str); cout<<str <<setw(3)<<x<<setw(3)<<y;

}

В результате исполнения программы получим (рис. 8.27):

Рис. 8.27. Результат работы программы примера 12.2

83

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

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

//передача параметров (по ссылке с пом. указателей) #include <iostream>

#include <iomanip> #include <windows.h> using namespace std; char str[256];

void swap(int *x, int *y); int main()

{int x,y; x=5, y=10;

AnsiToOem("\n x,y до обращения ",str); cout<<str<<setw(3)<<x<<setw(3) <<y;

swap(&x,&y);

AnsiToOem("\n x,y после обращ-я ",str); cout<<str<<setw(3)<<x<<setw(3) <<y<<"\n";

return(0);}

void swap(int *px, int *py) {int z;

AnsiToOem("\n x,y внутри функции до преобразования",str); cout<<str <<setw(3)<<*px<<setw(3)<<*py;

z=*px; *px=*py; *py=z;

AnsiToOem("\n x,y внутри функции после преобразования ",str); cout<<str <<setw(3)<<*px<<setw(3)<<*py;

}

В результате получаем (рис. 8.28):

Рис. 8.28. Результат работы примера 12.2 (с указателями)

84

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

// передача параметров в функцию (по ссылке) #include <iostream>

#include <iomanip> #include <windows.h> using namespace std; char str[256];

void swap(int &x, int &y); int main()

{int x,y; x=5, y=10;

AnsiToOem(" \n x,y до обращения ",str); cout<<str <<setw(3)<<x<<setw(3)<<y; swap(x,y);

AnsiToOem(" \n x,y после обращения ",str); cout<<str<<setw(3)<<x<<setw(3) <<y<<"\n";

return(0);}

void swap(int &rx, int &ry)

{int z;

AnsiToOem("\n x,y внутри функции до преобразования ",str); cout<<str <<setw(3) <<rx<<setw(3) <<ry;

z=rx; rx=ry; ry=z;

AnsiToOem("\n x,y внутри функции после преобразования ",str); cout<<str <<setw(3)<<rx <<setw(3) <<ry; }

В результате имеем (рис. 8.29):

Рис. 8.29. Результат работы программы примера 12.2 (с использованием ссылок)