Программирование >>  Структурное программирование 

1 ... 108 109 110 [ 111 ] 112 113 114 ... 342



vPtr

Рис. 5.2. Графическое представление указателя, указывающего на целую переменную в памяти yPtr у

500000

600000

600000

Рис. 5.3. Представление у и yPtr в памяти

Программа на рис. 5.4 демонстрирует операции с указателями. Ячейки памяти выводятся как шестнадцатиричные целые с помощью cout (смотри приложение Г, Системы счисления , для получения большей информации о шестнадцатиричных целых). Заметим, что адрес а и значение aPtr идентичны; это подтверждает, что адрес а действительно присвоен переменной указателю aPtr. Операции & и * взаимно дополняют друг друга - при их поочередном применении к aPtr в любой последовательности будет напечатан один и тот же результат. Таблица на рис. 5.5 показывает приоритет и ассоциативность операций, рассмотренных к данному моменту.

Использование операций & и tinclude <iostream.h>

main()

int a ; int *aPtr;

a = 7; aPtr = &a;

a - целое число

aPtr - указатель на целое число

aPtr устанавливается равным адресу а

cout Адрес а: &а endl

<< Значение aPtr: aPtr endl endl;

cout Значение a: a endl

Значение *aPtr: << *aPtr endl endl;

cout << Доказательство, что S и * дополняют

друг друга. endl &*aPtr = s*aPtr endl *&aPtr = *&aPtr endl;

return 0;

Рис. 5.4. Операции & и * над указателями (чааь 1 из 2)



Адрес а: 0xfff4 Значение aPtr: 0xfff4

Значение а: 7 Значение *aPtr: 7

Доказательство, что S и * дополняют друг друга. S*aPtr = 0xfff4 *&aPtr = 0xfff4

Рис. 5.4. Операции & и * над указателями (часть 2 из 2)

Операции

Ассоциативность

0 []

слева направо

наивысший

+ - + - ! * & (тип)

справа налево

унарные

/ %

слева направо

мультипликативные

слева направо

аддитивные

>>

слева направо

поместить в/взять из

< <= > >=

слева направо

отношение

== ! =

слева направо

проверка на равенство

&&

слева направо

логическое И

слева направо

логическое ИЛИ

справа налево

условная

+ = -= *= /= % =

справа налево

присваивание

слева направо

запятая

(поспедование)

Рис. 5.5. Приоритет операций

5.4. Вызов функций по ссылке

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

Как мы видели в главе 3, return можно использовать для возвращения одного значения из вызываемой функции вызывающему оператору (или для передачи управления из вызываемой функции без возвращения какого-либо значения). Мы также видели, что аргументы могут быть переданы функции с использованием аргументов ссылок, чтобы дать возможность функции модифицировать исходные значения аргументов (таким образом, из функции может быть возвращено более одного значения), или чтобы передать функции большие объекты данных и избежать накладных расходов, сопутствующих передаче объектов вызовом по значению (которая требует копирования объекта). Указатели, подобно ссылкам, тоже можно использовать для моди-



int cubeByValue(int n) {

return n * n * n; куб локальной переменной n

Исходное Значение числа: 5 Новое значение числа: 125

Рис. 5.6. Возведение переменной в куб с использованием вызова по значению

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

В С++ программисты могут использовать указатели и операции косвенной адресации для моделирования вызова по ссылке. При вызове функции с аргументами, которые должны быть модифицированы, передаются адреса аргументов. Это обычно сопровождается операцией адресации (&) переменной, которая должна быть модифицирована. Как мы видели в главе 4, массивы не передаются с использованием операции &, потому что имя массива - это начальный адрес массива в памяти (имя массива эквивалентно &аггау-Name[0]). При передаче функции адреса переменной может использоваться операция косвенной адресации (*) для модификации значения (если значение не объявлено как const) ячейки в памяти вызывающего оператора.

Программы на рис. 5.6 и 5.7 представляют два варианта функции, которая возводит в куб целое число - cubeByValue и cubeByReference. Программа на рис. 5.6, передает переменную number функции cubeByValue вызовом по значению. Функция cubeByValue возводит в куб свой аргумент и возвращает новое значение в main, используя оператор return. Новое значение присваивается переменной number в main. Ключевой момент вызова по значению состоит в том, что вы имеете возможность анализировать результат вызова функции перед модификацией значения переменной. Например, в этой программе мы могли бы сохранить результат cubeByValue в другой переменной, исследовать его значение, и после этой проверки присвоить результат переменной number.

Программа на рис. 5.7 передает переменную number по ссылке - в функцию cubeByReference передается адрес number. Функция cubeByReference в качестве аргумента получает nPtr (указатель на int). Функция разыменовывает указатель и возводит в куб значение, на которое указывает nPtr. Это изменяет значение number в main. Рисунки 5.8 и 5.9 графически анализируют программы на рис. 5.6 и 5.7 соответственно.

Возведение переменной в куб с использованием вызова по значению #include <iostream.h>

int cubeByValue(int); прототип

main () {

int number = 5;

cout << Исходное значение числа: << number << endl; number = cubeByValue(number);

cout << Новое значение числа: << number << endl; return 0;



1 ... 108 109 110 [ 111 ] 112 113 114 ... 342

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика