SlideShare a Scribd company logo
1 of 112
Теория и практика С++1
1
Язык программирования С++
История С и С++.
История начинается с 1970 год. (Bell Labs - бывшая американская, а ныне франко-американская корпорация,
крупный исследовательский центр в области телекоммуникаций, электронных и компьютерных систем ). Два
сотрудника Кен Томпсон и Денис Ричи являлись ведущими инженерами команды перед которыми была
поставлена задача написать переносимую ОС. Что это значит? Было несколько моделей компьютеров с разным
устройством и хотелось написать систему, которая могла работать на разных моделях.
Для этой цели был разработан язык С для ОС Unix. К языку предъявлялись следующие требования:
1. Эффективность, как язык Ассемблер.
2. Более удобен, чем Ассемблер.
Например – сложение двух чисел.
ASM C
mov AX, 2
mov BX, [1234]
add AX, BX
mov [DX], AX
a = b +c
Более сложные вещи пишутся еще более громоздко.
3. Переносимость на уровне текстов исходных программ.
Т.е. если есть новая платформа, то для нее достаточно написать компилятор С, которых мог перевести
программу на С для новой платформы. На языке ASM это было бы неудобно. У инструкций ASM есть
операнды, которые могут отличаться на различных машинах. Т.е. Язык ASM наиболее близок к машинному
коду. Хотелось от этого абстрагироваться. И такой язык был разработан - С.
Но в погоне за эффективностью он ближе к машине, чем к программисту.Например:
1. Нет специального символьного типа.
2. В нем отсутствует булевский тип для логических значений (true и false). Любое число 0 – true. 0 = false.
Казус:
if (a = 0) {
}
а сравнивается с нулем. На самом деле программист хотел написать a == 0. Ошибка, всегда будет false (в
результате присваивания возвратился ноль) и в условие никогда не попадем. С точки зрения компилятора
инструкция легальна. Ошибки не видит.
1980 год.
Bell Labs – Бьерн Страуструп.
Предложил новый язык С++, который является развитием языка С. Изначально язык назывался C++ with classes.
Т.е. С и еще что-то. Необходимость этого языка возникла из-за необходимости писать программы работающие с
большими БД.
Большинство программистовразрабатывают системы автоматизации (банка, магазина), т.е. автоматизация каких
то процессов в бизнесе. Язык С++ добавляет что-то к языку С и при этом сохраняется обратная совместимость,
т.е. С является подмножеством языка С++.
Почему так сделали, а не написали все заново при этом убравмногие ошибки в языке С? Потому что очень
много кода написано на языке С. По истории все.
Теория и практика С++2
2
Порядок создания программы
1. С помощью текстового редактора напишите свою программу
и сохраните ее в файле. Это будет исходный код вашей
программы.
2. Скомпилируйте исходный код. Для этого необходимо
запустить программу,которая транслирует исходный код во
внутренний язык, называемый машинным языком рабочего
компьютера. Файл, содержащий транслированную
программу — это объектный код вашей программы.
3. Свяжите объектный код с дополнительным кодом. Например,
программы на C++ обычно используют библиотеки.
Библиотека C++ содержит объектный код для набора
компьютерных подпрограмм, называемых функциями. В
процессе связывания ваш объектный код комбинируется с
объектным кодом для используемых функций и с некоторым
стандартным кодом запуска для формирования версии
времени выполнения вашей программы.Файл, содержащий
этот финальный продукт, называется исполняемым кодом.
1. Начальные сведения о языке С++
Программа 1_1
//программа отображаетна экране сообщение
#include <iostream> //директива препроцессора
using namespace std; //включает в программу определения
int main() //заголовок функции
{ //начало тела функции
cout << "I love C++"; //сообщение
cout << "n"; //начать новую строку
return 0; //завершение функции main()
} //конец тела функции
Результат:
Come up and C++ me some time
Функция main()
Программа С++ строится из отдельных блоков, называемых функциями. Программа 1_1 имеет
следующую структуру:
int main()
{
операторы
return 0;
}
Эти строки во-первых, означают, что перед нами функция с именем main(), и, во-вторых, они содержат
описание работы этой функции. Вся совокупность приведенных выше строк составляет определение функции.
Это определение состоит из двух частей: первой строки int main(), которая называется заголовком функции, и
остальной части, заключенной в фигурные скобки, которая является телом функции.
Заголовок функции определяет интерфейс между функцией и остальной частью программы, а тело функции
содержит инструкции для компьютера. Каждая завершенная инструкция называется оператором. Каждый
оператор должен заканчиваться точкой с запятой.
Заключительный оператор в функции main(), называется оператором возврата, завершает функцию.
Что такое return 0? Дело в том, что иногда возникает необходимость запускать несколько команд в сложном
сочетании. Это делается с помощью скриптов командной оболочки (язык сценариев). Под Windows - bat-
файлы. Из сценария можно запустить программу на исполнение и посмотреть, какой результат она вернет
операционной системе. Например это может использоваться для контроля над ошибками. Если программа
вернет 0, то ошибка нет надо что-то сделать.
Теория и практика С++3
3
Заголовок функции в роли интерфейса
В общем случае функция С++ активизируется или вызывается другой функцией, а заголовок функции
описывает интерфейс между нею и той функцией, которая ее вызывает. Слово, стоящее перед именем функции,
называется возвращаемым типом функции; оно описывает информацию, передаваемую из функции обратно в ту
функцию, которая ее вызывала. Информация в круглых скобках, следующих за именем функции, называется
списком аргументов или списком параметров. Этот список содержит описание информации, передаваемой из
вызывающей в вызываемую функцию.
Препроцессор C++ и файл iostream
#include <iostream> //директива препроцессора
В языке C++, как и в С, используется препроцессор. Препроцессор — это программа, которая выполняет
обработку файла исходного кода перед началом собственно компиляции.
Эта директива заставляет препроцессор добавить содержимое файла iostream в вашу программу. Добавление
или замена текста в исходном коде перед его компиляцией является одним из обычных действий препроцессора.
Имена заголовочных файлов
Файлы, такие как iostream, называются заголовочными (поскольку они включаются в начало файла).
Заголовочные файлы имеют расширение h и содержат прототипы функций.
Пространства имен
using namespace std; //включает в программу определения
Это называется директивой using. Сейчас самое главное — просто запомнить ее.
Поддержка пространства имен — это средство C++, предназначенное для упрощения разработки крупных
программ и программ, в которых комбинируется существующий код от нескольких поставщиков, а также для
помощи в организации таких программ. Одна из потенциальных проблем заключается в том, что вы можете
работать с двумя готовыми продуктами, в каждом из которых присутствует, скажем, функция f1(). При
использовании функции f1() компилятор не будет знать, какая конкретно версия этой функции имеется в виду.
Средство пространств имен позволяет поставщику упаковать свой продукт в модуль, называемый
пространством имен. Вы, в свою очередь, можете использовать название этого пространства имен для
указания, продукт какого производителя вам необходим. Так, например, компания Micro может поместить свои
определения в пространство имен Micro. Тогда полное имя. функции f1() будет выглядеть как Micro::f1().
Аналогично, Macro::f1() может обозначать версию функции f1() от компании Macro.
Комментарии
Комментарии обозначаются двойной наклонной чертой (//). Комментарий – это написанное программистом
примечание, которое предназначается для тех, кто будет изучать эту программу.
Вывод данных с использованием объекта cout
cout << "Come up and C++ me some time.";
Информация, заключенная в двойные кавычки, является сообщением, которое должно быть выведено на
экран. Любая последовательность символов, заключенная в двойные кавычки, называется строкой символов.
Обозначение << указывает на то, что этот оператор отправляет данную строку в объект cout. cout -
предопределенный объект, способный отображать на экране разнообразные данные – строки, числа и отдельные
числа.
Символ новой строки
cout << "n";
Комбинация символов n является специальной формой записи важного понятия, называемого символом
новой строки. Символ новой строки перемещает курсор на начало новой строки. Его можно комбинировать со
строкой символов.
cout << "Come up and C++ me some time.n";
Теория и практика С++4
4
Стиль форматирования исходного кода программ
1. В строке присутствует один оператор
2. Открывающая и закрывающая фигурные скобки для функции располагаются каждая в отдельной строке
3. Операторы тела функции располагаются с отступом от фигурных скобок
4. Символы пробела не ставятся с обеих сторон круглых скобок, следующих за именем функции
Дополнительные сведения об операторах
Программа представляет собой совокупность функций, а каждая функция – это совокупность операторов.
Программа 1_2
//программа p1_2.cpp - отображает на экране значение переменной
#include <iostream>
using namespace std;
void main()
{
int fleas; //создает целочисленную переменную
fleas = 38; //присваивает этой переменной значение
cout << "My cat has ";
cout << fleas; //отображает на экране значение переменной fleas
cout << " fleas.n";
system("pause");
}
Результат:
My cat has 38 fleas.
В программе 1_2 содержатся два новых вида операторов. Во-первых, оператор объявления создает
переменную. Во-вторых, оператор присваивания присваивает этой переменной некоторое значение.
Результат выполнения программы:
My cat has 38 fleas.
Операторы объявления и переменные
Для хранения в ПК какого-либо элемента информации необходимо указать, в каком месте памяти он будет
храниться, а также объем области памяти, требуемой для его хранения. Это можно сделать при помощи
оператора объявления. Например:
int fleas;
Тип хранимой информации определяется словом int, который соответствует целому числу
(положительные и отрицательные числа). Для идентификации области памяти в которой будет хранится
значение используется слово fleas. Поскольку это значение может изменяться, fleas называется переменной.
Оператор присваивания
Оператор присваивания присваивает значение некоторой области памяти. Например:
fleas = 38;
Операцию присваивания можно использовать последовательно. Например:
int x;
int y;
int z;
x = y = z = 88;
ВВОД ДАННЫХ
Программа 1_3
// ввод и вывод
#include <iostream>
using namespace std;
Теория и практика С++5
5
void main()
{
int fleas;
cout << "How many fleas does your cat have?n";
cin >> fleas; //ввод в программу С++
//следующая строка объединяет выводимые данные
cout << "Well, that's " << fleas << " fleas too many!n";
system("pause");
}
Результат:
How many fleas does your cat have?
112
Well, that's 112 fleas too many!
Ввод данных в программу осуществляется при помощи объекта cin.
ФУНКЦИИ
Имеются две разновидности функций: функции с возвращаемыми значениями и без них.
Применение функций с возвращаемым значением
Функция с возвращаемым значением в результате своей работы выдает значение, которое можно присвоить
переменной. Например функция sqrt(), возвращает квадратный корень числа.
x = sqrt(6.25); //возвращает значение 2.5 и присваивает его переменной x
Выражение sqrt(6.25) вызывает функцию sqrt(). Выражение sqrt(6.25) называется вызовом
функции, сама функция называется вызываемой, а функция, в которой находится вызов функции, называется
вызывающей.
Значение в круглых скобках ( в данном случае 6.25) представляет собой информацию, которая передается в
функцию. Это значение называется аргументом или параметром. Функция sqrt() вычисляет результат,
который будет равным 2,5, и отправляет это значение обратно вызывающей функции. Это отправляемое
значение называется возвращаемым значением функции.
Перед тем, как использовать функцию, компилятор С++ должен знать типы аргументов и возвращаем ого
значения функции. Эта информация передается компилятору с помощью прототипа функции.
ПОМНИТЕ
В программе С++ для каждой используемой функции должен быть прототип.
Прототип функции информирует программу о типахданных.
Прототип функции sqrt() выглядит так:
double sqrt(double); //прототип функции
Первое ключевое слово double означает, что функция sqrt() возвращает значение типа double.
Ключевое слово double в круглых скобках означает, что функции sqrt() необходим аргумент типа double.
Если в программе применяется функция sqrt(), необходимо включить в код ее прототип. Это можно
обеспечить двумя способами:
 Вручную ввести прототип функции в исходных код программы.
 Включить в программу заголовочный файл cmath, который содержит прототип этой функции.
Итак, прототип описывает информацию, посылаемую в функцию и из функции. А определение функции
содержит код функции.
Прототип функции должен находиться в программе до того места, где функция применяется впервые.
Программа 1_4
// использование функции sqrt()
#include <iostream>
using namespace std;
#include <cmath>
void main()
{
double cover; //использовать вещественные числа типа double
cout << "How many square feet of sheets do you have?n";
Теория и практика С++6
6
cin >> cover;
double side; //создать еще одну переменную
side = sqrt(cover); //вызвать функцию и присвоить возвращаемое значение переменной
cout << "You can cover a square with sides of " << side;
cout << "nfeet with your sheets.n";
}
Результат:
"How many square feet of sheets do you have?
123.21
You can cover a square with sides of 11.1
feet with your sheets.
Разновидности функций
Некоторым функциям требует более одного элемента информации. Эти функции используют несколько
аргументов, разделяемых запятыми. Например прототип функции pow():
double pow(double, double); //прототип функции с двумя аргументами
Пример использования функции:
answer = pow(5.0, 8.0); //вызов функции со списком аргументов
Пример прототипа функции, которая не принимает аргументов:
int rand(void); //прототип функции, не принимающей аргументов
Пример использования функции без аргументов:
myGuess = rand(); //вызов функции, не имеющей аргументов
Пример прототипа функции, которая не возвращает значения:
void bucks(double); //прототип функции, не имеющей возвращаемого значения
Пример использования функции bucks():
bucks(1234.56); //вызов функции, возвращаемое значение отсутствует
Функции, определяемые пользователем
Для пользовательской функции необходимо поместить прототип функции до ее вызова (обычно перед
функцией main()), а также необходимо написать исходный код определяемой функции.
Программа 1_5
//программа p1_5.cpp - определение собственной функции
#include <iostream>
using namespace std;
void simon(int); //прототип функции simon()
void main()
{
simon(3); //вызов функции simon()
cout << "Pick an integer: ";
int count;
cin >> count;
simon(count); //повторный вызов этой функции
}
void simon(int n) //определение функции simon()
{
cout << "Simon says touch your toes " << n << " times.n";
} //в функциях без возвращаемого значения не требуется оператор return
Результат:
Simon says touch your toes 3 times.
Pick an integer: 512
Simon says touch your toes 512 times.
Теория и практика С++7
7
Формат определения функции
Сначала идет заголовок функции, затем следует тело функции, заключенное в фигурные скобки. В общем
случае формат следующий:
тип имя_функции(список_аргументов)
{
операторы
}
ОПРЕДЕЛЯЕМАЯ ПОЛЬЗОВАТЕЛЕМ ФУНКЦИЯ С ВОЗВРАЩАЕМЫМ
ЗНАЧЕНИЕМ
Программа 1_6
//программа p1_6.cpp - преобразование стоунов в фунты
#include <iostream>
using namespace std;
int stonetolb(int); //прототип функции
void main()
{
int stone;
cout << "Enter the weight in stone: ";
cin >> stone;
int pounds=stonetolb(stone);
cout << stone << " stone are ";
cout << pounds << " pounds.n";
}
int stonetolb(int sts)
{
return 14 * sts;
}
Результат:
Enter the weight in stone: 14
14 stone are 196 pounds.
ВОПРОСЫ ДЛЯ ПОВТОРЕНИЯ (1)
1. Какой оператор следует использовать, чтобы вывести фразу "Hello, world" и перейти на начало строки?
2. Какой оператор следует использовать, чтобы создать целочисленную переменную с именем cheese?
3. Какой оператор следует использовать, чтобы присвоить переменной cheeses значение 32?
4. Какой оператор следует использовать для ввода значения с клавиатуры и присвоения его переменной
cheeses?
5. Какой оператор следует использовать для вывода предложения "We have X varieties of cheese",
где буква Х будет заменяться текущим значением переменной cheeses?
6. Какую информацию о функции дает следующий заголовок функции:
int froop(double t)
7. В каком случае при определении функции не используется ключевое слово return?
УПРАЖНЕНИЯ ПО ПРОГРАММИРОВАНИЮ (1)
1. Напишите программу, которая отображает на экране ваше имя и адрес.
2. Напишите программу, которая запрашивает расстояние в сантиметрах и преобразует его в миллиметры.
3. Напишите программу, которая состоит из двух определяемых пользователем функций и выводит на экран
следующие данные:
Three blind mice
Three blind mice
See how they run
See how they run
Теория и практика С++8
8
Одна функция, вызываемая дважды, должна отображать две первые строки, а другая, также вызываемая
дважды, должна отображать остальные выходные данные.
4. Напишите программу, в которой функция main() вызывает определяемую пользователем функцию,
принимающую в качестве аргумента значение температуры в градусах по Цельсию и возвращающую
эквивалентное значение в градусах по Фаренгейту. По запросу программы температуру в градусах Цельсия
вводит пользователь. Затем программа отображает результат. Данные, выводимые на экран, имеют
следующий вид:
Please enter a Celsius value: 20
20 degrees Celsius is 68 degrees Fahrenheit.
Для справок: формула для выполнения преобразования:
Fahrenheit = 1.8 x Celsius + 32.0
5. Напишите программу, в которой функция main() вызывает определяемую пользователем функцию. Эта
функция принимает значение расстояния в световых годах и возвращает расстояние в астрономических
единицах. Программа должна запрашивать ввод значения в световых годах и отображать результат, как
показано в следующем примере:
Enter the number of light years: 4.2
4.2 light are 265608 astronomical units
Для дробных чисел используйте тип double и следующую формулу преобразования:
1 световой год = 63240 астрономических единиц
2. Представление данных переменными
Существует две группы типов данных: базовые и составные, или производные. Базовые типы данных служат
для представления целых чисел и чисел с плавающей точкой.
Имена переменных
Для переменных рекомендуется выбирать имена, отражающие их назначение.
Существует несколько простых правил именования, которые обязательны для применения:
 В именах можно использовать только следующие символы: буквы алфавита, цифры и символ
подчеркивания (_).
 Первый символ имени не может быть цифрой.
 Символы верхнего и нижнего регистров рассматриваются как разные.
 В качестве имен нельзя использовать ключевые слова языка С++.
 Имена, начинающие с двух символов подчеркивания или с символа подчеркивания и следующей за ним
буквы в верхнем регистре, зарезервированы для использования реализацией языка. Имена,
начинающиеся с одного символа подчеркивания, зарезервированы реализацией языка в качестве
глобальных идентификаторов.
 В языке С++ на длину имени не накладывается никаких ограничений, т.е. учитывается каждый символ.
Примеры допустимых и недопустимых имен С++:
int poodle; //допустимое
int Poodle; //допустимое и отличное от имени poodle
int POODLE; //допустимое и еще более отличное от имени poodle
Int terrier; //недопустимое – должно быть ключевое слово int, а не Int
int my_stars3; //допустимое
int _Mystars3; //допустимое, но зарезервировано – начинается с символа
//подчеркивания
int 4ever; //недопустимое, так как начинается с цифры
int double; //недопустимое – double является ключевым словом С++
int begin; //допустимое
int __fools; //допустимое, но зарезервированное – начинается с двух
//символов подчеркивания
int the_very_best_variable_i_can_be_version_112;
//допустимое
int honky-tonk; //недопустимое – дефис не допускается
Целочисленные типы данных
Теория и практика С++9
9
Целые числа – это числа без дробной части.
В языке С++ различные типы данных различаются по объему памяти, используемому для их хранения.
Большой блок памяти может представлять большой диапазон целых чисел. Кроме того, одни типы данных )со
знаком) могут представлять и положительные, и отрицательные значения, тогда как другие типы данных (без
знака) не могут представлять отрицательные значения. Для описания объема памяти, используемого для
хранения целочисленного значения, обычно применяют термин размерность. Чем больше памяти отводится для
хранения значения, тем больше го размерность. Базовые типы целочисленных данных языка С++ (в порядке
размерности) именуются char, short, int и long. Каждый их этих типов данных подразделяется на две
разновидности: со знаком и без знака. В результате имеется набор из восьми различных типов целочисленных
данных.
Типы данных short, int и long
Размерность – это количество битов или разрядов.
 Размерность данных типа short не меньше 16 разрядов.
 Размерность данных типа int не меньше размерности данных типа short.
 Размерность данных типа long не меньше 32 разрядов и не меньше размерности данных типа int.
Примеры объявления переменных:
short score;
int temperature;
long position;
Следующая программа позволяет узнать размерность целых типов в конкретной системе.
Программа 2_1
//программа p2_1.cpp - предельные значения целочисленных типов данных
#include <iostream>
using namespace std;
#include <climits>
void main()
{
//оператор sizeof возвращает размерность типа данных или переменной
cout << "short is " << sizeof(short) << " bytes.n";
cout << "int is " << sizeof(int) << " bytes.n";
cout << "long is " << sizeof(long) << " bytes.nn";
//максимальное значение
cout << "Maximum value:n";
cout << "short: " << SHRT_MAX << "n";
cout << "int: " << INT_MAX << "n";
cout << "long: " << LONG_MAX << "nn";
//минимальное значение
cout << "Minimum value:n";
cout << "short: " << SHRT_MIN << "n";
cout << "int: " << INT_MIN << "n";
cout << "long: " << LONG_MIN << "nn";
//максимальное значение безнаковых типов
cout << "Maximum unsigned value:n";
cout << "unsigned short: " << USHRT_MAX << "n";
cout << "unsigned int: " << UINT_MAX << "n";
cout << "unsigned long: " << ULONG_MAX << "n";
}
Результат:
short is 2 bytes.
int is 4 bytes.
long is 4 bytes.
Maximum value:
short: 32767
int: 2147483647
long: 2147483647
Теория и практика С++10
10
Minimum value:
short: -32768
int: -2147483648
long: -2147483648
Maximum unsigned value:
unsigned short: 65535
unsigned int: 4294967295
unsigned long: 4294967295
ТИПЫ ДАННЫХ БЕЗ ЗНАКА
В программе 2_2 иллюстрируется использование беззнаковых типов данных. В ней также показано, что
может произойти, если в программе будет предпринята попытка выйти за границы диапазона возможных
значений для целочисленных данных какого-либо типа. И здесь вы можете увидеть директиву препроцессора
#define, которая дает команду заменить в программе все имена ZERO числами 0.
Программа 2_2
// предельные значения целочисленных типов данных
#include <iostream>
using namespace std;
int main()
{
const int ZERO = 0;
short sam = SHRT_MAX;
unsigned short sue = sam;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited.nAdd $1 to each account.nNow ";
sam = sam + 1;
sue = sue + 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited.nPoor Sam!n";
sam = ZERO;
sue = ZERO;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited.n";
cout << "Take $1 from each account.nNow ";
sam = sam - 1;
sue = sue - 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited.nLucky Sue!n";
}
Результат:
Sam has 32767 dollars and Sue has 32767 dollars deposited.
Add $1 to each account.
Now Sam has -32768 dollars and Sue has 32768 dollars deposited.
Poor Sam!
Sam has 0 dollars and Sue has 0 dollars deposited.
Take $1 from each account.
Now Sam has -1 dollars and Sue has 65535 dollars deposited.
Lucky Sue!
Целочисленная константа
Целочисленная константа – это константа, записываемая явно, например 212 или 1776. В языке С++
целочисленные константы могут записываться в трех системах счисления: десятичная, восьмеричная и
шестнадцатеричная. Правила записи чисел в различных системах счисления следующие. Если первая цифра
находится в диапазоне 1-9, то число является десятичным. Если первая цифра равна 0, а вторая находится в
диапазоне от 1 до 7, то число является восьмеричным. Если первые два символа – 0х или 0Х, то речь идет о
шестнадцатеричном числе.
Программа 2_3
// демонстрирует использование шестнадцатеричных / восьмеричных констант
Теория и практика С++11
11
#include <iostream>
using namespace std;
void main()
{
int chest = 42; //десятичная целочисленная константа
int waist = 0x42; //шестнадцатеричная целочисленная константа
int inseam = 042; //восьмеричная целочисленная константа
cout << "Monsieur cuts a striking figure!n";
cout << "chest = " << chest << "n";
cout << "waist = " << waist << "n";
cout << "inseam = " << inseam << "n";
}
Результат:
Monsieur cuts a striking figure!
chest = 42
waist = 66
inseam = 34
По умолчанию объект cout отображает целые числа в десятичном виде, независимо от того, как они
записаны в программе.
Тип данных char: символы и малые целые числа
Программа 2_4
// предельные значения типа данных char
#include <iostream>
using namespace std;
#include <climits>
void main()
{
//оператор sizeof возвращает размерность типа данных или переменной
cout << "char is " << sizeof(char) << " bytes.n";
//максимальное значение
cout << "Maximum value:n";
cout << "char: " << CHAR_MAX << "n";
//минимальное значение
cout << "Minimum value:n";
cout << "char: " << CHAR_MIN << "n";
//максимальное значение безнаковых типов
cout << "Maximum unsigned value:n";
cout << "unsigned char: " << UCHAR_MAX << "n";
}
Тип данных char также предназначен для хранения одного символа из следующей таблицы
0 · 32 [пробел] 64 @ 96 ` 128 · 160 [пробел] 192 А 224 а
1 · 33 ! 65 A 97 a 129 · 161 Ў 193 Б 225 б
2 · 34 " 66 B 98 b 130 · 162 ў 194 В 226 в
3 · 35 # 67 C 99 c 131 · 163 Ј 195 Г 227 г
4 · 36 $ 68 D 100 d 132 · 164 ¤ 196 Д 228 д
5 · 37 % 69 E 101 e 133 · 165 Ґ 197 Е 229 е
6 · 38 & 70 F 102 f 134 · 166 ¦ 198 Ж 230 ж
7 · 39 ' 71 G 103 g 135 · 167 § 199 З 231 з
8 * * 40 ( 72 H 104 h 136 · 168 Ё 200 И 232 и
9 * * 41 ) 73 I 105 i 137 · 169 © 201 Й 233 й
10 * * 42 * 74 J 106 j 138 · 170 Є 202 К 234 к
11 · 43 + 75 K 107 k 139 · 171 « 203 Л 235 л
12 · 44 , 76 L 108 l 140 · 172 ¬ 204 М 236 м
13 * * 45 - 77 M 109 m 141 · 173 - 205 Н 237 н
14 · 46 . 78 N 110 n 142 · 174 ® 206 О 238 о
15 · 47 / 79 O 111 o 143 · 175 Ї 207 П 239 п
16 · 48 0 80 P 112 p 144 · 176 ° 208 Р 240 р
Теория и практика С++12
12
17 · 49 1 81 Q 113 q 145 ‘ 177 ± 209 С 241 с
18 · 50 2 82 R 114 r 146 ’ 178 І 210 Т 242 т
19 · 51 3 83 S 115 s 147 · 179 і 211 У 243 у
20 · 52 4 84 T 116 t 148 · 180 ґ 212 Ф 244 ф
21 · 53 5 85 U 117 u 149 · 181 µ 213 Х 245 х
22 · 54 6 86 V 118 v 150 · 182 ¶ 214 Ц 246 ц
23 · 55 7 87 W 119 w 151 · 183 · 215 Ч 247 ч
24 · 56 8 88 X 120 x 152 · 184 ё 216 Ш 248 ш
25 · 57 9 89 Y 121 y 153 · 185 № 217 Щ 249 щ
26 · 58 : 90 Z 122 z 154 · 186 є 218 Ъ 250 ъ
27 · 59 ; 91 [ 123 { 155 · 187 » 219 Ы 251 ы
28 · 60 < 92  124 | 156 · 188 ј 220 Ь 252 ь
29 · 61 = 93 ] 125 } 157 · 189 Ѕ 221 Э 253 э
30 · 62 > 94 ^ 126 ~ 158 · 190 ѕ 222 Ю 254 ю
31 · 63 ? 95 _ 127 · 159 · 191 ї 223 Я 255 я
Применение данных типа char демонстрируется в программе 2_5.
Программа 2_5
// применение данных типа char
#include <iostream>
using namespace std;
void main()
{
char ch;
cout << "Enter a character:n";
cin >> ch;
cout << "Holla! ";
cout << "Thank you for the " << ch << " character.n";
}
Результат:
Enter a character:
M
Holla! Thank you for the M character.
Программа 2_6
// сопоставление данных типа char и int
#include <iostream>
using namespace std;
void main()
{
char c = 'M'; //переменной с присваивается ASCII-код символа М
int i = c; //тот же код сохраняется в переменной типа int
cout << "The ASCII code for " << c << " is " << i << "n";
cout << "Add one to the character code:n";
c = c + 1;
i = c;
cout << "The ASCII code for " << c << " is " << i << "n";
cout << "nDonen";
}
В этой программе показано, как определяются символьные константы: символ заключается в одинарные
кавычки, например 'M'.
Коды управляющих последовательностей в языке С++
Имя символа Код С++ Имя символа Код С++
Новая строка n Сигнал a
Горизонтальная
табуляция
t Обратная наклонная
черта

Вертикальная табуляция v Вопросительный знак ?
Возврат на одну позицию b Одинарная кавычка '
Теория и практика С++13
13
Возврат каретки r Двойная кавычка "
Программа 2_7
// использование управляющих последовательностей
#include <iostream>
using namespace std;
void main()
{
cout << "aOperation "HyperHype" is now activated!n";
cout << "Enter your agent code:________bbbbbbbb";
long code;
cin >> code;
cout << "aYou entered " << code << "...n";
cout << "aCode verified! Proceed with Plan Z3!n";
}
Результат:
Operation "HyperHype" is now activated!
Enter your agent code:007_____
You entered 7...
Code verified! Proceed with Plan Z3!
Тип данных bool
Переменная Boolean – это переменная, которая может принимать два значения: true (истина) или false
(ложь). Также необходимо учитывать, что ненулевые значения интерпретируются как значения true, а нулевые
значения – как значения false.
Примеры:
bool isready = true;
Литералы true и false могут быть преобразованы в данные типа int путем повышения типа, при этом
значение true преобразуется в 1, а false – в 0:
int ans = true; //переменной ans присваивается значение 1
int promise = false; // переменной promise присваивается значение 0
Кроме того, любое числовое значение может быть преобразовано в значение типа bool неявно. Любое
ненулевое значение преобразуется в значение true, а нулевое – в значение false:
bool start = -100; //переменной start присваивается значение true
bool stop = 0; //переменной stop присваивается значение false;
Квалификатор const
Для создания константы используется ключевое слово const:
const int MONTH = 12;
Обратите внимание: инициализация константы осуществляется вместе с ее объявлением. Следующая
последовательность операторов некорректна:
const int toes; //в этом операторе значение константы toes не определено
toes = 10; //слишком поздно!
Типы данных с плавающей точкой
Предусмотрено три типа данных с плавающей точкой: float, double и long double.
Размерность данных с плавающей точкой:
float – минимум 32 разряда;
double – минимум 48 разрядов;
long double – 80, 96 или 128 разрядов.
Арифметические операции
Имеются пять основных арифметических операции: сложение (+), вычитание (-), умножение (*), деление (/) и
деление по модулю (%) (получение остатка от деления). В каждой из этих операций используются два числа
(называемых операндами).
Теория и практика С++14
14
Разновидности операции деления
Если оба операнда являются целыми числами, то выполняется операция деления целых чисел. Это означает,
что любая дробная часть результата отбрасывается, и результат становится целым числом. Если оба или один из
операндов – числа с плавающей точкой, то дробная часть результат сохраняется и результат будет числом с
плавающей точкой.
Где объявляются переменные
Как правило, переменные объявляют в трех местах: внутри функций, в определении параметров функции и
за пределами всех функций. Соответственно такие переменные называются локальными, формальными
параметрами и глобальными.
Локальные переменные
Переменные, объявленные внутри функции, называются локальными. Локальные переменные можно
использовать только в операторах, расположенных внутри блока, где они объявлены. Иначе говоря, локальные
переменные невидимы снаружи их блока. Напомним, что блок ограничен открывающей и закрывающей
фигурными скобками.
Чаще всего локальные переменные объявляются внутри функций. Рассмотрим два примера.
void func1(void)
{
int x;
x = 10;
}
void func2(void)
{
int x;
x = -199;
}
Переменная x объявлена дважды: сначала — в функции func1(), а затем — в функции func2(). Переменная
х из функции func1() не имеет никакого отношения к переменной x, объявленной внутри функции func2().
Каждая из этих переменных существует только внутри блока, где она была объявлена.
Из соображений удобства и по традиции большинство программистов объявляют переменные; используемые
в функции, сразу после открывающей фигурной и перед всеми остальными операторами. Однако следует иметь
в виду, что локальные переменные можно объявлять в любом месте блока.
Локальную переменную можно проинициализировать неким значением. Оно будет присваиваться
переменной каждый раз при входе в блок. Рассмотрим в качестве мера программу, которая десять раз выводит
на печать число 10.
Программа 2_8
// присвоение значение переменной во время объявления
#include <iostream>
using namespace std;
void f();
int main()
{
int i;
f();
f();
f();
}
void f()
{
int j = 3;
cout << j << " ";
j = j + 1; // Этот оператор не имеет долговременного эффекта.
}
Теория и практика С++15
15
Формальные параметры
Если функция имеет аргументы, следует объявить переменные, которые будут принимать их значения. Эти
переменные называются формальными параметрами. Внутри функции они ничем не отличаются от других
локальных переменных. Как показано в приведенном ниже фрагменте программы, объявление таких
переменных должно размещаться сразу после имени функции и заключаться в скобки.
/* Функция возвращает 1, если символ с является частью строки s; в противном случае она возвращает0 */
int is_in(char *s, char с)
{
while(*s)
if(*s == c) return 1;
else s++;
return 0;
}
Функция is_in() имеет два параметра: вис. Она возвращает 1, если символ с является частью строки s, в
противном случае функция возвращает 0.
Тип формальных параметров задается при их объявлении. После этого их можно использовать как обычные
локальные переменные. Учтите, что, как и локальные переменные, формальные параметры являются
динамическими и разрушаются при выходе из функции.
Глобальные переменные
В отличие от локальных, глобальные переменные доступны из любой части программы и могут быть
использованы где угодно. Кроме того, они сохраняют свои значения на всем протяжении выполнения
программы. Объявления глобальных переменных должны размещаться вне всех функций. Эти переменные
можно использовать в любом выражении, в каком бы блоке оно не находилось.
В приведенном ниже фрагменте программы переменная count объявлена вне функций. Несмотря на то что
ее объявление расположено до функции main(), переменную можно было бы с таким же успехом объявить в
другом месте, но вне функций и до ее первого использования. И все же лучше всего размещать объявление
глобальных переменных в самом начале программы.
Программа 2_9
// глобальные переменные
#include <iostream>
using namespace std;
int count; /* Переменнная count является глобальной */
void func1();
void func2();
void main()
{
count = 100;
func1();
}
void func1(void)
{
int temp;
temp = count;
func2();
cout << "count = " << count << "n"; /* Выведет число 100. */
}
void func2(void)
{
int count;
for(count=1; count<10; count++)
cout << '.';
}Результат:
Теория и практика С++16
16
. . . . . . . . . .count = 100
Присмотритесь к этой программе повнимательнее. Заметьте, что, хотя ни функция main(), ни функция
func1() не содержат объявления переменной count, обе эти функции успешно ее используют. Однако внутри
функции func2() объявлена локальная переменная count. Когда функция func2() ссылается на
переменную count она использует лишь локальную переменную, а не глобальную. Если глобальная и
локальная переменные имеют одинаковые имена, то все ссылки на имя переменной внутри блока будут
относиться к локальной переменной и не влиять на ее глобальную тезку. Возможно, это удобно, однако об этой
особенности легко забыть, и тогда действия программы могут стать непредсказуемыми.
ВОПРОСЫ ДЛЯ ПОВТОРЕНИЯ (2)
1. Определите следующие переменные:
a. Типа short со значением 80
b. Типа unsigned int со значением 42110
c. Целочисленного типа со значением 3 000 000 000
2. Эквивалентны ли следующие операторы
char grade = 65;
char grade = 'A';
3. Как с помощью программы найти, какому символу соответствует код 88?
УПРАЖНЕНИЯ ПО ПРОГРАММИРОВАНИЮ (2)
1. Напишите программу, которая запрашивает рост в сантиметрах, а затем выражает его в метрах и
сантиметрах. Пусть в программе используется символ подчеркивания, чтобы указать место, где вводить
ответ.
Результат:
Enter your height in cm: 182
Your height: 1 m 82 cm
2. Напишите программу, которая запрашивает ваш рост в метрах и ваш вес в килограммах (для хранения этой
информации используйте две переменные). Пусть программа вычислит и отобразит на экране ваш ИМТ
(индекс массы тела). Чтобы вычислить ИМТ необходимо разделить вес в килограммах на рост в метрах,
возведенный в квадрат
Результат:
Enter your height in m: 1.82
Enter your weight in kg: 70
Your IMT = 21.1327
3. Напишите программу, которая запрашивает длину пути, который вы проехали, в километрах и количество
израсходованных литров бензина, а затем отображает на экране значение, показывающее, расход бензина в
литрах на 100 километров.
Результат:
Enter km: 250
Enter litre: 20
The charge on 100 km = 8
3. Составные типы данных
Составные типы данных формируются на основе базовых целочисленных типов и типов с плавающей
точкой. Это классы, указатели, структуры и массивы.
Массивы
Массив представляет собой набор переменных с одним именем и разными индексами. Каждая такая
переменная называется элементом массива. Количество хранящихся в массиве элементов называется размером
массива. Все элементы массива имеют одинаковый тип.
Объявление массива должно содержать три аргумента:
 тип каждого элемента
 имя массива
 количество элементов в массиве
например:
Теория и практика С++17
17
short months[12]; //создает массив с именем months, из 12 элементов типа short
Общая форма записи для объявления массива выглядит так:
typeName arrayName[arraySize];
Выражение arraySize, которое задает количество элементов, должно быть константой, и не может быть
переменной.
Программа 3_1
// программа p3_1.cpp - небольшие массивы целых чисел
#include <iostream>
using namespace std;
void main()
{
int yams[3]; //создается массив из трех элементов
yams[0] = 7; //присвоение значения первому элементу
yams[1] = 8;
yams[2] = 6;
int yamcosts[3] = {20, 30, 5}; //создание и инициализация массива
cout << "Total yams = ";
cout << yams[0] + yams[2] + yams[3] << "n";
cout << "The package with " << yams[1] << " yams costs ";
cout << yamcosts[1] << " center per yam.n";
int total = yams[0] * yamcosts[0] + yams[1] * yamcosts[1];
total = total + yams[2] * yamcosts[2];
cout << "The total yam expense is " << total << " cents.n";
cout << "Size of yams array = " << sizeof yams << " bytes.n";
cout << "Size of one element = " << sizeof yams[0] << " bytes.n";
}
Результат:
Total yams = 14
The package with 8 yams costs 30 center per yam.
The total yam expense is 410 cents.
Size of yams array = 12 bytes.
Size of one element = 4 bytes.
Правила инициализации массивов
Форму инициализации массива можно использовать только при определении массива. После этого
применять ее нельзя, нельзя также целиком присвоить один массив другому:
int cards[4] = {3, 6, 8, 10}; //допустимо
int hand[4]; //допустимо
hand[4] = {5, 6, 7, 9}; //недопустимо
hand = cards; //недопустимо
Однако можно, используя индексы, присваивать значения элементам массива индивидуально.
Если массив инициализируется частично, то транслятор устанавливает для оставшихся элементов нулевые
значения. Таким образом, можно легко присвоить всем элементам массива нуль – нужно лишь явно присвоить
нуль первому элементу и предоставить компилятору инициализировать оставшиеся элементы:
float totals[500] = {0};
Строки
Строка – это ряд символов, хранящихся в последовательно расположенных байтах памяти. Строки имеют
одну особенность: последний символ каждой строки – нулевой символ. Это символ, имеющий нулевой код
ASCII (записывается как 0); он служит для обозначения конца строки.
char dog[5] = {'b', 'e', 'a', 'u', 'x'}; //не строка!
char cat[5] = {'f', 'a', 't', 's', '0'}; //строка
Оба массива являются массивами символов, но только второй из них – строка. В строках нулевой символ
играет фундаментальную роль. С++ имеет много функций, которые обрабатывают строки. Их работа строится
по единому принципу: функция обрабатывает строку посимвольно до достижения нулевого символа.
Теория и практика С++18
18
Имеется более лучший способ присвоения строки символьному массиву. Нужно просто использовать строку
в кавычках, называемую строковой константой или строковым литералом.
char bird[10] = "Mr. Cheep"; //подразумевается символ 0 в конце
char fish[] = "Bubbles"; //предоставим компилятору определять размер массива
ПОМНИТЕ
Вычисляя минимальный размер массива, в который необходимо записать строку, не забывайте учитывать
и конечный нулевой символ.
Обратите внимание на то, что строковая константа (двойные кавычки) и символьная константа (одинарные
кавычки) не являются взаимозаменяемыми. Символьная константа, такая как 'S', является короткой записью
кода для символа. В системе ASCII запись 'S' – это просто другой способ записи числа 83. Таким образом,
оператор
char shirt_size = 'S'; //допустимо
присваивает значение 83 переменной shirt_size. При этом "S" представляет собой строку, состоящую из
двух символов, S и 0.
char shirt_size = "S"; //запрещенное смешение типов
Конкатенация строк
Любые две строковые константы, разделенные только пробельными символами (пробелами, знаками
табуляции и символами новой строки) автоматически объединяются в одну. Таким образом, все следующие
операторы вывода эквивалентны:
cout << "This is" " a map";
cout << "This is a map";
cout << "This is"
" a map";
Использование строк в массиве
Существует два наиболее распространенных способа записи строки в массив: первый – инициализация
массива строковой константой, второй – считывание в массив результатов ввода с клавиатуры или из файла. В
программе 3_2 используется функция стандартной библиотеки strlen(), чтобы узнать длину строки.
Стандартный заголовочный файл cstring обеспечивает объявление для этой и многих других функций,
связанных со строками.
Программа 3_2
// программа p3_2.cpp - сохранение строк в массиве
#include <iostream>
#include <cstring> //для функции strlen()
using namespace std;
void main()
{
const int Size = 15;
char name1[Size]; //пустой массив
char name2[Size] = "C++owboy"; //инициализация массива
cout << "Howdy! I'm " << name2;
cout << "! What's your name?n";
cin >> name1;
cout << "Well, " << name1 << ", your name has ";
cout << strlen(name1) << " letters and is storedn";
cout << "in am array of " << sizeof name1 << " bytes.n";
cout << "Your initial is " << name1[0] << ".n";
name2[3] = '0'; //нулевой символ
cout << "Here are the first 3 characters of my name: ";
cout << name2 << "n";
}
Результат:
Howdy! I'm C++owboy! What's your name?
Basicman
Теория и практика С++19
19
Well, Basicman, your name has 8 letters and is stored
in am array of 15 bytes.
Your initial is B.
Here are the first 3 characters of my name: C++
Проблемы при вводе строк
Программа 3_3
// программа p3_3.cpp - чтение более чем одной строки
#include "stdafx.h"
#include <iostream>
using namespace std;
void main()
{
setlocale(LC_CTYPE, "RUS");
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
cout << "Введите свое имя: ";
cin >> name;
cout << "Введите свой любимый десерт: ";
cin >> dessert;
cout << "У меня есть вкусный " << dessert;
cout << " для вас, " << name << ".n";
}
Результат:
Enter your name:
Alistar Dreeb
Enter your favorite dessert:
I have some delicious Dreeb for you, Alistar.
В программе с клавиатуры вводится имя пользователя и его любимый десерт, а затем отображается
информации.
Проблема заключается в том, что принцип работы cin основан на допущении, что для ограничения строки
используются пробельные символы. Это означает, что cin считывает только одно слово, когда он становится
входным для символьного массива, и помещает строку в массив, автоматически добавляя конечный нулевой
символ.
На практике у нас получается следующее: cin считает Alistar как полную первую строку и помещает ее в
массив name, а слово Dreeb остается в очереди ввода. Когда cin ищет очередь ввода для ответа на вопрос о
любимом десерте, то находит там слово Dreeb. Тогда cin, недолго думая, "проглатывает" Dreeb" и помещает
слово в массив dessert.
Следующая проблема заключается в следующем. cin не дает возможности предотвратить помещение 30-
символьной строки в 20-символьный массив
Ввод ориентированный на строки: функции getline()
Функция getline() читает целую строку, используя переданный с помощью клавиши ENTER символ
новой строки, чтобы пометить конец ввода. Для обращения к этому методу используется следующий вызов
функции: cin.getline(). Функция требует передачи двух параметров. Первый – имя массива,
предназначенного для сохранения введенной строки, а второй ограничивает количество символов, которые
нужно считать.
cin.getline(name,20);
Программа 3_4
// программа p3_4.cpp - чтение более одного слова с помощью функции getline
#include <iostream>
using namespace std;
void main()
{
Теория и практика С++20
20
setlocale(LC_CTYPE, "RUS");
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
cout << "Введите ваше имя: ";
cin.getline(name, ArSize); // читать до символа новой строки
cout << "Введите ваш любимый десерт: ";
cin.getline(dessert, ArSize);
cout << "У меня есть вкусный " << dessert;
cout << " для вас, " << name << ".n";
}
Результат:
Enter your name:
Dirk Hammernose
Enter your favorite dessert:
Ice-cream
I have some delicious Ice-cream for you, Dirk Hammernose.
Теперь программа читает полные имена и отображает для пользователя заказанные десерты! Функция
getline() воспринимает строку "в один присест". Она читает вводимые данные до конца символа новой
строки, который обозначает конец строки, однако не сохраняет его, а заменяет при сохранении строки нулевым
символом.
Смешанный ввод строк и чисел
Смешанный ввод строк и чисел с помощью ориентированный на строки функций может вызывать
затруднения.
Программа 3_5
// программа p3_5.cpp - чередование ввода чисел и строк
#include "stdafx.h"
#include <iostream>
using namespace std;
void main()
{
setlocale(LC_CTYPE, "RUS");
cout << "В каком году построен ваш дом? n";
int year;
cin >> year;
cout << "По какому адресу он расположен? n";
char address[80];
cin.getline(address, 80);
cout << "Год постройки: " << year << endl;
cout << "Адрес: " << address << endl;
cout << "Готово! n";
}
Результат:
What year was your house built?
1996
What is its street address?
Year built: 1996
Address:
Done!
При работе с данной программой пользователь никогда не получит возможности ввести адрес. Проблема
состоит в том, что объект cin, считав значение года, оставляет символ новой строки, сгенерированный с
помощью клавиши ENTER, во входной очереди. Затем функция cin.getline() воспринимает символ новой
строки так, как будто это пустая строка, и присваивает нулевую строку элементу массива address. Чтобы
исправить ошибку, следует считать и отбросить символ новой строки перед чтением адреса. Это можно сделать
при помощи функции cin.get().
Теория и практика С++21
21
cin >> year;
cin.get();
СТРУКТУРЫ
Структура – более универсальная форма данных, чем массив, поскольку может содержать элементы,
относящиеся к различным типам данных.
Структура – определяемый пользователем тип данных. Объявление структуры служит для того, чтобы
задавать свойства типов данных. После определения типа можно создавать переменные этого вновь созданного
типа. Таким образом, создание структуры предусматривает два этапа.
Сначала создается описание структуры. Затем можно создавать структурные переменные.
struct inflatable //описание структуры
{
char name[20]; //элемент типа array
float volume; //элемент типа float
double price; //элемент типа double
};
Ключевое слово struct указывает на то, что код определяет компоновку структуры. Идентификатор
inflatable – имя, или дескриптор, для этой формы. Таким образом, inflatable представляет собой имя
нового типа данных. Между фигурными скобками находится список типов данных, которые будут содержаться
в структуре. Каждый элемент списка – это оператор объявления. Каждый отдельный элемент в списке
называется элементом структуры.
Когда шаблон готов, можно создавать переменные данного типа:
inflatable hat; //hat - структурная переменная типа inflatable
inflatable woopie_cushion; //структурная переменная типа inflatable
inflatable mainfraim; //структурная переменная типа inflatable
Поскольку переменная hat имеет тип inflatable, для обращения к отдельным элементам можно
использовать оператор принадлежности (.). Например, выражение hat.volume указывает на элемент
volume структуры.
Программа 3_6
// программа p3_6.cpp - простая структура
#include <iostream>
using namespace std;
struct inflatable
{
char name[20];
float volume;
double price;
};
void main()
{
inflatable guest =
{
"Glorious Gloria",
1.88,
29.99
};
inflatable pal =
{
"Audacious Arthur",
3.12,
32.99
};
cout << "Expand your guest list with " << guest.name;
Теория и практика С++22
22
cout << " and " << pal.name << "!n";
cout << "You can have both for $";
cout << guest.price + pal.price << "!n";
}
Результат:
Expand your guest list with Glorious Gloria and Audacious Arthur!
You can have both for $62.98!
Примечание к программе
Существует один важный момент, который состоит в том, чтобы определить, где следует размещать
объявление структуры. Возможны два варианта. Первый (внутреннее объявление) – поместить объявление
структуры внутри функции main() сразу после отрывающей скобки. Второй (внешнее объявление) - поместить
объявление структуры перед функцией main(). Внешнее объявление может использовать всеми функциями,
следующими за main(), тогда как внутреннее объявление может быть использовано только той функцией, в
которой оно содержится.
Другие свойства структур
Можно передавать структуры функциям в качестве аргументов, а также использовать структуру, как
возвращаемое значение функции. Кроме того, допускается использование оператора присвоения (=), чтобы
присвоить значение одной структуры другой структуре того же типа. Данный вид операции называется
поэлементным присваиванием.
Программа 3_7
// программа p3_7.cpp - присвоение значений структурам
#include <iostream>
using namespace std;
struct inflatable
{
char name[20];
float volume;
double price;
};
void main()
{
inflatable bouquet =
{
"sunflowers",
0.20,
12.49
};
inflatable choice;
cout << "bouquet: " << bouquet.name << " for $";
cout << bouquet.price << "!n";
choice = bouquet; //присвоение значения одной структуры другой структуре
cout << "choice: " << choice.name << " for $";
cout << choice.price << "!n";
}
Результат:
bouquet: sunflowers for $12.49!
choice: sunflowers for $12.49!
Указатели и свободная память
Три фундаментальных свойства, которые должна учитывать компьютерная программа при сохранении
данных. Перечислим их:
 где хранится информация
 какое значение там, хранится
 вид хранящейся информации
Теория и практика С++23
23
Для реализации этих свойств использовался один из возможных методов — определение простой
переменной. Оператор объявления определяет тип и символическое имя значения, а также заставляет программу
выделить область памяти для значения и внутренними средствами отслеживать ее адрес.
Теперь рассмотрим второй метод. Он приобретает особое значение при разработке классов C++. Этот метод
основан на указателях, которые являются переменными, сохраняющими адреса значений вместо
непосредственно самих значений. Но прежде чем, рассматривать указатели, обратимся к способу явного
определения адресов обычных переменных. Этот способ заключается в применении к переменной операции
определения адреса, представленной знаком &. Например, если home – переменная, &home является ее
адресом.
Программа 3_8
// использование оператора & для определения адреса
#include <iostream>
using namespace std;
void main()
{
int donuts = 6;
double cups = 4.5;
cout << "donuts value = " << donuts;
cout << " and donuts address = " << &donuts << "n";
cout << "cups value = " << cups;
cout << " and cups address = " << &cups << "n";
}
Результат:
donuts value = 6 and donuts address = 0012FF7C
cups value = 4.5 and cups address = 0012FF74
При отображении адресов объект cout использует шестнадцатеричное представление, потому что оно
обычно применяется для записи адресов памяти. В нашей реализации значение переменной cups хранится в
ячейке памяти с меньшей величиной адреса по сравнению с переменной donuts. Разность между двумя
адресами составляет 8. Это имеет смысл, поскольку переменная cups имеет тип double, размерность которого
составляет восемь байта. Конечно, в разных системах значения адресов будут различными. Кроме того,
значение переменной donuts может предшествовать в памяти значению переменной cups. При этом разница
адресов будет составлять 8 байтов, поскольку переменная donuts имеет тип int.
Используя в таком случае обыкновенные переменные, можно обработать значение как именованную
величину, а его адрес как производную величину. Теперь ознакомимся с принципом использования указателей,
который занимает важное место в философии языка C++ относительно программного управления памятью.
В соответствии с новой стратегией обработки хранящихся в памяти данных местоположение значения
трактуется как именованная величина, а значение — как производная (порожденная) величина. Специальный
тип переменной – указатель – содержит адрес значения. Таким образом, имя указателя представляет
местонахождение значения в памяти. Применяя операцию *, называемую косвенным значением или операцией
разыменованием, получаем значение, хранящееся по данному адресу. Предположим, что manly – указатель.
Тогда выражение manly представляет собой адрес, а *manly – значение по данному адресу. Комбинация
*manly становится эквивалентом обычной переменной типа int. Эти моменты отражены в программе 3_9. Здесь
также показано, как объявлять указатель.
Программа 3_9
// наша первая переменная-указатель
#include <iostream>
using namespace std;
void main()
{
int updates = 6; //объявление переменной
int *p_updates; //объявление указателя на значением типа int
p_updates = &updates; //присвоение адреса значения типа int указателю
//выражения значений двумя способами
cout << "Values: updates = " << updates;
cout << ", *p_updates = " << *p_updates << "n";
//выражение адресов двумя способами
cout << "Addresses: &updates = " << &updates;
Теория и практика С++24
24
cout << ", p_updates = " << p_updates << "n";
//использование указателя для изменения значения
*p_updates = *p_updates + 1;
cout << "Now updates = " << updates << "n";
}
Результат:
Values: updates = 6, *p_updates = 6
Addresses: &updates = 0012FF7C, p_updates = 0012FF7C
Now updates = 7
Очевидно, что переменная updates типа int и переменная-указатель p_updates являются всего лишь
двумя сторонами одной и той же медали. Переменная updates представляет прежде всего значение, а
операция & используется для получения адреса, тогда как переменная p_updates представляет адрес, а
операция * служит для получения значения. Поскольку p_updates указывает на значение updates,
выражения *p_updates и updates совершенно эквиваленты. Выражение *p_updates можно использовать
точно так же, как переменную типа int. Как видно из программы, можно даже присваивать значения переменной
*p_updates. При этом изменяется указываемое значение переменной updates.
Объявление и инициализация указателей
Рассмотрим процесс объявления указателей. Компьютеру необходимо отслеживать тип значения, на которое
ссылается указатель. Например, адрес переменной типа char выглядит так же, как и адрес переменной типа
double, но для типов char и double используется различное количество байтов и различные внутренние
форматы для хранения значений. Поэтому при объявлении указателя необходимо точно определять, на какой
тип данных он указывает.
Последний пример содержит следующее объявление:
int *p_updates;
Это выражение указывает, что комбинация *p_updates принадлежит к типу int. Поскольку операция *
выполняется по отношению к указателю, переменная p_updates сама должна быть указателем. Мы говорим,
что p_updates указывает на значение типа int. Мы также говорим, что типом для p_updates должен быть
указатель на int или, более кратко, int *. Повторим: p_updates является указателем (адресом), a *p_updates —
переменной типа int, но не указателем (рис. 2).
int jumbo = 23;
int *pe = &jumbo;
эти выражения эквива-
лентны
эти выражения эквива-
лентны
jumbo
*pe
&jumbo
pe
значение
23
адрес
0x2ac8
Две стороны одной медали
Рисунок 1
1000
1002
1004
1006
1008
1010
1012
1014
1016
адрес в
памяти
имя
переменной
int ducks = 12;
ducks
birddog
12
1000
birddog
ducks
указывает
на
int *birddog = &ducks;
создает переменную
и сохраняет в ней
значение 12
ducks
создает переменную и
сохраняет в ней адрес
birddog
ducks
Рисунок 2
В указателях хранится адрес
Теория и практика С++25
25
Отметим, что отделять пробелами знак операции * не обязательно. Программисты, работающие на С,
традиционно применяют следующую форму записи:
int *ptr;
При использовании данной формы записи подчеркивается то, что комбинации *ptr имеет значение типа int.
Широко распространена и другая форма этого выражения:
int* ptr;
В ней акцентируется внимание на том, что int* — это тип "указатели на int". Компилятору же совершенно
безразлично, где будут размещены пробелы. Однако не следует упускать из виду, что, например, объявление
int* p1, p2;
создает один указатель (р1) и одну обычную переменную (р2), другими словами, необходимо использовать
знак * для каждого имени объявляемой переменной-указателя.
Для объявления указателей на другие типы переменных используется аналогичный синтаксис:
double *tax_ptr; // tax_ptr указывает на тип double
char *str; // str указывает на тип char
Поскольку tax_ptr объявляется как указатель на тип double, компилятор определяет, что значение *tax_ptr
принадлежит к типу double. Другими словами, он распознает, что *tax_ptr представляет собой величину,
которая хранится в формате с плавающей точкой и занимает (в большинстве систем) восемь байтов.
Переменная-указатель никогда не бывает просто указателем. Она всегда указывает на определенный тип
данных. Так, переменная tax_ptr имеет тип "указатель на тип double" (или тип double*), a str — "указатель на
тип char" (или char*). Несмотря на то, что обе переменные являются указателями, они указывают на два
различных типа данных. Подобно массивам, указатели являются производными от других типов данных.
Заметим, что в то время, как tax_ptr и str указывают на типы данных, имеющие различную размерность,
сами по себе две переменные — tax_ptr и str — имеют одинаковый размер. Иными словами, адрес переменной
типа char имеет тот же размер, что и адрес переменной типа double (точно так же, как номер дома 1016 может
означать адрес большого универмага, а 1024 — адрес маленького коттеджа). По размеру или значению адреса
ничего нельзя сказать о размере или типе переменной, так же, как и по номеру дома — о здании, которое
находится по этому адресу. Обычно для хранения адреса требуются два или четыре байта, в зависимости от
компьютера.
Для инициализации указателя можно использовать оператор объявления. В этом случае инициализируется
указатель, а не указываемое значение. Таким образом, следующие операторы:
int higgens = 5;
int *pt = &higgens;
присваивают указателю pt (но не *pt) значение &higgens.
В программе 3_10 демонстрируется инициализация указателя с присвоением ему адреса.
Программа 3_10
// программа p3_10.cpp - инициализация указателя
#include <iostream>
using namespace std;
void main()
{
int higgens = 5;
int *pi = &higgens;
cout << "Value of higgens = " << higgens
<< "; Address of higgens = " << &higgens << "n";
cout << "Value of *pi = " << *pi << "; Address of pi = " << pi << "n";
}
Результат:
Value of higgens = 5; Address of higgens = 0012FF7C
Value of *pi = 5; Address of pi = 0012FF7C
Можно видеть, что программа присваивает адрес переменной higgens указателю pi, но не значению *pi.
Отметим однако, что неосторожное использование указателей может привести к нежелательным
последствиям. Крайне важно не забывать о том, что при создании указателя в C++ компьютер выделяет память
для хранения адреса, но не для хранения данных, на которые указывает этот адрес. Чтобы выделить места для
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория
C++ теория

More Related Content

What's hot

Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...
Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...
Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...Jordano Santos Cerqueira
 
บริการจัดวางตัวบุคคล
บริการจัดวางตัวบุคคลบริการจัดวางตัวบุคคล
บริการจัดวางตัวบุคคลChainarong Maharak
 
O jogo do contrário em avaliação
O jogo do contrário em avaliaçãoO jogo do contrário em avaliação
O jogo do contrário em avaliaçãoJéssica Frontelli
 
สาระสำคัญของการลูกเสือ
สาระสำคัญของการลูกเสือสาระสำคัญของการลูกเสือ
สาระสำคัญของการลูกเสือpreecha klamrassamee
 
Plano de aula matemática
Plano de aula   matemáticaPlano de aula   matemática
Plano de aula matemáticaAmanda Freitas
 
หน่วยที่ ๕ การ์ตูนสร้างสรรค์
หน่วยที่ ๕ การ์ตูนสร้างสรรค์หน่วยที่ ๕ การ์ตูนสร้างสรรค์
หน่วยที่ ๕ การ์ตูนสร้างสรรค์srkschool
 
Apresentação estágio supervisionado ii
Apresentação estágio supervisionado iiApresentação estágio supervisionado ii
Apresentação estágio supervisionado iifamiliaestagio
 
Os 6 papéis equivocados do coordenador pedagógico
Os 6 papéis equivocados do coordenador pedagógicoOs 6 papéis equivocados do coordenador pedagógico
Os 6 papéis equivocados do coordenador pedagógicoopmacae
 
บทที่8การวัดผลประเมินผลการเรียนรู้
บทที่8การวัดผลประเมินผลการเรียนรู้บทที่8การวัดผลประเมินผลการเรียนรู้
บทที่8การวัดผลประเมินผลการเรียนรู้Bert Nangngam
 
Informatica basica e tecnologias na educacao unidade 03
Informatica basica e tecnologias na educacao  unidade 03Informatica basica e tecnologias na educacao  unidade 03
Informatica basica e tecnologias na educacao unidade 03Alelis Gomes
 
Best practice บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่น
Best practice   บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่นBest practice   บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่น
Best practice บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่นatunya2530
 

What's hot (20)

Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...
Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...
Vasco Pedro Moretto - Prova. Um momento privilegiado de Estudo, não um acerto...
 
บริการจัดวางตัวบุคคล
บริการจัดวางตัวบุคคลบริการจัดวางตัวบุคคล
บริการจัดวางตัวบุคคล
 
O jogo do contrário em avaliação
O jogo do contrário em avaliaçãoO jogo do contrário em avaliação
O jogo do contrário em avaliação
 
สาระสำคัญของการลูกเสือ
สาระสำคัญของการลูกเสือสาระสำคัญของการลูกเสือ
สาระสำคัญของการลูกเสือ
 
Plano de aula matemática
Plano de aula   matemáticaPlano de aula   matemática
Plano de aula matemática
 
Projeto festa junina 2013
Projeto festa junina 2013Projeto festa junina 2013
Projeto festa junina 2013
 
P C C H R&amp; D K P I
P C C  H R&amp; D  K P IP C C  H R&amp; D  K P I
P C C H R&amp; D K P I
 
Ot apresentação saresp
Ot apresentação sarespOt apresentação saresp
Ot apresentação saresp
 
หน่วยที่ ๕ การ์ตูนสร้างสรรค์
หน่วยที่ ๕ การ์ตูนสร้างสรรค์หน่วยที่ ๕ การ์ตูนสร้างสรรค์
หน่วยที่ ๕ การ์ตูนสร้างสรรค์
 
Tocaram a Campainha
Tocaram a CampainhaTocaram a Campainha
Tocaram a Campainha
 
Apresentação estágio supervisionado ii
Apresentação estágio supervisionado iiApresentação estágio supervisionado ii
Apresentação estágio supervisionado ii
 
Apresentação TCC I
Apresentação TCC IApresentação TCC I
Apresentação TCC I
 
Ata da reunião 12 06 2012
Ata da reunião 12 06 2012Ata da reunião 12 06 2012
Ata da reunião 12 06 2012
 
Trabalho de Educação Física
Trabalho de Educação FísicaTrabalho de Educação Física
Trabalho de Educação Física
 
wan
wanwan
wan
 
Os 6 papéis equivocados do coordenador pedagógico
Os 6 papéis equivocados do coordenador pedagógicoOs 6 papéis equivocados do coordenador pedagógico
Os 6 papéis equivocados do coordenador pedagógico
 
WORKSHOP DE JOGOS MATEMÁTICOS
WORKSHOP DE JOGOS MATEMÁTICOSWORKSHOP DE JOGOS MATEMÁTICOS
WORKSHOP DE JOGOS MATEMÁTICOS
 
บทที่8การวัดผลประเมินผลการเรียนรู้
บทที่8การวัดผลประเมินผลการเรียนรู้บทที่8การวัดผลประเมินผลการเรียนรู้
บทที่8การวัดผลประเมินผลการเรียนรู้
 
Informatica basica e tecnologias na educacao unidade 03
Informatica basica e tecnologias na educacao  unidade 03Informatica basica e tecnologias na educacao  unidade 03
Informatica basica e tecnologias na educacao unidade 03
 
Best practice บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่น
Best practice   บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่นBest practice   บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่น
Best practice บทเรียนการ์ตูนและเกมส์ช่วยสอน โรงเรียนบ้านซับสนุ่น
 

Viewers also liked

Введение в MFC
Введение в MFCВведение в MFC
Введение в MFCmcroitor
 
Обзор MS.Net Framework
Обзор MS.Net FrameworkОбзор MS.Net Framework
Обзор MS.Net Frameworkmcroitor
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++mcroitor
 
стандартная библиотека с++: введение
стандартная библиотека с++: введениестандартная библиотека с++: введение
стандартная библиотека с++: введениеmcroitor
 
C++ и базы данных
C++ и базы данныхC++ и базы данных
C++ и базы данныхmcroitor
 
библиотеки программирования
библиотеки программированиябиблиотеки программирования
библиотеки программированияmcroitor
 

Viewers also liked (6)

Введение в MFC
Введение в MFCВведение в MFC
Введение в MFC
 
Обзор MS.Net Framework
Обзор MS.Net FrameworkОбзор MS.Net Framework
Обзор MS.Net Framework
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 
стандартная библиотека с++: введение
стандартная библиотека с++: введениестандартная библиотека с++: введение
стандартная библиотека с++: введение
 
C++ и базы данных
C++ и базы данныхC++ и базы данных
C++ и базы данных
 
библиотеки программирования
библиотеки программированиябиблиотеки программирования
библиотеки программирования
 

Similar to C++ теория

C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.Igor Shkulipa
 
C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.Igor Shkulipa
 
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...Tatyanazaxarova
 
Теория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциямТеория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциямSergey Staroletov
 
20090721 hpc exercise2
20090721 hpc exercise220090721 hpc exercise2
20090721 hpc exercise2Michael Karpov
 
язык програмирования
язык програмированияязык програмирования
язык програмированияOlegmingalev1997
 
Programming history. Algorithm
Programming history. AlgorithmProgramming history. Algorithm
Programming history. AlgorithmIhor Porotikov
 
программирование на Maple. Лекция 1
программирование на Maple. Лекция 1программирование на Maple. Лекция 1
программирование на Maple. Лекция 1Andrei V, Zhuravlev
 
Algorithms and programming lecture in ru
Algorithms and programming lecture in ruAlgorithms and programming lecture in ru
Algorithms and programming lecture in russuser0562f1
 
Алгоритмизация и программирование С/С++
Алгоритмизация и  программирование С/С++Алгоритмизация и  программирование С/С++
Алгоритмизация и программирование С/С++ssuser0562f1
 
лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)djbelyakk
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.Igor Shkulipa
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6Technopark
 
языки программирования
языки программированияязыки программирования
языки программированияDmitry Kulikov
 

Similar to C++ теория (20)

лек1
лек1лек1
лек1
 
лек1
лек1лек1
лек1
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.
 
C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.
 
лек12
лек12лек12
лек12
 
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
Использование библиотеки анализа кода OpenC++: модификация, улучшение, исправ...
 
378 васильев куницын
378 васильев куницын378 васильев куницын
378 васильев куницын
 
лек13 3
лек13 3лек13 3
лек13 3
 
Теория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциямТеория языков программирования некоторые слайды к лекциям
Теория языков программирования некоторые слайды к лекциям
 
20090721 hpc exercise2
20090721 hpc exercise220090721 hpc exercise2
20090721 hpc exercise2
 
язык програмирования
язык програмированияязык програмирования
язык програмирования
 
Programming history. Algorithm
Programming history. AlgorithmProgramming history. Algorithm
Programming history. Algorithm
 
программирование на Maple. Лекция 1
программирование на Maple. Лекция 1программирование на Maple. Лекция 1
программирование на Maple. Лекция 1
 
Algorithms and programming lecture in ru
Algorithms and programming lecture in ruAlgorithms and programming lecture in ru
Algorithms and programming lecture in ru
 
Алгоритмизация и программирование С/С++
Алгоритмизация и  программирование С/С++Алгоритмизация и  программирование С/С++
Алгоритмизация и программирование С/С++
 
лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)лекции спрг 6_семестр (1)
лекции спрг 6_семестр (1)
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6
 
лек5 6
лек5 6лек5 6
лек5 6
 
языки программирования
языки программированияязыки программирования
языки программирования
 

More from tank1975

презентация1
презентация1презентация1
презентация1tank1975
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power pointtank1975
 
розумники пикуза
розумники пикузарозумники пикуза
розумники пикузаtank1975
 
презентація батьківські збори
презентація батьківські зборипрезентація батьківські збори
презентація батьківські збориtank1975
 
п1 сухаревська о.о. (оновлена)1 (1)
п1 сухаревська о.о. (оновлена)1 (1)п1 сухаревська о.о. (оновлена)1 (1)
п1 сухаревська о.о. (оновлена)1 (1)tank1975
 
інтелект україни презентація для батьків1
інтелект україни презентація для батьків1інтелект україни презентація для батьків1
інтелект україни презентація для батьків1tank1975
 
віртуальна екскурсія кнвк
віртуальна екскурсія кнвквіртуальна екскурсія кнвк
віртуальна екскурсія кнвкtank1975
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power pointtank1975
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power pointtank1975
 
мігутіна 24.02
мігутіна 24.02мігутіна 24.02
мігутіна 24.02tank1975
 
доклад 2
доклад 2доклад 2
доклад 2tank1975
 
скаути
скаутискаути
скаутиtank1975
 
презентация Microsoft power point
презентация Microsoft power pointпрезентация Microsoft power point
презентация Microsoft power pointtank1975
 
Random 161024151802
Random 161024151802Random 161024151802
Random 161024151802tank1975
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power pointtank1975
 
презентация Microsoft power point
презентация Microsoft power pointпрезентация Microsoft power point
презентация Microsoft power pointtank1975
 
на сайт пасхалія 1 а клас
на сайт пасхалія 1   а класна сайт пасхалія 1   а клас
на сайт пасхалія 1 а класtank1975
 
презентация Microsoft power point
презентация Microsoft power pointпрезентация Microsoft power point
презентация Microsoft power pointtank1975
 

More from tank1975 (20)

презентация1
презентация1презентация1
презентация1
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power point
 
розумники пикуза
розумники пикузарозумники пикуза
розумники пикуза
 
презентація батьківські збори
презентація батьківські зборипрезентація батьківські збори
презентація батьківські збори
 
п1 сухаревська о.о. (оновлена)1 (1)
п1 сухаревська о.о. (оновлена)1 (1)п1 сухаревська о.о. (оновлена)1 (1)
п1 сухаревська о.о. (оновлена)1 (1)
 
інтелект україни презентація для батьків1
інтелект україни презентація для батьків1інтелект україни презентація для батьків1
інтелект україни презентація для батьків1
 
віртуальна екскурсія кнвк
віртуальна екскурсія кнвквіртуальна екскурсія кнвк
віртуальна екскурсія кнвк
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power point
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power point
 
мігутіна 24.02
мігутіна 24.02мігутіна 24.02
мігутіна 24.02
 
доклад 2
доклад 2доклад 2
доклад 2
 
скаути
скаутискаути
скаути
 
презентация Microsoft power point
презентация Microsoft power pointпрезентация Microsoft power point
презентация Microsoft power point
 
Klass
KlassKlass
Klass
 
Random 161024151802
Random 161024151802Random 161024151802
Random 161024151802
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power point
 
презентация Microsoft power point
презентация Microsoft power pointпрезентация Microsoft power point
презентация Microsoft power point
 
на сайт пасхалія 1 а клас
на сайт пасхалія 1   а класна сайт пасхалія 1   а клас
на сайт пасхалія 1 а клас
 
презентация Microsoft power point
презентация Microsoft power pointпрезентация Microsoft power point
презентация Microsoft power point
 
9 г+
9 г+9 г+
9 г+
 

C++ теория

  • 1. Теория и практика С++1 1 Язык программирования С++ История С и С++. История начинается с 1970 год. (Bell Labs - бывшая американская, а ныне франко-американская корпорация, крупный исследовательский центр в области телекоммуникаций, электронных и компьютерных систем ). Два сотрудника Кен Томпсон и Денис Ричи являлись ведущими инженерами команды перед которыми была поставлена задача написать переносимую ОС. Что это значит? Было несколько моделей компьютеров с разным устройством и хотелось написать систему, которая могла работать на разных моделях. Для этой цели был разработан язык С для ОС Unix. К языку предъявлялись следующие требования: 1. Эффективность, как язык Ассемблер. 2. Более удобен, чем Ассемблер. Например – сложение двух чисел. ASM C mov AX, 2 mov BX, [1234] add AX, BX mov [DX], AX a = b +c Более сложные вещи пишутся еще более громоздко. 3. Переносимость на уровне текстов исходных программ. Т.е. если есть новая платформа, то для нее достаточно написать компилятор С, которых мог перевести программу на С для новой платформы. На языке ASM это было бы неудобно. У инструкций ASM есть операнды, которые могут отличаться на различных машинах. Т.е. Язык ASM наиболее близок к машинному коду. Хотелось от этого абстрагироваться. И такой язык был разработан - С. Но в погоне за эффективностью он ближе к машине, чем к программисту.Например: 1. Нет специального символьного типа. 2. В нем отсутствует булевский тип для логических значений (true и false). Любое число 0 – true. 0 = false. Казус: if (a = 0) { } а сравнивается с нулем. На самом деле программист хотел написать a == 0. Ошибка, всегда будет false (в результате присваивания возвратился ноль) и в условие никогда не попадем. С точки зрения компилятора инструкция легальна. Ошибки не видит. 1980 год. Bell Labs – Бьерн Страуструп. Предложил новый язык С++, который является развитием языка С. Изначально язык назывался C++ with classes. Т.е. С и еще что-то. Необходимость этого языка возникла из-за необходимости писать программы работающие с большими БД. Большинство программистовразрабатывают системы автоматизации (банка, магазина), т.е. автоматизация каких то процессов в бизнесе. Язык С++ добавляет что-то к языку С и при этом сохраняется обратная совместимость, т.е. С является подмножеством языка С++. Почему так сделали, а не написали все заново при этом убравмногие ошибки в языке С? Потому что очень много кода написано на языке С. По истории все.
  • 2. Теория и практика С++2 2 Порядок создания программы 1. С помощью текстового редактора напишите свою программу и сохраните ее в файле. Это будет исходный код вашей программы. 2. Скомпилируйте исходный код. Для этого необходимо запустить программу,которая транслирует исходный код во внутренний язык, называемый машинным языком рабочего компьютера. Файл, содержащий транслированную программу — это объектный код вашей программы. 3. Свяжите объектный код с дополнительным кодом. Например, программы на C++ обычно используют библиотеки. Библиотека C++ содержит объектный код для набора компьютерных подпрограмм, называемых функциями. В процессе связывания ваш объектный код комбинируется с объектным кодом для используемых функций и с некоторым стандартным кодом запуска для формирования версии времени выполнения вашей программы.Файл, содержащий этот финальный продукт, называется исполняемым кодом. 1. Начальные сведения о языке С++ Программа 1_1 //программа отображаетна экране сообщение #include <iostream> //директива препроцессора using namespace std; //включает в программу определения int main() //заголовок функции { //начало тела функции cout << "I love C++"; //сообщение cout << "n"; //начать новую строку return 0; //завершение функции main() } //конец тела функции Результат: Come up and C++ me some time Функция main() Программа С++ строится из отдельных блоков, называемых функциями. Программа 1_1 имеет следующую структуру: int main() { операторы return 0; } Эти строки во-первых, означают, что перед нами функция с именем main(), и, во-вторых, они содержат описание работы этой функции. Вся совокупность приведенных выше строк составляет определение функции. Это определение состоит из двух частей: первой строки int main(), которая называется заголовком функции, и остальной части, заключенной в фигурные скобки, которая является телом функции. Заголовок функции определяет интерфейс между функцией и остальной частью программы, а тело функции содержит инструкции для компьютера. Каждая завершенная инструкция называется оператором. Каждый оператор должен заканчиваться точкой с запятой. Заключительный оператор в функции main(), называется оператором возврата, завершает функцию. Что такое return 0? Дело в том, что иногда возникает необходимость запускать несколько команд в сложном сочетании. Это делается с помощью скриптов командной оболочки (язык сценариев). Под Windows - bat- файлы. Из сценария можно запустить программу на исполнение и посмотреть, какой результат она вернет операционной системе. Например это может использоваться для контроля над ошибками. Если программа вернет 0, то ошибка нет надо что-то сделать.
  • 3. Теория и практика С++3 3 Заголовок функции в роли интерфейса В общем случае функция С++ активизируется или вызывается другой функцией, а заголовок функции описывает интерфейс между нею и той функцией, которая ее вызывает. Слово, стоящее перед именем функции, называется возвращаемым типом функции; оно описывает информацию, передаваемую из функции обратно в ту функцию, которая ее вызывала. Информация в круглых скобках, следующих за именем функции, называется списком аргументов или списком параметров. Этот список содержит описание информации, передаваемой из вызывающей в вызываемую функцию. Препроцессор C++ и файл iostream #include <iostream> //директива препроцессора В языке C++, как и в С, используется препроцессор. Препроцессор — это программа, которая выполняет обработку файла исходного кода перед началом собственно компиляции. Эта директива заставляет препроцессор добавить содержимое файла iostream в вашу программу. Добавление или замена текста в исходном коде перед его компиляцией является одним из обычных действий препроцессора. Имена заголовочных файлов Файлы, такие как iostream, называются заголовочными (поскольку они включаются в начало файла). Заголовочные файлы имеют расширение h и содержат прототипы функций. Пространства имен using namespace std; //включает в программу определения Это называется директивой using. Сейчас самое главное — просто запомнить ее. Поддержка пространства имен — это средство C++, предназначенное для упрощения разработки крупных программ и программ, в которых комбинируется существующий код от нескольких поставщиков, а также для помощи в организации таких программ. Одна из потенциальных проблем заключается в том, что вы можете работать с двумя готовыми продуктами, в каждом из которых присутствует, скажем, функция f1(). При использовании функции f1() компилятор не будет знать, какая конкретно версия этой функции имеется в виду. Средство пространств имен позволяет поставщику упаковать свой продукт в модуль, называемый пространством имен. Вы, в свою очередь, можете использовать название этого пространства имен для указания, продукт какого производителя вам необходим. Так, например, компания Micro может поместить свои определения в пространство имен Micro. Тогда полное имя. функции f1() будет выглядеть как Micro::f1(). Аналогично, Macro::f1() может обозначать версию функции f1() от компании Macro. Комментарии Комментарии обозначаются двойной наклонной чертой (//). Комментарий – это написанное программистом примечание, которое предназначается для тех, кто будет изучать эту программу. Вывод данных с использованием объекта cout cout << "Come up and C++ me some time."; Информация, заключенная в двойные кавычки, является сообщением, которое должно быть выведено на экран. Любая последовательность символов, заключенная в двойные кавычки, называется строкой символов. Обозначение << указывает на то, что этот оператор отправляет данную строку в объект cout. cout - предопределенный объект, способный отображать на экране разнообразные данные – строки, числа и отдельные числа. Символ новой строки cout << "n"; Комбинация символов n является специальной формой записи важного понятия, называемого символом новой строки. Символ новой строки перемещает курсор на начало новой строки. Его можно комбинировать со строкой символов. cout << "Come up and C++ me some time.n";
  • 4. Теория и практика С++4 4 Стиль форматирования исходного кода программ 1. В строке присутствует один оператор 2. Открывающая и закрывающая фигурные скобки для функции располагаются каждая в отдельной строке 3. Операторы тела функции располагаются с отступом от фигурных скобок 4. Символы пробела не ставятся с обеих сторон круглых скобок, следующих за именем функции Дополнительные сведения об операторах Программа представляет собой совокупность функций, а каждая функция – это совокупность операторов. Программа 1_2 //программа p1_2.cpp - отображает на экране значение переменной #include <iostream> using namespace std; void main() { int fleas; //создает целочисленную переменную fleas = 38; //присваивает этой переменной значение cout << "My cat has "; cout << fleas; //отображает на экране значение переменной fleas cout << " fleas.n"; system("pause"); } Результат: My cat has 38 fleas. В программе 1_2 содержатся два новых вида операторов. Во-первых, оператор объявления создает переменную. Во-вторых, оператор присваивания присваивает этой переменной некоторое значение. Результат выполнения программы: My cat has 38 fleas. Операторы объявления и переменные Для хранения в ПК какого-либо элемента информации необходимо указать, в каком месте памяти он будет храниться, а также объем области памяти, требуемой для его хранения. Это можно сделать при помощи оператора объявления. Например: int fleas; Тип хранимой информации определяется словом int, который соответствует целому числу (положительные и отрицательные числа). Для идентификации области памяти в которой будет хранится значение используется слово fleas. Поскольку это значение может изменяться, fleas называется переменной. Оператор присваивания Оператор присваивания присваивает значение некоторой области памяти. Например: fleas = 38; Операцию присваивания можно использовать последовательно. Например: int x; int y; int z; x = y = z = 88; ВВОД ДАННЫХ Программа 1_3 // ввод и вывод #include <iostream> using namespace std;
  • 5. Теория и практика С++5 5 void main() { int fleas; cout << "How many fleas does your cat have?n"; cin >> fleas; //ввод в программу С++ //следующая строка объединяет выводимые данные cout << "Well, that's " << fleas << " fleas too many!n"; system("pause"); } Результат: How many fleas does your cat have? 112 Well, that's 112 fleas too many! Ввод данных в программу осуществляется при помощи объекта cin. ФУНКЦИИ Имеются две разновидности функций: функции с возвращаемыми значениями и без них. Применение функций с возвращаемым значением Функция с возвращаемым значением в результате своей работы выдает значение, которое можно присвоить переменной. Например функция sqrt(), возвращает квадратный корень числа. x = sqrt(6.25); //возвращает значение 2.5 и присваивает его переменной x Выражение sqrt(6.25) вызывает функцию sqrt(). Выражение sqrt(6.25) называется вызовом функции, сама функция называется вызываемой, а функция, в которой находится вызов функции, называется вызывающей. Значение в круглых скобках ( в данном случае 6.25) представляет собой информацию, которая передается в функцию. Это значение называется аргументом или параметром. Функция sqrt() вычисляет результат, который будет равным 2,5, и отправляет это значение обратно вызывающей функции. Это отправляемое значение называется возвращаемым значением функции. Перед тем, как использовать функцию, компилятор С++ должен знать типы аргументов и возвращаем ого значения функции. Эта информация передается компилятору с помощью прототипа функции. ПОМНИТЕ В программе С++ для каждой используемой функции должен быть прототип. Прототип функции информирует программу о типахданных. Прототип функции sqrt() выглядит так: double sqrt(double); //прототип функции Первое ключевое слово double означает, что функция sqrt() возвращает значение типа double. Ключевое слово double в круглых скобках означает, что функции sqrt() необходим аргумент типа double. Если в программе применяется функция sqrt(), необходимо включить в код ее прототип. Это можно обеспечить двумя способами:  Вручную ввести прототип функции в исходных код программы.  Включить в программу заголовочный файл cmath, который содержит прототип этой функции. Итак, прототип описывает информацию, посылаемую в функцию и из функции. А определение функции содержит код функции. Прототип функции должен находиться в программе до того места, где функция применяется впервые. Программа 1_4 // использование функции sqrt() #include <iostream> using namespace std; #include <cmath> void main() { double cover; //использовать вещественные числа типа double cout << "How many square feet of sheets do you have?n";
  • 6. Теория и практика С++6 6 cin >> cover; double side; //создать еще одну переменную side = sqrt(cover); //вызвать функцию и присвоить возвращаемое значение переменной cout << "You can cover a square with sides of " << side; cout << "nfeet with your sheets.n"; } Результат: "How many square feet of sheets do you have? 123.21 You can cover a square with sides of 11.1 feet with your sheets. Разновидности функций Некоторым функциям требует более одного элемента информации. Эти функции используют несколько аргументов, разделяемых запятыми. Например прототип функции pow(): double pow(double, double); //прототип функции с двумя аргументами Пример использования функции: answer = pow(5.0, 8.0); //вызов функции со списком аргументов Пример прототипа функции, которая не принимает аргументов: int rand(void); //прототип функции, не принимающей аргументов Пример использования функции без аргументов: myGuess = rand(); //вызов функции, не имеющей аргументов Пример прототипа функции, которая не возвращает значения: void bucks(double); //прототип функции, не имеющей возвращаемого значения Пример использования функции bucks(): bucks(1234.56); //вызов функции, возвращаемое значение отсутствует Функции, определяемые пользователем Для пользовательской функции необходимо поместить прототип функции до ее вызова (обычно перед функцией main()), а также необходимо написать исходный код определяемой функции. Программа 1_5 //программа p1_5.cpp - определение собственной функции #include <iostream> using namespace std; void simon(int); //прототип функции simon() void main() { simon(3); //вызов функции simon() cout << "Pick an integer: "; int count; cin >> count; simon(count); //повторный вызов этой функции } void simon(int n) //определение функции simon() { cout << "Simon says touch your toes " << n << " times.n"; } //в функциях без возвращаемого значения не требуется оператор return Результат: Simon says touch your toes 3 times. Pick an integer: 512 Simon says touch your toes 512 times.
  • 7. Теория и практика С++7 7 Формат определения функции Сначала идет заголовок функции, затем следует тело функции, заключенное в фигурные скобки. В общем случае формат следующий: тип имя_функции(список_аргументов) { операторы } ОПРЕДЕЛЯЕМАЯ ПОЛЬЗОВАТЕЛЕМ ФУНКЦИЯ С ВОЗВРАЩАЕМЫМ ЗНАЧЕНИЕМ Программа 1_6 //программа p1_6.cpp - преобразование стоунов в фунты #include <iostream> using namespace std; int stonetolb(int); //прототип функции void main() { int stone; cout << "Enter the weight in stone: "; cin >> stone; int pounds=stonetolb(stone); cout << stone << " stone are "; cout << pounds << " pounds.n"; } int stonetolb(int sts) { return 14 * sts; } Результат: Enter the weight in stone: 14 14 stone are 196 pounds. ВОПРОСЫ ДЛЯ ПОВТОРЕНИЯ (1) 1. Какой оператор следует использовать, чтобы вывести фразу "Hello, world" и перейти на начало строки? 2. Какой оператор следует использовать, чтобы создать целочисленную переменную с именем cheese? 3. Какой оператор следует использовать, чтобы присвоить переменной cheeses значение 32? 4. Какой оператор следует использовать для ввода значения с клавиатуры и присвоения его переменной cheeses? 5. Какой оператор следует использовать для вывода предложения "We have X varieties of cheese", где буква Х будет заменяться текущим значением переменной cheeses? 6. Какую информацию о функции дает следующий заголовок функции: int froop(double t) 7. В каком случае при определении функции не используется ключевое слово return? УПРАЖНЕНИЯ ПО ПРОГРАММИРОВАНИЮ (1) 1. Напишите программу, которая отображает на экране ваше имя и адрес. 2. Напишите программу, которая запрашивает расстояние в сантиметрах и преобразует его в миллиметры. 3. Напишите программу, которая состоит из двух определяемых пользователем функций и выводит на экран следующие данные: Three blind mice Three blind mice See how they run See how they run
  • 8. Теория и практика С++8 8 Одна функция, вызываемая дважды, должна отображать две первые строки, а другая, также вызываемая дважды, должна отображать остальные выходные данные. 4. Напишите программу, в которой функция main() вызывает определяемую пользователем функцию, принимающую в качестве аргумента значение температуры в градусах по Цельсию и возвращающую эквивалентное значение в градусах по Фаренгейту. По запросу программы температуру в градусах Цельсия вводит пользователь. Затем программа отображает результат. Данные, выводимые на экран, имеют следующий вид: Please enter a Celsius value: 20 20 degrees Celsius is 68 degrees Fahrenheit. Для справок: формула для выполнения преобразования: Fahrenheit = 1.8 x Celsius + 32.0 5. Напишите программу, в которой функция main() вызывает определяемую пользователем функцию. Эта функция принимает значение расстояния в световых годах и возвращает расстояние в астрономических единицах. Программа должна запрашивать ввод значения в световых годах и отображать результат, как показано в следующем примере: Enter the number of light years: 4.2 4.2 light are 265608 astronomical units Для дробных чисел используйте тип double и следующую формулу преобразования: 1 световой год = 63240 астрономических единиц 2. Представление данных переменными Существует две группы типов данных: базовые и составные, или производные. Базовые типы данных служат для представления целых чисел и чисел с плавающей точкой. Имена переменных Для переменных рекомендуется выбирать имена, отражающие их назначение. Существует несколько простых правил именования, которые обязательны для применения:  В именах можно использовать только следующие символы: буквы алфавита, цифры и символ подчеркивания (_).  Первый символ имени не может быть цифрой.  Символы верхнего и нижнего регистров рассматриваются как разные.  В качестве имен нельзя использовать ключевые слова языка С++.  Имена, начинающие с двух символов подчеркивания или с символа подчеркивания и следующей за ним буквы в верхнем регистре, зарезервированы для использования реализацией языка. Имена, начинающиеся с одного символа подчеркивания, зарезервированы реализацией языка в качестве глобальных идентификаторов.  В языке С++ на длину имени не накладывается никаких ограничений, т.е. учитывается каждый символ. Примеры допустимых и недопустимых имен С++: int poodle; //допустимое int Poodle; //допустимое и отличное от имени poodle int POODLE; //допустимое и еще более отличное от имени poodle Int terrier; //недопустимое – должно быть ключевое слово int, а не Int int my_stars3; //допустимое int _Mystars3; //допустимое, но зарезервировано – начинается с символа //подчеркивания int 4ever; //недопустимое, так как начинается с цифры int double; //недопустимое – double является ключевым словом С++ int begin; //допустимое int __fools; //допустимое, но зарезервированное – начинается с двух //символов подчеркивания int the_very_best_variable_i_can_be_version_112; //допустимое int honky-tonk; //недопустимое – дефис не допускается Целочисленные типы данных
  • 9. Теория и практика С++9 9 Целые числа – это числа без дробной части. В языке С++ различные типы данных различаются по объему памяти, используемому для их хранения. Большой блок памяти может представлять большой диапазон целых чисел. Кроме того, одни типы данных )со знаком) могут представлять и положительные, и отрицательные значения, тогда как другие типы данных (без знака) не могут представлять отрицательные значения. Для описания объема памяти, используемого для хранения целочисленного значения, обычно применяют термин размерность. Чем больше памяти отводится для хранения значения, тем больше го размерность. Базовые типы целочисленных данных языка С++ (в порядке размерности) именуются char, short, int и long. Каждый их этих типов данных подразделяется на две разновидности: со знаком и без знака. В результате имеется набор из восьми различных типов целочисленных данных. Типы данных short, int и long Размерность – это количество битов или разрядов.  Размерность данных типа short не меньше 16 разрядов.  Размерность данных типа int не меньше размерности данных типа short.  Размерность данных типа long не меньше 32 разрядов и не меньше размерности данных типа int. Примеры объявления переменных: short score; int temperature; long position; Следующая программа позволяет узнать размерность целых типов в конкретной системе. Программа 2_1 //программа p2_1.cpp - предельные значения целочисленных типов данных #include <iostream> using namespace std; #include <climits> void main() { //оператор sizeof возвращает размерность типа данных или переменной cout << "short is " << sizeof(short) << " bytes.n"; cout << "int is " << sizeof(int) << " bytes.n"; cout << "long is " << sizeof(long) << " bytes.nn"; //максимальное значение cout << "Maximum value:n"; cout << "short: " << SHRT_MAX << "n"; cout << "int: " << INT_MAX << "n"; cout << "long: " << LONG_MAX << "nn"; //минимальное значение cout << "Minimum value:n"; cout << "short: " << SHRT_MIN << "n"; cout << "int: " << INT_MIN << "n"; cout << "long: " << LONG_MIN << "nn"; //максимальное значение безнаковых типов cout << "Maximum unsigned value:n"; cout << "unsigned short: " << USHRT_MAX << "n"; cout << "unsigned int: " << UINT_MAX << "n"; cout << "unsigned long: " << ULONG_MAX << "n"; } Результат: short is 2 bytes. int is 4 bytes. long is 4 bytes. Maximum value: short: 32767 int: 2147483647 long: 2147483647
  • 10. Теория и практика С++10 10 Minimum value: short: -32768 int: -2147483648 long: -2147483648 Maximum unsigned value: unsigned short: 65535 unsigned int: 4294967295 unsigned long: 4294967295 ТИПЫ ДАННЫХ БЕЗ ЗНАКА В программе 2_2 иллюстрируется использование беззнаковых типов данных. В ней также показано, что может произойти, если в программе будет предпринята попытка выйти за границы диапазона возможных значений для целочисленных данных какого-либо типа. И здесь вы можете увидеть директиву препроцессора #define, которая дает команду заменить в программе все имена ZERO числами 0. Программа 2_2 // предельные значения целочисленных типов данных #include <iostream> using namespace std; int main() { const int ZERO = 0; short sam = SHRT_MAX; unsigned short sue = sam; cout << "Sam has " << sam << " dollars and Sue has " << sue; cout << " dollars deposited.nAdd $1 to each account.nNow "; sam = sam + 1; sue = sue + 1; cout << "Sam has " << sam << " dollars and Sue has " << sue; cout << " dollars deposited.nPoor Sam!n"; sam = ZERO; sue = ZERO; cout << "Sam has " << sam << " dollars and Sue has " << sue; cout << " dollars deposited.n"; cout << "Take $1 from each account.nNow "; sam = sam - 1; sue = sue - 1; cout << "Sam has " << sam << " dollars and Sue has " << sue; cout << " dollars deposited.nLucky Sue!n"; } Результат: Sam has 32767 dollars and Sue has 32767 dollars deposited. Add $1 to each account. Now Sam has -32768 dollars and Sue has 32768 dollars deposited. Poor Sam! Sam has 0 dollars and Sue has 0 dollars deposited. Take $1 from each account. Now Sam has -1 dollars and Sue has 65535 dollars deposited. Lucky Sue! Целочисленная константа Целочисленная константа – это константа, записываемая явно, например 212 или 1776. В языке С++ целочисленные константы могут записываться в трех системах счисления: десятичная, восьмеричная и шестнадцатеричная. Правила записи чисел в различных системах счисления следующие. Если первая цифра находится в диапазоне 1-9, то число является десятичным. Если первая цифра равна 0, а вторая находится в диапазоне от 1 до 7, то число является восьмеричным. Если первые два символа – 0х или 0Х, то речь идет о шестнадцатеричном числе. Программа 2_3 // демонстрирует использование шестнадцатеричных / восьмеричных констант
  • 11. Теория и практика С++11 11 #include <iostream> using namespace std; void main() { int chest = 42; //десятичная целочисленная константа int waist = 0x42; //шестнадцатеричная целочисленная константа int inseam = 042; //восьмеричная целочисленная константа cout << "Monsieur cuts a striking figure!n"; cout << "chest = " << chest << "n"; cout << "waist = " << waist << "n"; cout << "inseam = " << inseam << "n"; } Результат: Monsieur cuts a striking figure! chest = 42 waist = 66 inseam = 34 По умолчанию объект cout отображает целые числа в десятичном виде, независимо от того, как они записаны в программе. Тип данных char: символы и малые целые числа Программа 2_4 // предельные значения типа данных char #include <iostream> using namespace std; #include <climits> void main() { //оператор sizeof возвращает размерность типа данных или переменной cout << "char is " << sizeof(char) << " bytes.n"; //максимальное значение cout << "Maximum value:n"; cout << "char: " << CHAR_MAX << "n"; //минимальное значение cout << "Minimum value:n"; cout << "char: " << CHAR_MIN << "n"; //максимальное значение безнаковых типов cout << "Maximum unsigned value:n"; cout << "unsigned char: " << UCHAR_MAX << "n"; } Тип данных char также предназначен для хранения одного символа из следующей таблицы 0 · 32 [пробел] 64 @ 96 ` 128 · 160 [пробел] 192 А 224 а 1 · 33 ! 65 A 97 a 129 · 161 Ў 193 Б 225 б 2 · 34 " 66 B 98 b 130 · 162 ў 194 В 226 в 3 · 35 # 67 C 99 c 131 · 163 Ј 195 Г 227 г 4 · 36 $ 68 D 100 d 132 · 164 ¤ 196 Д 228 д 5 · 37 % 69 E 101 e 133 · 165 Ґ 197 Е 229 е 6 · 38 & 70 F 102 f 134 · 166 ¦ 198 Ж 230 ж 7 · 39 ' 71 G 103 g 135 · 167 § 199 З 231 з 8 * * 40 ( 72 H 104 h 136 · 168 Ё 200 И 232 и 9 * * 41 ) 73 I 105 i 137 · 169 © 201 Й 233 й 10 * * 42 * 74 J 106 j 138 · 170 Є 202 К 234 к 11 · 43 + 75 K 107 k 139 · 171 « 203 Л 235 л 12 · 44 , 76 L 108 l 140 · 172 ¬ 204 М 236 м 13 * * 45 - 77 M 109 m 141 · 173 - 205 Н 237 н 14 · 46 . 78 N 110 n 142 · 174 ® 206 О 238 о 15 · 47 / 79 O 111 o 143 · 175 Ї 207 П 239 п 16 · 48 0 80 P 112 p 144 · 176 ° 208 Р 240 р
  • 12. Теория и практика С++12 12 17 · 49 1 81 Q 113 q 145 ‘ 177 ± 209 С 241 с 18 · 50 2 82 R 114 r 146 ’ 178 І 210 Т 242 т 19 · 51 3 83 S 115 s 147 · 179 і 211 У 243 у 20 · 52 4 84 T 116 t 148 · 180 ґ 212 Ф 244 ф 21 · 53 5 85 U 117 u 149 · 181 µ 213 Х 245 х 22 · 54 6 86 V 118 v 150 · 182 ¶ 214 Ц 246 ц 23 · 55 7 87 W 119 w 151 · 183 · 215 Ч 247 ч 24 · 56 8 88 X 120 x 152 · 184 ё 216 Ш 248 ш 25 · 57 9 89 Y 121 y 153 · 185 № 217 Щ 249 щ 26 · 58 : 90 Z 122 z 154 · 186 є 218 Ъ 250 ъ 27 · 59 ; 91 [ 123 { 155 · 187 » 219 Ы 251 ы 28 · 60 < 92 124 | 156 · 188 ј 220 Ь 252 ь 29 · 61 = 93 ] 125 } 157 · 189 Ѕ 221 Э 253 э 30 · 62 > 94 ^ 126 ~ 158 · 190 ѕ 222 Ю 254 ю 31 · 63 ? 95 _ 127 · 159 · 191 ї 223 Я 255 я Применение данных типа char демонстрируется в программе 2_5. Программа 2_5 // применение данных типа char #include <iostream> using namespace std; void main() { char ch; cout << "Enter a character:n"; cin >> ch; cout << "Holla! "; cout << "Thank you for the " << ch << " character.n"; } Результат: Enter a character: M Holla! Thank you for the M character. Программа 2_6 // сопоставление данных типа char и int #include <iostream> using namespace std; void main() { char c = 'M'; //переменной с присваивается ASCII-код символа М int i = c; //тот же код сохраняется в переменной типа int cout << "The ASCII code for " << c << " is " << i << "n"; cout << "Add one to the character code:n"; c = c + 1; i = c; cout << "The ASCII code for " << c << " is " << i << "n"; cout << "nDonen"; } В этой программе показано, как определяются символьные константы: символ заключается в одинарные кавычки, например 'M'. Коды управляющих последовательностей в языке С++ Имя символа Код С++ Имя символа Код С++ Новая строка n Сигнал a Горизонтальная табуляция t Обратная наклонная черта Вертикальная табуляция v Вопросительный знак ? Возврат на одну позицию b Одинарная кавычка '
  • 13. Теория и практика С++13 13 Возврат каретки r Двойная кавычка " Программа 2_7 // использование управляющих последовательностей #include <iostream> using namespace std; void main() { cout << "aOperation "HyperHype" is now activated!n"; cout << "Enter your agent code:________bbbbbbbb"; long code; cin >> code; cout << "aYou entered " << code << "...n"; cout << "aCode verified! Proceed with Plan Z3!n"; } Результат: Operation "HyperHype" is now activated! Enter your agent code:007_____ You entered 7... Code verified! Proceed with Plan Z3! Тип данных bool Переменная Boolean – это переменная, которая может принимать два значения: true (истина) или false (ложь). Также необходимо учитывать, что ненулевые значения интерпретируются как значения true, а нулевые значения – как значения false. Примеры: bool isready = true; Литералы true и false могут быть преобразованы в данные типа int путем повышения типа, при этом значение true преобразуется в 1, а false – в 0: int ans = true; //переменной ans присваивается значение 1 int promise = false; // переменной promise присваивается значение 0 Кроме того, любое числовое значение может быть преобразовано в значение типа bool неявно. Любое ненулевое значение преобразуется в значение true, а нулевое – в значение false: bool start = -100; //переменной start присваивается значение true bool stop = 0; //переменной stop присваивается значение false; Квалификатор const Для создания константы используется ключевое слово const: const int MONTH = 12; Обратите внимание: инициализация константы осуществляется вместе с ее объявлением. Следующая последовательность операторов некорректна: const int toes; //в этом операторе значение константы toes не определено toes = 10; //слишком поздно! Типы данных с плавающей точкой Предусмотрено три типа данных с плавающей точкой: float, double и long double. Размерность данных с плавающей точкой: float – минимум 32 разряда; double – минимум 48 разрядов; long double – 80, 96 или 128 разрядов. Арифметические операции Имеются пять основных арифметических операции: сложение (+), вычитание (-), умножение (*), деление (/) и деление по модулю (%) (получение остатка от деления). В каждой из этих операций используются два числа (называемых операндами).
  • 14. Теория и практика С++14 14 Разновидности операции деления Если оба операнда являются целыми числами, то выполняется операция деления целых чисел. Это означает, что любая дробная часть результата отбрасывается, и результат становится целым числом. Если оба или один из операндов – числа с плавающей точкой, то дробная часть результат сохраняется и результат будет числом с плавающей точкой. Где объявляются переменные Как правило, переменные объявляют в трех местах: внутри функций, в определении параметров функции и за пределами всех функций. Соответственно такие переменные называются локальными, формальными параметрами и глобальными. Локальные переменные Переменные, объявленные внутри функции, называются локальными. Локальные переменные можно использовать только в операторах, расположенных внутри блока, где они объявлены. Иначе говоря, локальные переменные невидимы снаружи их блока. Напомним, что блок ограничен открывающей и закрывающей фигурными скобками. Чаще всего локальные переменные объявляются внутри функций. Рассмотрим два примера. void func1(void) { int x; x = 10; } void func2(void) { int x; x = -199; } Переменная x объявлена дважды: сначала — в функции func1(), а затем — в функции func2(). Переменная х из функции func1() не имеет никакого отношения к переменной x, объявленной внутри функции func2(). Каждая из этих переменных существует только внутри блока, где она была объявлена. Из соображений удобства и по традиции большинство программистов объявляют переменные; используемые в функции, сразу после открывающей фигурной и перед всеми остальными операторами. Однако следует иметь в виду, что локальные переменные можно объявлять в любом месте блока. Локальную переменную можно проинициализировать неким значением. Оно будет присваиваться переменной каждый раз при входе в блок. Рассмотрим в качестве мера программу, которая десять раз выводит на печать число 10. Программа 2_8 // присвоение значение переменной во время объявления #include <iostream> using namespace std; void f(); int main() { int i; f(); f(); f(); } void f() { int j = 3; cout << j << " "; j = j + 1; // Этот оператор не имеет долговременного эффекта. }
  • 15. Теория и практика С++15 15 Формальные параметры Если функция имеет аргументы, следует объявить переменные, которые будут принимать их значения. Эти переменные называются формальными параметрами. Внутри функции они ничем не отличаются от других локальных переменных. Как показано в приведенном ниже фрагменте программы, объявление таких переменных должно размещаться сразу после имени функции и заключаться в скобки. /* Функция возвращает 1, если символ с является частью строки s; в противном случае она возвращает0 */ int is_in(char *s, char с) { while(*s) if(*s == c) return 1; else s++; return 0; } Функция is_in() имеет два параметра: вис. Она возвращает 1, если символ с является частью строки s, в противном случае функция возвращает 0. Тип формальных параметров задается при их объявлении. После этого их можно использовать как обычные локальные переменные. Учтите, что, как и локальные переменные, формальные параметры являются динамическими и разрушаются при выходе из функции. Глобальные переменные В отличие от локальных, глобальные переменные доступны из любой части программы и могут быть использованы где угодно. Кроме того, они сохраняют свои значения на всем протяжении выполнения программы. Объявления глобальных переменных должны размещаться вне всех функций. Эти переменные можно использовать в любом выражении, в каком бы блоке оно не находилось. В приведенном ниже фрагменте программы переменная count объявлена вне функций. Несмотря на то что ее объявление расположено до функции main(), переменную можно было бы с таким же успехом объявить в другом месте, но вне функций и до ее первого использования. И все же лучше всего размещать объявление глобальных переменных в самом начале программы. Программа 2_9 // глобальные переменные #include <iostream> using namespace std; int count; /* Переменнная count является глобальной */ void func1(); void func2(); void main() { count = 100; func1(); } void func1(void) { int temp; temp = count; func2(); cout << "count = " << count << "n"; /* Выведет число 100. */ } void func2(void) { int count; for(count=1; count<10; count++) cout << '.'; }Результат:
  • 16. Теория и практика С++16 16 . . . . . . . . . .count = 100 Присмотритесь к этой программе повнимательнее. Заметьте, что, хотя ни функция main(), ни функция func1() не содержат объявления переменной count, обе эти функции успешно ее используют. Однако внутри функции func2() объявлена локальная переменная count. Когда функция func2() ссылается на переменную count она использует лишь локальную переменную, а не глобальную. Если глобальная и локальная переменные имеют одинаковые имена, то все ссылки на имя переменной внутри блока будут относиться к локальной переменной и не влиять на ее глобальную тезку. Возможно, это удобно, однако об этой особенности легко забыть, и тогда действия программы могут стать непредсказуемыми. ВОПРОСЫ ДЛЯ ПОВТОРЕНИЯ (2) 1. Определите следующие переменные: a. Типа short со значением 80 b. Типа unsigned int со значением 42110 c. Целочисленного типа со значением 3 000 000 000 2. Эквивалентны ли следующие операторы char grade = 65; char grade = 'A'; 3. Как с помощью программы найти, какому символу соответствует код 88? УПРАЖНЕНИЯ ПО ПРОГРАММИРОВАНИЮ (2) 1. Напишите программу, которая запрашивает рост в сантиметрах, а затем выражает его в метрах и сантиметрах. Пусть в программе используется символ подчеркивания, чтобы указать место, где вводить ответ. Результат: Enter your height in cm: 182 Your height: 1 m 82 cm 2. Напишите программу, которая запрашивает ваш рост в метрах и ваш вес в килограммах (для хранения этой информации используйте две переменные). Пусть программа вычислит и отобразит на экране ваш ИМТ (индекс массы тела). Чтобы вычислить ИМТ необходимо разделить вес в килограммах на рост в метрах, возведенный в квадрат Результат: Enter your height in m: 1.82 Enter your weight in kg: 70 Your IMT = 21.1327 3. Напишите программу, которая запрашивает длину пути, который вы проехали, в километрах и количество израсходованных литров бензина, а затем отображает на экране значение, показывающее, расход бензина в литрах на 100 километров. Результат: Enter km: 250 Enter litre: 20 The charge on 100 km = 8 3. Составные типы данных Составные типы данных формируются на основе базовых целочисленных типов и типов с плавающей точкой. Это классы, указатели, структуры и массивы. Массивы Массив представляет собой набор переменных с одним именем и разными индексами. Каждая такая переменная называется элементом массива. Количество хранящихся в массиве элементов называется размером массива. Все элементы массива имеют одинаковый тип. Объявление массива должно содержать три аргумента:  тип каждого элемента  имя массива  количество элементов в массиве например:
  • 17. Теория и практика С++17 17 short months[12]; //создает массив с именем months, из 12 элементов типа short Общая форма записи для объявления массива выглядит так: typeName arrayName[arraySize]; Выражение arraySize, которое задает количество элементов, должно быть константой, и не может быть переменной. Программа 3_1 // программа p3_1.cpp - небольшие массивы целых чисел #include <iostream> using namespace std; void main() { int yams[3]; //создается массив из трех элементов yams[0] = 7; //присвоение значения первому элементу yams[1] = 8; yams[2] = 6; int yamcosts[3] = {20, 30, 5}; //создание и инициализация массива cout << "Total yams = "; cout << yams[0] + yams[2] + yams[3] << "n"; cout << "The package with " << yams[1] << " yams costs "; cout << yamcosts[1] << " center per yam.n"; int total = yams[0] * yamcosts[0] + yams[1] * yamcosts[1]; total = total + yams[2] * yamcosts[2]; cout << "The total yam expense is " << total << " cents.n"; cout << "Size of yams array = " << sizeof yams << " bytes.n"; cout << "Size of one element = " << sizeof yams[0] << " bytes.n"; } Результат: Total yams = 14 The package with 8 yams costs 30 center per yam. The total yam expense is 410 cents. Size of yams array = 12 bytes. Size of one element = 4 bytes. Правила инициализации массивов Форму инициализации массива можно использовать только при определении массива. После этого применять ее нельзя, нельзя также целиком присвоить один массив другому: int cards[4] = {3, 6, 8, 10}; //допустимо int hand[4]; //допустимо hand[4] = {5, 6, 7, 9}; //недопустимо hand = cards; //недопустимо Однако можно, используя индексы, присваивать значения элементам массива индивидуально. Если массив инициализируется частично, то транслятор устанавливает для оставшихся элементов нулевые значения. Таким образом, можно легко присвоить всем элементам массива нуль – нужно лишь явно присвоить нуль первому элементу и предоставить компилятору инициализировать оставшиеся элементы: float totals[500] = {0}; Строки Строка – это ряд символов, хранящихся в последовательно расположенных байтах памяти. Строки имеют одну особенность: последний символ каждой строки – нулевой символ. Это символ, имеющий нулевой код ASCII (записывается как 0); он служит для обозначения конца строки. char dog[5] = {'b', 'e', 'a', 'u', 'x'}; //не строка! char cat[5] = {'f', 'a', 't', 's', '0'}; //строка Оба массива являются массивами символов, но только второй из них – строка. В строках нулевой символ играет фундаментальную роль. С++ имеет много функций, которые обрабатывают строки. Их работа строится по единому принципу: функция обрабатывает строку посимвольно до достижения нулевого символа.
  • 18. Теория и практика С++18 18 Имеется более лучший способ присвоения строки символьному массиву. Нужно просто использовать строку в кавычках, называемую строковой константой или строковым литералом. char bird[10] = "Mr. Cheep"; //подразумевается символ 0 в конце char fish[] = "Bubbles"; //предоставим компилятору определять размер массива ПОМНИТЕ Вычисляя минимальный размер массива, в который необходимо записать строку, не забывайте учитывать и конечный нулевой символ. Обратите внимание на то, что строковая константа (двойные кавычки) и символьная константа (одинарные кавычки) не являются взаимозаменяемыми. Символьная константа, такая как 'S', является короткой записью кода для символа. В системе ASCII запись 'S' – это просто другой способ записи числа 83. Таким образом, оператор char shirt_size = 'S'; //допустимо присваивает значение 83 переменной shirt_size. При этом "S" представляет собой строку, состоящую из двух символов, S и 0. char shirt_size = "S"; //запрещенное смешение типов Конкатенация строк Любые две строковые константы, разделенные только пробельными символами (пробелами, знаками табуляции и символами новой строки) автоматически объединяются в одну. Таким образом, все следующие операторы вывода эквивалентны: cout << "This is" " a map"; cout << "This is a map"; cout << "This is" " a map"; Использование строк в массиве Существует два наиболее распространенных способа записи строки в массив: первый – инициализация массива строковой константой, второй – считывание в массив результатов ввода с клавиатуры или из файла. В программе 3_2 используется функция стандартной библиотеки strlen(), чтобы узнать длину строки. Стандартный заголовочный файл cstring обеспечивает объявление для этой и многих других функций, связанных со строками. Программа 3_2 // программа p3_2.cpp - сохранение строк в массиве #include <iostream> #include <cstring> //для функции strlen() using namespace std; void main() { const int Size = 15; char name1[Size]; //пустой массив char name2[Size] = "C++owboy"; //инициализация массива cout << "Howdy! I'm " << name2; cout << "! What's your name?n"; cin >> name1; cout << "Well, " << name1 << ", your name has "; cout << strlen(name1) << " letters and is storedn"; cout << "in am array of " << sizeof name1 << " bytes.n"; cout << "Your initial is " << name1[0] << ".n"; name2[3] = '0'; //нулевой символ cout << "Here are the first 3 characters of my name: "; cout << name2 << "n"; } Результат: Howdy! I'm C++owboy! What's your name? Basicman
  • 19. Теория и практика С++19 19 Well, Basicman, your name has 8 letters and is stored in am array of 15 bytes. Your initial is B. Here are the first 3 characters of my name: C++ Проблемы при вводе строк Программа 3_3 // программа p3_3.cpp - чтение более чем одной строки #include "stdafx.h" #include <iostream> using namespace std; void main() { setlocale(LC_CTYPE, "RUS"); const int ArSize = 20; char name[ArSize]; char dessert[ArSize]; cout << "Введите свое имя: "; cin >> name; cout << "Введите свой любимый десерт: "; cin >> dessert; cout << "У меня есть вкусный " << dessert; cout << " для вас, " << name << ".n"; } Результат: Enter your name: Alistar Dreeb Enter your favorite dessert: I have some delicious Dreeb for you, Alistar. В программе с клавиатуры вводится имя пользователя и его любимый десерт, а затем отображается информации. Проблема заключается в том, что принцип работы cin основан на допущении, что для ограничения строки используются пробельные символы. Это означает, что cin считывает только одно слово, когда он становится входным для символьного массива, и помещает строку в массив, автоматически добавляя конечный нулевой символ. На практике у нас получается следующее: cin считает Alistar как полную первую строку и помещает ее в массив name, а слово Dreeb остается в очереди ввода. Когда cin ищет очередь ввода для ответа на вопрос о любимом десерте, то находит там слово Dreeb. Тогда cin, недолго думая, "проглатывает" Dreeb" и помещает слово в массив dessert. Следующая проблема заключается в следующем. cin не дает возможности предотвратить помещение 30- символьной строки в 20-символьный массив Ввод ориентированный на строки: функции getline() Функция getline() читает целую строку, используя переданный с помощью клавиши ENTER символ новой строки, чтобы пометить конец ввода. Для обращения к этому методу используется следующий вызов функции: cin.getline(). Функция требует передачи двух параметров. Первый – имя массива, предназначенного для сохранения введенной строки, а второй ограничивает количество символов, которые нужно считать. cin.getline(name,20); Программа 3_4 // программа p3_4.cpp - чтение более одного слова с помощью функции getline #include <iostream> using namespace std; void main() {
  • 20. Теория и практика С++20 20 setlocale(LC_CTYPE, "RUS"); const int ArSize = 20; char name[ArSize]; char dessert[ArSize]; cout << "Введите ваше имя: "; cin.getline(name, ArSize); // читать до символа новой строки cout << "Введите ваш любимый десерт: "; cin.getline(dessert, ArSize); cout << "У меня есть вкусный " << dessert; cout << " для вас, " << name << ".n"; } Результат: Enter your name: Dirk Hammernose Enter your favorite dessert: Ice-cream I have some delicious Ice-cream for you, Dirk Hammernose. Теперь программа читает полные имена и отображает для пользователя заказанные десерты! Функция getline() воспринимает строку "в один присест". Она читает вводимые данные до конца символа новой строки, который обозначает конец строки, однако не сохраняет его, а заменяет при сохранении строки нулевым символом. Смешанный ввод строк и чисел Смешанный ввод строк и чисел с помощью ориентированный на строки функций может вызывать затруднения. Программа 3_5 // программа p3_5.cpp - чередование ввода чисел и строк #include "stdafx.h" #include <iostream> using namespace std; void main() { setlocale(LC_CTYPE, "RUS"); cout << "В каком году построен ваш дом? n"; int year; cin >> year; cout << "По какому адресу он расположен? n"; char address[80]; cin.getline(address, 80); cout << "Год постройки: " << year << endl; cout << "Адрес: " << address << endl; cout << "Готово! n"; } Результат: What year was your house built? 1996 What is its street address? Year built: 1996 Address: Done! При работе с данной программой пользователь никогда не получит возможности ввести адрес. Проблема состоит в том, что объект cin, считав значение года, оставляет символ новой строки, сгенерированный с помощью клавиши ENTER, во входной очереди. Затем функция cin.getline() воспринимает символ новой строки так, как будто это пустая строка, и присваивает нулевую строку элементу массива address. Чтобы исправить ошибку, следует считать и отбросить символ новой строки перед чтением адреса. Это можно сделать при помощи функции cin.get().
  • 21. Теория и практика С++21 21 cin >> year; cin.get(); СТРУКТУРЫ Структура – более универсальная форма данных, чем массив, поскольку может содержать элементы, относящиеся к различным типам данных. Структура – определяемый пользователем тип данных. Объявление структуры служит для того, чтобы задавать свойства типов данных. После определения типа можно создавать переменные этого вновь созданного типа. Таким образом, создание структуры предусматривает два этапа. Сначала создается описание структуры. Затем можно создавать структурные переменные. struct inflatable //описание структуры { char name[20]; //элемент типа array float volume; //элемент типа float double price; //элемент типа double }; Ключевое слово struct указывает на то, что код определяет компоновку структуры. Идентификатор inflatable – имя, или дескриптор, для этой формы. Таким образом, inflatable представляет собой имя нового типа данных. Между фигурными скобками находится список типов данных, которые будут содержаться в структуре. Каждый элемент списка – это оператор объявления. Каждый отдельный элемент в списке называется элементом структуры. Когда шаблон готов, можно создавать переменные данного типа: inflatable hat; //hat - структурная переменная типа inflatable inflatable woopie_cushion; //структурная переменная типа inflatable inflatable mainfraim; //структурная переменная типа inflatable Поскольку переменная hat имеет тип inflatable, для обращения к отдельным элементам можно использовать оператор принадлежности (.). Например, выражение hat.volume указывает на элемент volume структуры. Программа 3_6 // программа p3_6.cpp - простая структура #include <iostream> using namespace std; struct inflatable { char name[20]; float volume; double price; }; void main() { inflatable guest = { "Glorious Gloria", 1.88, 29.99 }; inflatable pal = { "Audacious Arthur", 3.12, 32.99 }; cout << "Expand your guest list with " << guest.name;
  • 22. Теория и практика С++22 22 cout << " and " << pal.name << "!n"; cout << "You can have both for $"; cout << guest.price + pal.price << "!n"; } Результат: Expand your guest list with Glorious Gloria and Audacious Arthur! You can have both for $62.98! Примечание к программе Существует один важный момент, который состоит в том, чтобы определить, где следует размещать объявление структуры. Возможны два варианта. Первый (внутреннее объявление) – поместить объявление структуры внутри функции main() сразу после отрывающей скобки. Второй (внешнее объявление) - поместить объявление структуры перед функцией main(). Внешнее объявление может использовать всеми функциями, следующими за main(), тогда как внутреннее объявление может быть использовано только той функцией, в которой оно содержится. Другие свойства структур Можно передавать структуры функциям в качестве аргументов, а также использовать структуру, как возвращаемое значение функции. Кроме того, допускается использование оператора присвоения (=), чтобы присвоить значение одной структуры другой структуре того же типа. Данный вид операции называется поэлементным присваиванием. Программа 3_7 // программа p3_7.cpp - присвоение значений структурам #include <iostream> using namespace std; struct inflatable { char name[20]; float volume; double price; }; void main() { inflatable bouquet = { "sunflowers", 0.20, 12.49 }; inflatable choice; cout << "bouquet: " << bouquet.name << " for $"; cout << bouquet.price << "!n"; choice = bouquet; //присвоение значения одной структуры другой структуре cout << "choice: " << choice.name << " for $"; cout << choice.price << "!n"; } Результат: bouquet: sunflowers for $12.49! choice: sunflowers for $12.49! Указатели и свободная память Три фундаментальных свойства, которые должна учитывать компьютерная программа при сохранении данных. Перечислим их:  где хранится информация  какое значение там, хранится  вид хранящейся информации
  • 23. Теория и практика С++23 23 Для реализации этих свойств использовался один из возможных методов — определение простой переменной. Оператор объявления определяет тип и символическое имя значения, а также заставляет программу выделить область памяти для значения и внутренними средствами отслеживать ее адрес. Теперь рассмотрим второй метод. Он приобретает особое значение при разработке классов C++. Этот метод основан на указателях, которые являются переменными, сохраняющими адреса значений вместо непосредственно самих значений. Но прежде чем, рассматривать указатели, обратимся к способу явного определения адресов обычных переменных. Этот способ заключается в применении к переменной операции определения адреса, представленной знаком &. Например, если home – переменная, &home является ее адресом. Программа 3_8 // использование оператора & для определения адреса #include <iostream> using namespace std; void main() { int donuts = 6; double cups = 4.5; cout << "donuts value = " << donuts; cout << " and donuts address = " << &donuts << "n"; cout << "cups value = " << cups; cout << " and cups address = " << &cups << "n"; } Результат: donuts value = 6 and donuts address = 0012FF7C cups value = 4.5 and cups address = 0012FF74 При отображении адресов объект cout использует шестнадцатеричное представление, потому что оно обычно применяется для записи адресов памяти. В нашей реализации значение переменной cups хранится в ячейке памяти с меньшей величиной адреса по сравнению с переменной donuts. Разность между двумя адресами составляет 8. Это имеет смысл, поскольку переменная cups имеет тип double, размерность которого составляет восемь байта. Конечно, в разных системах значения адресов будут различными. Кроме того, значение переменной donuts может предшествовать в памяти значению переменной cups. При этом разница адресов будет составлять 8 байтов, поскольку переменная donuts имеет тип int. Используя в таком случае обыкновенные переменные, можно обработать значение как именованную величину, а его адрес как производную величину. Теперь ознакомимся с принципом использования указателей, который занимает важное место в философии языка C++ относительно программного управления памятью. В соответствии с новой стратегией обработки хранящихся в памяти данных местоположение значения трактуется как именованная величина, а значение — как производная (порожденная) величина. Специальный тип переменной – указатель – содержит адрес значения. Таким образом, имя указателя представляет местонахождение значения в памяти. Применяя операцию *, называемую косвенным значением или операцией разыменованием, получаем значение, хранящееся по данному адресу. Предположим, что manly – указатель. Тогда выражение manly представляет собой адрес, а *manly – значение по данному адресу. Комбинация *manly становится эквивалентом обычной переменной типа int. Эти моменты отражены в программе 3_9. Здесь также показано, как объявлять указатель. Программа 3_9 // наша первая переменная-указатель #include <iostream> using namespace std; void main() { int updates = 6; //объявление переменной int *p_updates; //объявление указателя на значением типа int p_updates = &updates; //присвоение адреса значения типа int указателю //выражения значений двумя способами cout << "Values: updates = " << updates; cout << ", *p_updates = " << *p_updates << "n"; //выражение адресов двумя способами cout << "Addresses: &updates = " << &updates;
  • 24. Теория и практика С++24 24 cout << ", p_updates = " << p_updates << "n"; //использование указателя для изменения значения *p_updates = *p_updates + 1; cout << "Now updates = " << updates << "n"; } Результат: Values: updates = 6, *p_updates = 6 Addresses: &updates = 0012FF7C, p_updates = 0012FF7C Now updates = 7 Очевидно, что переменная updates типа int и переменная-указатель p_updates являются всего лишь двумя сторонами одной и той же медали. Переменная updates представляет прежде всего значение, а операция & используется для получения адреса, тогда как переменная p_updates представляет адрес, а операция * служит для получения значения. Поскольку p_updates указывает на значение updates, выражения *p_updates и updates совершенно эквиваленты. Выражение *p_updates можно использовать точно так же, как переменную типа int. Как видно из программы, можно даже присваивать значения переменной *p_updates. При этом изменяется указываемое значение переменной updates. Объявление и инициализация указателей Рассмотрим процесс объявления указателей. Компьютеру необходимо отслеживать тип значения, на которое ссылается указатель. Например, адрес переменной типа char выглядит так же, как и адрес переменной типа double, но для типов char и double используется различное количество байтов и различные внутренние форматы для хранения значений. Поэтому при объявлении указателя необходимо точно определять, на какой тип данных он указывает. Последний пример содержит следующее объявление: int *p_updates; Это выражение указывает, что комбинация *p_updates принадлежит к типу int. Поскольку операция * выполняется по отношению к указателю, переменная p_updates сама должна быть указателем. Мы говорим, что p_updates указывает на значение типа int. Мы также говорим, что типом для p_updates должен быть указатель на int или, более кратко, int *. Повторим: p_updates является указателем (адресом), a *p_updates — переменной типа int, но не указателем (рис. 2). int jumbo = 23; int *pe = &jumbo; эти выражения эквива- лентны эти выражения эквива- лентны jumbo *pe &jumbo pe значение 23 адрес 0x2ac8 Две стороны одной медали Рисунок 1 1000 1002 1004 1006 1008 1010 1012 1014 1016 адрес в памяти имя переменной int ducks = 12; ducks birddog 12 1000 birddog ducks указывает на int *birddog = &ducks; создает переменную и сохраняет в ней значение 12 ducks создает переменную и сохраняет в ней адрес birddog ducks Рисунок 2 В указателях хранится адрес
  • 25. Теория и практика С++25 25 Отметим, что отделять пробелами знак операции * не обязательно. Программисты, работающие на С, традиционно применяют следующую форму записи: int *ptr; При использовании данной формы записи подчеркивается то, что комбинации *ptr имеет значение типа int. Широко распространена и другая форма этого выражения: int* ptr; В ней акцентируется внимание на том, что int* — это тип "указатели на int". Компилятору же совершенно безразлично, где будут размещены пробелы. Однако не следует упускать из виду, что, например, объявление int* p1, p2; создает один указатель (р1) и одну обычную переменную (р2), другими словами, необходимо использовать знак * для каждого имени объявляемой переменной-указателя. Для объявления указателей на другие типы переменных используется аналогичный синтаксис: double *tax_ptr; // tax_ptr указывает на тип double char *str; // str указывает на тип char Поскольку tax_ptr объявляется как указатель на тип double, компилятор определяет, что значение *tax_ptr принадлежит к типу double. Другими словами, он распознает, что *tax_ptr представляет собой величину, которая хранится в формате с плавающей точкой и занимает (в большинстве систем) восемь байтов. Переменная-указатель никогда не бывает просто указателем. Она всегда указывает на определенный тип данных. Так, переменная tax_ptr имеет тип "указатель на тип double" (или тип double*), a str — "указатель на тип char" (или char*). Несмотря на то, что обе переменные являются указателями, они указывают на два различных типа данных. Подобно массивам, указатели являются производными от других типов данных. Заметим, что в то время, как tax_ptr и str указывают на типы данных, имеющие различную размерность, сами по себе две переменные — tax_ptr и str — имеют одинаковый размер. Иными словами, адрес переменной типа char имеет тот же размер, что и адрес переменной типа double (точно так же, как номер дома 1016 может означать адрес большого универмага, а 1024 — адрес маленького коттеджа). По размеру или значению адреса ничего нельзя сказать о размере или типе переменной, так же, как и по номеру дома — о здании, которое находится по этому адресу. Обычно для хранения адреса требуются два или четыре байта, в зависимости от компьютера. Для инициализации указателя можно использовать оператор объявления. В этом случае инициализируется указатель, а не указываемое значение. Таким образом, следующие операторы: int higgens = 5; int *pt = &higgens; присваивают указателю pt (но не *pt) значение &higgens. В программе 3_10 демонстрируется инициализация указателя с присвоением ему адреса. Программа 3_10 // программа p3_10.cpp - инициализация указателя #include <iostream> using namespace std; void main() { int higgens = 5; int *pi = &higgens; cout << "Value of higgens = " << higgens << "; Address of higgens = " << &higgens << "n"; cout << "Value of *pi = " << *pi << "; Address of pi = " << pi << "n"; } Результат: Value of higgens = 5; Address of higgens = 0012FF7C Value of *pi = 5; Address of pi = 0012FF7C Можно видеть, что программа присваивает адрес переменной higgens указателю pi, но не значению *pi. Отметим однако, что неосторожное использование указателей может привести к нежелательным последствиям. Крайне важно не забывать о том, что при создании указателя в C++ компьютер выделяет память для хранения адреса, но не для хранения данных, на которые указывает этот адрес. Чтобы выделить места для