
- •Часть 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
§ 4. Область действия имён. Локальные и глобальные имена
Существенной особенностью функций языка С++, упрощающей их изучение, является то, что функции не могут быть вложенными. Другими словами, невозможно определить (описать) одну функцию внутри другой. В таком случае говорят, что все функции находятся на одном уровне видимости. Поэтому вопрос области действия имён решается проще, чем на языке Pascal.
Есть несколько мест объявления локальных переменных.
В скобках в прототипе и в заголовке при описании функции перечисляются только те переменные, которые должны быть переданы в функцию, то есть входные, и её результаты (выходные параметры), если такие есть. Такие переменные, названные формальными параметрами, доступны (видны, их можно использовать) только в той функции, в заголовке которой они описаны. Повторно в теле функции формальные параметры объявлять не надо! В прототипе функции имена параметров можно не писать, достаточно указать только их типы. Эта информация используется компилятором при проверке соответствия типов и количества фактических и формальных параметров. При описании функции в её заголовке имена параметров и повторно их типы записываются обязательно; Как видно из предыдущих примеров, здесь объявляются не все используемые в функции переменные.
Переменные, содержащие некоторые промежуточные значения, объявляются в любом месте тела функции до первого их использования, доступны только в ней и являются также локальными. Они не являются формальными параметрами, в заголовке функции не записываются, при вызове функции не передаются. В теле функции, отличной от void, можно объявить также переменную для результата, возвращаемого с помощью return переменная.
Как частный случай последней возможности переменные можно объявить внутри блока. Блок или составной оператор — это последовательность операторов, заключённая в фигурные скобки. Таким блоком может быть, например, тело любого из циклов, одна из ветвей if или switch. Например,
if (…) { float t; …}. Такую переменную (t) можно использовать только в этом блоке и во всех внутренних (вложенных) по отношению к нему. Вне данного блока она недоступна. Этим мы гарантируем, что вне блока такая переменная не будет изменена. Такая локальная переменная часто используется в заголовке for.
…… //Здесь i недоступна
for (int i=0; i<n;i++) // i видна в заголовке
{ …… // i видна здесь
}
…… // Здесь i использовать нельзя
При таком объявлении переменную (в примере i) можно использовать только внутри цикла и в любом из трёх выражений заголовка цикла.
Объявив её вне заголовка цикла, получим:
……// Здесь i использовать нельзя
int i;
… ... //Здесь i видна
for (i=0; i<n;i++) // i видна и в заголовке цикла
{ …… /* i видна и в цикле */ }
… … // i доступна и после цикла здесь
Тогда она видна не только в цикле, а и в любом месте после объявления, как перед for, так и после фигурных скобок для цикла.
Локальные переменные имеют следующие особенности:
их можно объявить в любом месте функции или блока до первого их использования, то есть не обязательно в самом начале. Это, конечно, не относится к формальным параметрам, которые объявляются всегда в скобках заголовка;
локальные переменные создаются при входе в функцию или блок и уничтожаются при выходе из них. При этом не просто теряются значения, но и освобождается память;
локальные переменные в разных функциях или блоках, не вложенных друг в друга, могут иметь одинаковые идентификаторы. Но на самом деле это разные переменные, для них отводится разная память.
Переменные, объявленные в main, также являются локальными и их можно использовать только в основной функции.
Глобальные переменные можно объявить вне всех функций, в том числе вне main, например, в самом начале перед прототипами функций. Кроме этого их разрешается объявлять также между прототипами, непосредственно перед функцией main или между текстами функций. Особенности таких переменных:
“видны” из любой функции, размещенной после описания переменной;
память занята на всё время выполнения проекта;
как правило, использование локальных переменных предпочтительнее глобальных. Например, из двух вариантов функции
/* Вариант 1 */ float MyMax1 (float x, float y) { return x>y?x:y; }
/* Вариант 2 */ float x, y; float MyMax2 () { return x>y?x:y; }
первый лучше, так как использует локальные переменные. Во втором варианте используются глобальные переменные. Противоречие в том, что второй вариант легче для написания. Это относится и к функциям типа void. Объясняется это тем, что не надо заботиться о передаче входных параметров в функцию и можно не знать, как вернуть результаты из функции. То есть можно не знать ни ссылочный тип, ни указатели для этих целей.
Сказанное выше относится к константам и типам. Эти элементы также могут быть локальными, то есть объявленными в функции или в блоке, и глобальными, которые доступны всем или нескольким функциям. Понятно, что не имеет смысла говорить о формальных константах или формальных типах.