- •Оглавление
- •1.2. Свойства языков программирования
- •1.3. Основные парадигмы программирования Процедурное программирование
- •Модульное программирование
- •Абстракция данных
- •Объектно-ориентированное программирование
- •Непечатные символы
- •Тема 2 Типы данных
- •2.1. Понятие переменной и объявление переменных
- •Объявление переменных
- •Встроенные типы данных
- •Размер памяти, выделяемой под встроенные типы данных
- •2.2. Константы и перечисления Константные переменные
- •Перечисления
- •2.3. Операции и выражения
- •Мультипликативные операции
- •Операции сравнения
- •Побитовые логические операции
- •Побитовые операции
- •Комментарии
- •Оператор while(пока)
- •Оператор do/while(выполнять/пока)
- •Оператор for(цикл)
- •Оператор множественного выбора switch
- •Операторы breakиcontinue
- •Тема 4 Массивы
- •4.1.Определение, объявление и инициализация массивов
- •Объявления и инициализация массивов в программе
- •4.2. Сортировка массивов Пузырьковая сортировка
- •Сортировка вставками
- •4.3. Поиск в массивах Линейный поиск
- •Двоичный поиск
- •4.4. Многомерные массивы
- •Тема 5 Указатели Объявления и инициализация переменных указателей
- •5.1. Операции над указателями
- •5.2. Выражения и арифметические действия с указателями
- •5.3. Взаимосвязи между указателями и массивами
- •5.4. Массивы указателей
- •5.5. Динамическое выделение памяти под массивы
- •Тема 6 Функции
- •6.2. Определения функций
- •Генерация случайных чисел
- •6.3. Классы памяти и область действия Классы памяти
- •Область действия
- •6.4. Рекурсия
- •6.5. Ссылки и ссылочные параметры
- •Вызов функций по ссылке с аргументами указателями
- •6.6. Использование спецификатораconstс указателями
- •6.7. Перегрузка функций
- •Аргументы по умолчанию
- •6.8. Передача массивов в функции
- •6.9. Указатель на функцию
- •6.10. Командная строка аргументов
- •6.11 Неопределенное количество аргументов
- •Тема 7 Введение в обработку строк
- •7.1. Работа со строками в с
- •Понятие символов и строк в с
- •Функции для работы со строками
- •Определение длины строки
- •Сложение двух строк (конкатенация)
- •Добавление к исходной строке указанного количества символов.
- •Копирование строки в другую строку
- •Сравнение строк
- •Получение строки от пользователя
- •Тема 8 Работа с файлами
- •Открытие файла
- •Чтение из файла символа или строки символов
- •Запись символа или строки символов в файл
- •Смещение внутри файла
- •Значения параметра fromwhereфункцииfseek
- •Закрытие файла
- •Тема 9 Компоновка программ и препроцессор
- •9.1. Компоновка программ
- •Проблема использования общих функций и имен
- •Использование включаемых файлов
- •9.2. Препроцессор
- •Определение макросов
- •Условная компиляция
- •Дополнительные директивы препроцессора
- •Тема 10 Структуры
- •10.1. Определение структур и доступ к элементам
- •Доступ к элементам структур
- •Использование структур
- •10.2. Битовые поля
- •10.3. Объединения
- •10.4. Построение связных списков на основе структур с самоадресацией
- •Создание простого связного списка
- •Очереди
- •Деревья
- •Список рекомендуемой литературы
Генерация случайных чисел
Программа моделирует бросание игральной кости (рис. 6.4.)
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
srand(time(0));
for (int i = 1; i <=20; i++)
cout << 1+ rand() % 6 << endl;
return 0;
}
Рис. 6.4. Программа, моделирующая бросание игральной кости
Функция rand()генерирует псевдослучайное целое число в диапазоне между0иRAND_MAX(константа, определенная в заголовочном файлеstdlib.h). Для данной программы необходимы только числа, лежащие в диапазоне от1до6.
rand() % 6– эту операцию называютмасштабированием. Число 6 называетсямасштабирующим коэффициентом. В результате этой операции получаются числа от0до5включительно. После масштабирования нужносдвинутьдиапазон чисел, добавляя1к каждому полученному результату.
Так как функция rand()генерирует псевдослучайные числа, то при втором запуске программы будут получены те же числа, что и при первом. Для получения разных последовательностей необходимо применить операциюрандомизации. Она реализуется с помощью библиотечной функцииsrand. Функция получает в качестве аргумента беззнаковое целое и при каждом выполнении программы задает начальное число, которое функцияrandиспользует для генерации последовательности псевдослучайных чисел. Функцияtimeстандартной библиотеки<time.h>возвращает наилучшее приближение текущего календарного времени, обеспечиваемое реализацией. Таким образом, при каждом запуске программы в генератор псевдослучайных чисел будет передаваться разное начальное число.
6.3. Классы памяти и область действия Классы памяти
В C++ имеется [1] четыре спецификации класса памяти:auto,register,externиstatic. Спецификация класса памяти идентификатора помогает определить его класс памяти, область действия и пространство имен.
Класс памятиидентификатора определяет еговремяжизни- период, в течение которого этот идентификатор существует в памяти. Одни идентификаторы существуют недолго, другие - неоднократно создаются и уничтожаются, третьи - существуют на протяжении всего времени выполнения программы.
Спецификации класса памяти могут быть разбиты на два класса: автоматический класс памяти с локальным временем жизниистатический класс памяти с глобальным временем жизни. Ключевые словаautoиregisterиспользуются для объявления переменных с локальным временем жизни. Такие переменные создаются при входе в блок, в котором они объявлены, они существуют лишь во время активности блока и исчезают при выходе из блока.
К классу с локальным временем жизни могут относиться только переменные. К этому классу относятся локальные переменные функций и параметры функций. Спецификация autoявно объявляет переменные автоматического класса памяти, т.е. с локальным временем жизни. Например, следующее объявление указывает, что переменныех иутипаfloatявляются временными с локальным временем жизни, т.е. они существуют только в теле функции, в которой появляется объявление:
auto float x, у;
Локальные переменные являются переменными с локальным временем жизни по умолчанию, так что ключевое слово autoиспользуется редко. Далее будем ссылаться на переменные автоматического класса памяти просто как на автоматические переменные.
Обычно данные в версии программы на машинном языке загружаются для расчетов и другой обработки в регистры.
Спецификация класса памяти registerможет быть помещена перед объявлением автоматической переменной, чтобы компилятор сохранял переменную не в памяти, а в одном из высокоскоростных аппаратных регистров компьютера. Если интенсивно используемые переменные, такие как счетчики или суммы могут сохраняться в аппаратных регистрах, накладные расходы на повторную загрузку переменных из памяти в регистр и обратную загрузку результата в память могут быть исключены.
Компилятор может проигнорировать объявления register. Например, может оказаться недостаточным количество регистров, доступных компилятору для использования. Приведенное далее объявление определяет, что целая переменнаяcounterдолжна быть помещена в один из регистров компьютера; независимо от того, сделает это компилятор или нет,counterполучит начальное значение1:
register int counter = 1;
Ключевое слово registerможет применяться только к локальным переменным и параметрам функций. Часто объявленияregisterне являются необходимыми. Современные оптимизирующие компиляторы способны распознавать часто используемые переменные и решать, помещать их в регистры или нет, не требуя от программиста объявленияregister
Ключевые слова externиstaticиспользуются, чтобы объявить идентификаторы переменных и функций как идентификаторы статического класса памяти с глобальным временем жизни. Такие переменные существуют с момента начала выполнения программы. Для таких переменных память выделяется и инициализируется сразу после начала выполнения программы. Имена функций тоже существуют с самого начала выполнения программы. Однако это не означает, что эти идентификаторы могут быть использованы во всей программе. Класс памяти и область действия (где можно использовать имя) — это разные вещи.
Существуют два типа идентификаторов статического класса памяти: внешние идентификаторы (такие, как глобальные переменные и имена функций), и локальные переменные, объявленные спецификацией класса памяти static. Глобальные переменные и имена функций по умолчанию относятся к классу памятиextern. Глобальные переменные создаются путем размещения их объявлений вне описания какой-либо функции. Глобальные переменные сохраняют свои значения в течение всего времени выполнения программы. На глобальные переменные и функции может ссылаться любая функция, которая расположена после их объявления или описания в файле.
Если глобальная переменная объявлена в одном файле, а используется в другом, то ее нельзя просто повторно объявить. Для этого в другом файле ее нужно объявить со словом extern, например:
int x, y; //объявление в одном файле (file1)
extern int x, y; //extern объявление в другом файле (file2)
После такого объявления переменных xиyв файлеfile2они будут видны, но повторно создаваться не будут.
#include <iostream>
using namespace std;
int counter()
{
static int count; //по умолчанию count = 0
return ++count;
}
int main()
{
for(int i=0;i<10;i++)
cout<<counter()<<endl;
return 0;
}
Рис. 6.5. Функцияcounterсчитает количество собственных вызовов
Локальные переменные, объявленные с ключевым словом static, известны только в той функции, в которой они определены, но в отличие от автоматических переменных локальные переменныеstaticсохраняют свои значения в течение всего времени существования функции. При каждом следующем вызове функции локальные переменные содержат те значения, которые они имели при предыдущем вызове (см. рис. 6.5.). Следующий оператор объявляет локальную переменнуюcountкакstaticи присваивает начальное значение 1
static int count = 1;
Все числовые переменные статического класса памяти принимают нулевые начальные значения, если программист явно не указал другие начальные значения.
Глобальные переменные и функции, определенные со словом staticизвестны только для файла, где они объявлены.
В С++ для той же цели используются анонимные пространства имен [2]. Использование глобальных static-переменных не рекомендуется.