
- •Часть 1
- •18 Сентября 2012 г., протокол № 1
- •Предисловие
- •§ 1. Основные понятия программы
- •1.2. Директива препроцессора #include
- •Структура программы
- •Комментарии
- •Ключевые слова, идентификаторы, переменные
- •§ 2. Ввод, вывод
- •§ 3. Выражения
- •3.1. Константы
- •Непосредственно записать в выражении;
- •3.2. Операции и их приоритет
- •3.3. Операции отношения и логические операции
- •3.4. Операция присваивания
- •§ 4. Программирование ветвлений
- •4.1. Оператор if
- •4.2. Тернарная операция
- •4.3. Оператор выбора switch
- •Г л а в а 2 циклы
- •§ 1. Оператор while
- •§ 2. Оператор break
- •§ 3. Оператор do … while
- •§ 4. Оператор for
- •Г л а в а 3 Введение в массивы
- •§ 1. Основные понятия
- •§ 2. Способы определения массивов
- •§ 3. Вывод массива. Функции printf и cprintf
- •§ 4. Типы задач при работе с массивами
- •Упражнения и тесты
- •Г л а в а 4 модульное программирование. Функции
- •§1. Функции без результатов. Параметры-значения
- •1.1. Примеры. Правила оформления и вызова функций
- •Формальные и фактические параметры
- •Передача параметров по значению
- •§ 2. Функции типа void с результатами
- •2.1. Вычислeниe бeсконeчных сумм
- •2.2. Что такое ссылочный тип
- •2.3. Параметры ссылочного типа
- •§ 3. Функции, отличные от void. Оператор return
- •§ 4. Область действия имён. Локальные и глобальные имена
- •§ 5. Встраиваемые (inline) функции
- •§ 6. Параметры по умолчанию
- •§ 7. Перегрузка функций
- •7. Сравнение функций типа void и отличных от типа void.
- •Г л а в а 5 введение в объектно-оРиентированное программирование
- •§ 1. Первое знакомство с ооп
- •§ 2. Класс. Поля и методы класса
- •§ 3. Создание объектов. Конструктор
- •Упражнения и тесты
- •Оглавление
- •3.1. Константы …………………………………………….………..….........…8
- •Упражнения и тесты …….………………..………………………….…………....19
- •Методы программирования:
- •Лекции, примеры, тесты
- •Пособие для студентов механико-математического факультета
- •В двух частях
- •Часть 1
2.2. Что такое ссылочный тип
Сначала рассмотрим самостоятельное использование переменной этого типа, так называемую независимую ссылку. Пусть объявлены две переменные, обычная (x) и ссылочного типа (s): float x=5; float &s=x;. Переменная ссылочного типа обязательно должна быть проинициализирована. При этом особенностью инициализации является использование ранее объявленной обычной переменной (в нашем примере x).
После такого объявления идентификатор s определяет другое, альтернативное, имя одной и той же ячейки, названной x. Другими словами, s и x — синонимы, разные идентификаторы для обозначения одной и той же области оперативной памяти, одной и той же переменной. Иногда говорят, что ссылочная переменная — это псевдоним переменной, к которой она обращается. Поэтому оператор cout<<endl <<x<<" "<<s; выведет два одинаковых числа 5. Изменим значение переменной x, например, x*=2; а выведем s: cout<<endl <<x<<
” “<<s; Несмотря на то, что значение s явно в программе не изменялось, то есть не было записано s*=2, оно также изменится, и будут выведены два одинаковых числа 10. Это произошло потому, что между этими переменными нет разницы, то есть s и x — имена одной и той же ячейки. Наоборот, если изменим значение s, например, s+=100; а с помощью cout<<endl <<x<<” “<<s; выведем x, то убедимся, что x также изменилось, и выводятся два одинаковых числа 110.
Если объявить и проинициализировать ещё одну “обычную” переменную float y=3; и записать s=y; то копируются не адреса, а, как и при обычном объявлении, значение одной ячейки (y) помещается в другую, которую можно использовать как с именем s, так и x. Аналогично, s++ не меняет адрес, а увеличивает на единицу значение переменной s или x. Другими словами, с ячейкой s работаем как с обычной переменной.
Если объявляется несколько переменных ссылочного типа, то перед каждым идентификатором должен стоять символ “&”.
Следует различать использование символа & для взятия адреса элемента. Это связано с указателями и рассматривается позже. При работе с переменными ссылочного типа символ & записываем только при объявлении.
Самостоятельное использование переменных ссылочного типа не имеет практического применения. Наоборот, независимые ссылки создают недоразумения и затрудняют отладку программы. Ссылочный тип эффективен в функциях.
2.3. Параметры ссылочного типа
Для возврата полученных результатов простого типа из функций ссылочный тип используется следующим образом:
в заголовке функции параметрырезультаты (в нашем примере y, z) записываем как переменные ссылочного типа, то есть с символом &;
в тексте функции никакие дополнительные операции, а значит, и символы, для этих переменных не используем, то есть работаем, как с обычными переменными;
при вызове функции в качестве фактических параметров, указываем простые переменные соответствующего типа (cs, sn), объявленные обычным образом;
входные параметрызначения используются по тем же правилам (см. §1);
вызов функции типа void с несколькими результатами осуществляется как вызов функции типа void без результата, то есть отдельно, а не в выражении (см. § 1).
Почему полученное значение возвращается в вызывающую функцию? Мы уже знаем, что с помощью ссылочного типа определяется другое имя ячейки. Поэтому для формального (y) и фактического (cs) параметров отводится одна и та же ячейка, которая в функции SINCOS называется y, а при вызове в головной функции — cs. Поэтому если в функции получим y, то этим самым определим и значение cs, то есть полученное в функции значение возвращается в вызывающую функцию просто с другим именем. При этом никакого копирования не выполняется. Аналогично для переменных z и sn также резервируется одна и таже ячейка оперативной памяти.
Аналогично ссылочный тип используется и в случае, если значение переданной в функцию переменной надо не просто получить, как в рассмотренном выше примере, а передать в функцию, изменить и это изменённое значение надо возвратить в точку вызова. В таком случае одна и та же переменная является и входным, и выходным параметром. Например, составим функцию для перестановки значений двух переменных:
void CHANGE (float &u, float &v)
{ float temp=u; u=v; v=temp; }
Тогда вызвать её можно, например, так:
float a=1.1, b=2.2; CHANGE( a, b);
Так как a и u — это два имена одной и той же ячейки благодаря ссылочному типу, то изменение u с 1.1 на 2.2 автоматически приведёт к изменению переменной a. Аналогично изменится и переменная b, если изменили значение переменной v. И тогда оператор cout<<a<<” “<<b; после вызова функции выведет изменённые значения 2.2 и 1.1, полученные в результате их перестановки. Заметим, однако, что если бы заголовок функции записать без ссылочного типа void CHANGE (float u, float v); то программа будет не только компилироваться, но и выполняться. Но при этом в функции u и v будут переставлены, но это изменение не передаётся в вызывающую функцию для a и b, то есть эти переменные не изменятся.