Презентацию к лекции Вы можете скачать здесь.
Программа на языке С++ состоит из функций, описаний и директив
Одна (и только одна) функция программы должна иметь имя main. Выполнение программы начинается с первого оператора этой функции. Ее вызывает на выполнение исполняющая система.
Описания представляют собой определения и объявления элементов программы:
ПРИМЕЧАНИЕ
Такие требования естественны: ведь определения требуют от компилятора конкретных действий (например, выделения памяти), а объявления служат для информации.
Итак, программа, состоящая из одного модуля, имеет следующую структуру:
директивы препроцессора
описания
int main()
{
операторы главной функции
}
В общем случае программа состоит из нескольких модулей, каждый из которых может содержать все рассмотренные элементы.
Любая программа работает с данными. В простейшем случае данные хранят в переменных. Переменная - это
Перед использованием любая переменная должна быть определена. Пример описания целой переменной с именем a и вещественной переменной: x
int a; float x;
В общем случае описание переменной задает не только ее имя и тип, но и другие характеристики, например, начальное значение,
Область действия имени - это часть программы, в которой его можно использовать для доступа к связанной с ним области памяти. В зависимости от области действия переменная может быть локальной или глобальной.
Если переменная определена внутри блока (блок ограничен
СОВЕТ
Глобальные переменные нужно стремиться использовать как можно реже. Переменная должна иметь минимальную из возможных областей видимости и действия, поскольку это значительно облегчает поиск ошибок.
Время жизни глобальных и
Кроме времени жизни и области действия,
Рассмотрим общий вид оператора
[класс_памяти] [const] тип имя [инициализатор];
Начнем с
= выражение
или в круглых скобках:
( выражение )
Выражение должно быть вычисляемым на момент выполнения оператора, например:
short int a = 1; short int b( a + 1 );
Первая форма инициализации чаще применяется для переменных
Модификатор показывает, что данное описание определяет не переменную, а именованную константу. Константа должна быть обязательно инициализирована при объявлении. Ключевое слово можно задавать как перед типом, так и после него.
В одном операторе можно определить несколько величин одного типа, разделяя их запятыми. Примеры:
const char C = 'C', X = '|'; // символьные константы С и X int const y = 56; // целая константа y char s, sf = 'f'; // инициализация относится только к sf char t (54); float c = 0.22, x(3), sum;
Класс памяти задается явным образом или по контексту описания переменной. Если он не задан явно, и переменная описана внутри блока (в частности, внутри функции main ), она считается автоматической. Память под нее выделяется при входе в блок и при необходимости инициализируется каждый раз при выполнении оператора, содержащего ее определение.
Класс памяти задает статическую переменную. Время ее жизни равно времени работы программы (как у глобальных переменных), а инициализируется она один раз при первом выполнении оператора, содержащего определение переменной. В зависимости от расположения
Ключевое слово хотя и относится в стандарте к спецификаторам , должна быть определена в другом месте программы (как правило, в другом модуле).
может задаваться и в определении переменной, но при этом переменная обязательно должна быть проинициализирована, например:
extern double PI = 3.1415926; // это определение переменной PI
В одномодульной программе использовать
int a; // 1 глобальная переменная a
int main() // 2
{ int b; // 3 локальная переменная b
static int c; // 4 локальная статическая переменная c
a = 1; // 5 присваивание глобальной переменной
int a; // 6 локальная переменная a
a = 2; // 7 присваивание локальной переменной
::a = 3; // 8 присваивание глобальной переменной
extern int x; // 9 переменная х объявлена; определение дальше
...
return 0; // 10
} // 11
int x = 4; // 12 определение и инициализация x
Здесь a определена вне всех блоков, областью ее действия является вся программа. Переменная создается при запуске программы и уничтожается при окончании ее работы.
Переменные b и c - локальные, область их видимости (и действия) - блок, но время жизни различно: переменная b "рождается" при входе в блок и "умирает" при выходе из него, а переменная c, как и a, создается при запуске программы и существует все время, пока работает программа.
Переменная х является глобальной и определена после main. (строка 9).
Если при определении переменных их начальные значения явным образом не заданы, глобальные и
Любая программа каким-либо образом взаимодействует с внешним миром. В простейшем случае это работа с консолью: ввод с клавиатуры и вывод на экран. В языке С++ нет встроенных средств ввода/вывода - он осуществляется с помощью средств, содержащихся в
// используются классы стандартной библиотеки
#include <iostream> // 1
using namespace std; // 2
int main() // 3
{ const double course = 35.8; // 4
double sum; // 5
cout << "Введите сумму в рублях:\n"; // 6
cin >> sum; // 7
double euro = sum / course; // 8
cout << "В рублях: " << sum
<< " В евро: " << euro
<< "\n"; // 9
return 0; // 10
}
Это первый пример законченной программы, поэтому рассмотрим его подробно. В первой строке записана
#include <имя_файла>
вставляет содержимое указанного файла (он называется заголовочным ) в ту точку исходного файла, где она расположена. В данном случае
Строка 2 является описанием, по которому программе становятся доступными все имена, определенные в стандартном
Конечно, открытие всех стандартных имен из заголовочного файла не может предотвратить подобный конфликт, но есть средства, позволяющие сделать доступными не все, а только нужные имена. Они будут рассмотрены позже.
ПРИМЕЧАНИЕ
Для многих заголовочных файлов, содержимое которых определено в пространстве имен , существуют их двойники "старого стиля" с расширением .h,описания, находящиеся в которых, доступны без дополнительных усилий - например, <iostream.h>, <stdio.h>. c. Этот способ использования заголовочных файлов считается устаревшим.
Строка 3 представляет собой заголовок главной (и единственной) функции, в строках 4 и 5 описаны две величины с плавающей точкой: константа и переменная . Строка 6 является приглашением к вводу. В результате выполнения этого оператора на экран выводится строка "Введите сумму в рублях:" и курсор переводится на следующую строку в соответствии с \n.
Стандартному объекту cout с помощью операции << передается то, что мы хотим вывести, в данном случае
В процессе ввода ( строка 7 ) происходит обратный процесс: величина преобразуется из последовательности символов, набранных на клавиатуре, во внутреннее представление числа с плавающей точкой и помещается в ячейку памяти, зарезервированную для переменной . Как видите,
В строке 8 определяется переменная euro, которая инициализируется результатом деления переменной на переменную . В строке 10 в вызывающую среду возвращается значение 0 - признак успешного завершения программы. Оператор return 0 в главной функции записывать не обязательно, поскольку при его отсутствии значение 0 будет возвращено автоматически. Во всех последующих примерах этот оператор опущен для экономии места.
Другой вариант записи той же программы приведен в листинге 2.2.
// используются функции ввода/вывода в стиле С
#include <сstdio> // 1
using namespace std; // 2
int main() // 3
{ const double course = 36.5; // 4
double sum; // 5
printf( "Введите сумму в рублях\n" ); // 6
scanf( "%lf", sum ); // 7
double euro = sum / course; // 8
printf( "В рублях: %lf В евро: %lf\n", sum, euro ); // 9
}
По директиве printf в строке 6 выводит приглашение "Введите сумму в рублях:" и переходит на новую строку в соответствии с \n. Функция scanf в строке 7 заносит введенное с клавиатуры число в переменную .
Знак обозначает операцию получения . Это нужно чтобы функция scanf могла записать в эту переменную введенное с клавиатуры значение.
Формат основных функций ввода-вывода, унаследованных из С:
int scanf ( строка_формата, список адресов вводимых величин ) // ввод int printf( строка_формата, список выводимых величин ) // вывод
Функции выполняют форматированный ввод и вывод произвольного количества величин в соответствии со строкой формата. Она содержит символы, которые копируются на экран при выводе или запрашиваются с клавиатуры при вводе, и спецификации преобразования, начинающиеся со знака %, которые при вводе и выводе заменяются конкретными величинами. Каждой величине должна соответствовать своя спецификация.
Спецификация %d означает целое десятичное число, %f используется для величин типа , %lf - для величин типа double. Оператор в строке 9 выводит на экран указанную в нем строку, заменив %lf на значения переменных и euro.
Для каждой программы необходимо выбрать один из способов вывода (либо с помощью классов, либо с помощью функций), поскольку смешивать оба варианта не рекомендуется. Функции ввода/вывода в стиле С имеет смысл использовать в тех программах, где требуется тщательное форматирование результатов, а классы - в остальных случаях.
Задача вывода русских букв в консольное окно является частным случаем сложной проблемы локализации приложений. К
MS к системе Windows. В консольном окне Windows по умолчанию используется кодировка, принятая в MS , для того чтобы старые программы MS правильно работали в консольном окне Windows.
Однако Visual Studio.NET 2005 работает в системе Windows, в которой по умолчанию установлена другая кодовая страница. Русские символы, набираемые в окне редактора среды, имеют другую кодировку, и поэтому в консольном окне видны как "иероглифы".
Есть множество способов решения этой проблемы. Самый простой - вообще отказаться от русских букв. Если же все-таки хочется их использовать, проще всего воспользоваться функцией setlocale, унаследованной из языка С (она описана в
setlocale( LC_ALL, "Russian" ); setlocale( LC_ALL, "rus" );
Любой из этих вызовов устанавливает русскую локаль,после чего русские константы выводятся в консольное окно по-русски при использовании и printf, и cout.
Чтобы русификация консольного окна работала, необходимо, чтобы в операционной системе Windows в настройках языков и стандартов была установлена кириллица по умолчанию.
В любой программе требуется производить вычисления. Для
( a + 0.12 ) / 6 x y || ! z ( t * sin( x ) - 1.05e4 ) / ( ( 2 * k + 2 ) * (2 * k + 3 ) ) a = b = c b++ cout << a i++, j++
Операнды задают данные для вычислений. Операции задают действия, которые необходимо выполнить. Каждый
Язык С++ предоставляет в наше распоряжение внушительный набор операций: арифметические, логические, поразрядные,
| Операция | Краткое описание |
|---|---|
| ++ | постфиксный |
| -- | постфиксный |
sizeof |
размер объекта или типа |
| -- | префиксный |
| ++ | префиксный |
| ! | логическое |
| - | арифметическое |
| + | унарный плюс |
| (<тип>) | преобразование типа |
| Бинарные и | |
| * | |
| / | деление |
| % | |
| + | |
| - | |
| < | меньше |
| <= | меньше или равно |
| > | больше |
| >= | больше или равно |
| == | равно |
| != | не равно |
| логическое И | |
| || | |
| ? : | условная операция (тернарная) |
| = | присваивание |
| *= | |
| /= | деление с присваиванием |
| %= | |
| += | |
| -= | |
| , | последовательное вычисление |
Операции расположены в порядке убывания С++ огорчительно много, поэтому в случае сомнений надо не лениться обращаться к справочной информации. Основные правила, тем не менее, просты и соответствуют принятым в математике: например,
Если в одном выражении записано несколько операций одинакового приоритета, то a = b = c означает a = (b = c), а a + b + c означает (a + b) + c.
Порядок вычисления операндов в выражении не определен: например, нельзя считать, что в выражении (sin(x + 2) + обращение к синусу будет выполнено раньше, чем к косинусу. Только четыре операции гарантируют порядок вычислений слева направо: ,, ?:, и ||.
Результат вычисления выражения характеризуется значением и типом. Например, пусть описаны две переменные
Тогда выражение a + b имеет значение 7 и тип . В С++ различаются так называемые L-значения (L-value) и R-значения (R-value). Название произошло от
L -значением (от слова Left - левый), может располагаться как с левой, так и с правой стороны R -значением (от слова Right - правый), может располагаться только с правой, но никак не с левой стороны Выражения возвращают в качестве результата либо L -значения, либо R -значения. Переменная - частный случай L -значения, а константа - частный случай R -значения. Более общим случаем R -значения является обычное L -значением в общем случае может быть не только переменная, но и некоторое выражение, ссылающееся на область памяти. В дальнейшем мы будем указывать, какие операции возвращают L -значение.
Рассмотрим подробнее некоторые операции.
Операции присваивания ( =, +=, -=, *= и т. д.). Формат операции простого присваивания ( = ):
операнд_1 = операнд_2
Левым операндом должно быть L -значение, а правым - любое выражение. Сначала вычисляется выражение, стоящее в правой части операции, а потом его результат записывается в область памяти, ссылка на которую стоит в левой части (мнемоническое правило: "присваивание - это
Если
Выражение с операцией присваивания может участвовать в качестве операнда в других выражениях. Например, оно может быть
Результат выражения с присваиванием является L -значением, поэтому выражение с присваиванием может быть аргументом другой a = b = c: сначала вычисляется выражение b = c, а затем его результат становится правым операндом для a.
Выражения с операциями присваивания могут использоваться и как самостоятельные операторы. Для этого нужно после выражения поставить точку с запятой. Пример
#include <iostream>
using namespace std;
int main()
{ int a = 3, b = 5, с = 7; // инициализация
a = b; b = a; с = с + 1; // присваивание
cout << "a = " << a
<< "\t b = " << b
<< "\t c = " << c;
с = a + ( b = 5 );
cout << "\t c = " << c;
}
Результат работы программы:
a = 5 b = 5 c = 8 с = 10
В составных операциях присваивания ( +=, *=, /= и т. п.) при L -значение из левой части. Например, при сложении с присваиванием к значению левого операнда прибавляется значение правого, и результат записывается в левый a += b является более компактной записью выражения a = a + b.
Операции увеличения и уменьшения на 1 ( ++ и -- ). Эти операции, называемые также
#include <cstdio>
using namespace std;
int main()
{ int x = 3, y = 3;
printf( "Значение префиксного выражения: %d \n", ++x );
printf( "Значение постфиксного выражения: %d \n", y++ );
printf( "Значение х после приращения: %d \n", x );
printf( "Значение у после приращения: %d \n", у );
}
Результат работы программы:
Значение префиксного выражения: 4 Значение постфиксного выражения: 3 Значение х после приращения: 4 Значение у после приращения: 4
Как и выражения с присваиванием, выражения с
Операции отрицания ( !) дает в результате значение false, если true, и значение true, если false. bool.
Деление ( / ) и остаток от деления ( % ). Операция деления применима к операндам арифметического типа. Если оба операнда целочисленные, результатом операции является целая часть частного (дробная часть отсекается). Например, результатом 5/2 будет 2. Если же хотя бы один
#include <cstdio>
using namespace std;
int main()
{int x = 11, y = 4;
float z = 4;
printf( "Результаты деления: %d %f \n", x / y, x / z );
printf( "Остаток: %d \n", x % y );
}
Результат работы программы:
Результаты деления: 2 2.750000 Остаток: 3
Операции отношения (<, <=, >, >=, ==, !=) сравнивают первый true или false. Операции сравнения на равенство и неравенство имеют меньший приоритет, чем остальные операции сравнения.
ВНИМАНИЕ
Обратите внимание на разницу между операцией проверки на равенство ( == ) и операцией присваивания ( = ), результатом которой является значение, присвоенное левому операнду.
Логические операции ( и ||). bool, при этом true или false. Результат операции логическое И имеет значение true только если оба операнда имеют значение true. Результат операции логическое ИЛИ имеет значение true,
если хотя бы один из операндов имеет значение true. Логические операции выполняются слева направо. Если значения первого операнда достаточно, чтобы определить результат операции, второй
Условная операция ( ?:).Эта единственная в С++ тернарная операция (имеет три операнда), ее формат:
операнд_1 ? операнд_2 : операнд_3
bool. Если результат равен true, то результатом выполнения всей условной операции будет значение второго операнда, иначе - третьего операнда. Их типы могут быть различными.
Пример: пусть требуется, чтобы некоторая целая величина увеличивалась на 1, если ее значение не превышает n, а иначе принимала значение 1. Это можно записать с помощью одной строки кода:
i = ( i < n ) ? i + 1 : 1;
Операция последовательного вычисления "запятая" (,). Формат операции:
выражение_1, выражение_2
Операция выполняется слева направо: сначала вычисляется выражение слева от знака операции (его результат отбрасывается), а затем вычисляется выражение справа от знака и его результат принимается за результат операции. Вычисление левого выражения обязательно завершается до того, как начнется вычисление правого выражения. Это позволяет присваивать значения переменным в левом выражении, а затем использовать их в правом.
Например, результатом операции j = 2, j = 1 будет 1, результатом операции j = 2, j++ будет 2, а результатом операции j = 2, ++j будет 3.
Стандарт разрешает любое выражение заменить последовательностью выражений, разделенных операцией "запятая". Результатом вычисления последовательности выражений будет значение самого правого выражения.
Операции, не рассмотренные в этом разделе, будут описаны по мере необходимости.
В выражение могут входить
( char, short ) -> int -> unsigned int -> long -> unsigned long -> float -> double -> long double
Это не означает, что преобразование типа в double выполняется последовательно по цепочке, просто менее "объемный" тип преобразуется к более "объемному". Типы и перед выполнением операции обязательно преобразуются к . Типом результата выражения обычно является самый "объемный" из типов операндов.
Однако в выражениях с операцией присваивания встречается и обратный вариант, когда более "объемный" тип присваивается менее "объемному", например, в . Подобные преобразования связаны с потерей информации (дробная часть отбрасывается), поэтому называются сужающими приведениями (преобразованиями). Компилятор предупреждает о таких операциях.
В логических операциях и условной операции выполняется bool. При этом любое значение, не равное нулю (даже отрицательное), трактуется как true, а нуль считается false. При обратных преобразованиях величин типа bool к целому типу значение true преобразуется в целую константу 1, а значение false - в 0.
Программист может задать явное преобразование типа. Операция
( тип ) выражение тип ( выражение )
Результатом операции является значение заданного типа, например:
int a = 2; float b = 6.8; printf( "%lf %d", double ( a ), ( int ) b );
Величина a преобразуется к типу double, а переменная b - к типу с отсечением дробной части (сужающее приведение).
Явное преобразование типа в стиле С оставлено в С++ только для совместимости. Использовать его не рекомендуется, поскольку оно слишком универсально, а потому чревато плохо диагностируемыми ошибками.
В стандарте С++ определено четыре специализированных операций
static_cast<тип>( выражение ) reinterpret_cast<тип>( выражение ) dynamic_cast<тип>( выражение ) const_cast<тип>( выражение )
В зависимости от вида преобразования необходимо использовать соответствующую ему операцию приведения типа. Приведение типа static_cast<T>(e) используется между родственными типами. Его может проверить компилятор. Операция reinterpret_cast выполняет преобразование типов без проверки при компиляции. Оно часто необходимо тогда, когда точно известно, что объекты разных типов занимают в памяти одинаковое количество байт и фактического преобразования делать как раз не нужно. Операция const_cast аннулирует действие модификатора и применяется достаточно редко. Операция dynamic_cast выполняет преобразование во время работы программы и применяется для преобразования указателей и ссылок родственных полиморфных классов. Примеры применения этих операций вы увидите в следующих лекциях.
Презентацию к лекции Вы можете скачать здесь.
Программа на языке С++ состоит из функций, описаний и директив
Одна (и только одна) функция программы должна иметь имя main. Выполнение программы начинается с первого оператора этой функции. Ее вызывает на выполнение исполняющая система.
Описания представляют собой определения и объявления элементов программы:
ПРИМЕЧАНИЕ
Такие требования естественны: ведь определения требуют от компилятора конкретных действий (например, выделения памяти), а объявления служат для информации.
Итак, программа, состоящая из одного модуля, имеет следующую структуру:
директивы препроцессора
описания
int main()
{
операторы главной функции
}
В общем случае программа состоит из нескольких модулей, каждый из которых может содержать все рассмотренные элементы.
Любая программа работает с данными. В простейшем случае данные хранят в переменных. Переменная - это
Перед использованием любая переменная должна быть определена. Пример описания целой переменной с именем a и вещественной переменной: x
int a; float x;
В общем случае описание переменной задает не только ее имя и тип, но и другие характеристики, например, начальное значение,
Область действия имени - это часть программы, в которой его можно использовать для доступа к связанной с ним области памяти. В зависимости от области действия переменная может быть локальной или глобальной.
Если переменная определена внутри блока (блок ограничен
СОВЕТ
Глобальные переменные нужно стремиться использовать как можно реже. Переменная должна иметь минимальную из возможных областей видимости и действия, поскольку это значительно облегчает поиск ошибок.
Время жизни глобальных и
Кроме времени жизни и области действия,
Рассмотрим общий вид оператора
[класс_памяти] [const] тип имя [инициализатор];
Начнем с
= выражение
или в круглых скобках:
( выражение )
Выражение должно быть вычисляемым на момент выполнения оператора, например:
short int a = 1; short int b( a + 1 );
Первая форма инициализации чаще применяется для переменных
Модификатор показывает, что данное описание определяет не переменную, а именованную константу. Константа должна быть обязательно инициализирована при объявлении. Ключевое слово можно задавать как перед типом, так и после него.
В одном операторе можно определить несколько величин одного типа, разделяя их запятыми. Примеры:
const char C = 'C', X = '|'; // символьные константы С и X int const y = 56; // целая константа y char s, sf = 'f'; // инициализация относится только к sf char t (54); float c = 0.22, x(3), sum;
Класс памяти задается явным образом или по контексту описания переменной. Если он не задан явно, и переменная описана внутри блока (в частности, внутри функции main ), она считается автоматической. Память под нее выделяется при входе в блок и при необходимости инициализируется каждый раз при выполнении оператора, содержащего ее определение.
Класс памяти задает статическую переменную. Время ее жизни равно времени работы программы (как у глобальных переменных), а инициализируется она один раз при первом выполнении оператора, содержащего определение переменной. В зависимости от расположения
Ключевое слово хотя и относится в стандарте к спецификаторам , должна быть определена в другом месте программы (как правило, в другом модуле).
может задаваться и в определении переменной, но при этом переменная обязательно должна быть проинициализирована, например:
extern double PI = 3.1415926; // это определение переменной PI
В одномодульной программе использовать
int a; // 1 глобальная переменная a
int main() // 2
{ int b; // 3 локальная переменная b
static int c; // 4 локальная статическая переменная c
a = 1; // 5 присваивание глобальной переменной
int a; // 6 локальная переменная a
a = 2; // 7 присваивание локальной переменной
::a = 3; // 8 присваивание глобальной переменной
extern int x; // 9 переменная х объявлена; определение дальше
...
return 0; // 10
} // 11
int x = 4; // 12 определение и инициализация x
Здесь a определена вне всех блоков, областью ее действия является вся программа. Переменная создается при запуске программы и уничтожается при окончании ее работы.
Переменные b и c - локальные, область их видимости (и действия) - блок, но время жизни различно: переменная b "рождается" при входе в блок и "умирает" при выходе из него, а переменная c, как и a, создается при запуске программы и существует все время, пока работает программа.
Переменная х является глобальной и определена после main. (строка 9).
Если при определении переменных их начальные значения явным образом не заданы, глобальные и
Любая программа каким-либо образом взаимодействует с внешним миром. В простейшем случае это работа с консолью: ввод с клавиатуры и вывод на экран. В языке С++ нет встроенных средств ввода/вывода - он осуществляется с помощью средств, содержащихся в
// используются классы стандартной библиотеки
#include <iostream> // 1
using namespace std; // 2
int main() // 3
{ const double course = 35.8; // 4
double sum; // 5
cout << "Введите сумму в рублях:\n"; // 6
cin >> sum; // 7
double euro = sum / course; // 8
cout << "В рублях: " << sum
<< " В евро: " << euro
<< "\n"; // 9
return 0; // 10
}
Это первый пример законченной программы, поэтому рассмотрим его подробно. В первой строке записана
#include <имя_файла>
вставляет содержимое указанного файла (он называется заголовочным ) в ту точку исходного файла, где она расположена. В данном случае
Строка 2 является описанием, по которому программе становятся доступными все имена, определенные в стандартном
Конечно, открытие всех стандартных имен из заголовочного файла не может предотвратить подобный конфликт, но есть средства, позволяющие сделать доступными не все, а только нужные имена. Они будут рассмотрены позже.
ПРИМЕЧАНИЕ
Для многих заголовочных файлов, содержимое которых определено в пространстве имен , существуют их двойники "старого стиля" с расширением .h,описания, находящиеся в которых, доступны без дополнительных усилий - например, <iostream.h>, <stdio.h>. c. Этот способ использования заголовочных файлов считается устаревшим.
Строка 3 представляет собой заголовок главной (и единственной) функции, в строках 4 и 5 описаны две величины с плавающей точкой: константа и переменная . Строка 6 является приглашением к вводу. В результате выполнения этого оператора на экран выводится строка "Введите сумму в рублях:" и курсор переводится на следующую строку в соответствии с \n.
Стандартному объекту cout с помощью операции << передается то, что мы хотим вывести, в данном случае
В процессе ввода ( строка 7 ) происходит обратный процесс: величина преобразуется из последовательности символов, набранных на клавиатуре, во внутреннее представление числа с плавающей точкой и помещается в ячейку памяти, зарезервированную для переменной . Как видите,
В строке 8 определяется переменная euro, которая инициализируется результатом деления переменной на переменную . В строке 10 в вызывающую среду возвращается значение 0 - признак успешного завершения программы. Оператор return 0 в главной функции записывать не обязательно, поскольку при его отсутствии значение 0 будет возвращено автоматически. Во всех последующих примерах этот оператор опущен для экономии места.
Другой вариант записи той же программы приведен в листинге 2.2.
// используются функции ввода/вывода в стиле С
#include <сstdio> // 1
using namespace std; // 2
int main() // 3
{ const double course = 36.5; // 4
double sum; // 5
printf( "Введите сумму в рублях\n" ); // 6
scanf( "%lf", sum ); // 7
double euro = sum / course; // 8
printf( "В рублях: %lf В евро: %lf\n", sum, euro ); // 9
}
По директиве printf в строке 6 выводит приглашение "Введите сумму в рублях:" и переходит на новую строку в соответствии с \n. Функция scanf в строке 7 заносит введенное с клавиатуры число в переменную .
Знак обозначает операцию получения . Это нужно чтобы функция scanf могла записать в эту переменную введенное с клавиатуры значение.
Формат основных функций ввода-вывода, унаследованных из С:
int scanf ( строка_формата, список адресов вводимых величин ) // ввод int printf( строка_формата, список выводимых величин ) // вывод
Функции выполняют форматированный ввод и вывод произвольного количества величин в соответствии со строкой формата. Она содержит символы, которые копируются на экран при выводе или запрашиваются с клавиатуры при вводе, и спецификации преобразования, начинающиеся со знака %, которые при вводе и выводе заменяются конкретными величинами. Каждой величине должна соответствовать своя спецификация.
Спецификация %d означает целое десятичное число, %f используется для величин типа , %lf - для величин типа double. Оператор в строке 9 выводит на экран указанную в нем строку, заменив %lf на значения переменных и euro.
Для каждой программы необходимо выбрать один из способов вывода (либо с помощью классов, либо с помощью функций), поскольку смешивать оба варианта не рекомендуется. Функции ввода/вывода в стиле С имеет смысл использовать в тех программах, где требуется тщательное форматирование результатов, а классы - в остальных случаях.
Задача вывода русских букв в консольное окно является частным случаем сложной проблемы локализации приложений. К
MS к системе Windows. В консольном окне Windows по умолчанию используется кодировка, принятая в MS , для того чтобы старые программы MS правильно работали в консольном окне Windows.
Однако Visual Studio.NET 2005 работает в системе Windows, в которой по умолчанию установлена другая кодовая страница. Русские символы, набираемые в окне редактора среды, имеют другую кодировку, и поэтому в консольном окне видны как "иероглифы".
Есть множество способов решения этой проблемы. Самый простой - вообще отказаться от русских букв. Если же все-таки хочется их использовать, проще всего воспользоваться функцией setlocale, унаследованной из языка С (она описана в
setlocale( LC_ALL, "Russian" ); setlocale( LC_ALL, "rus" );
Любой из этих вызовов устанавливает русскую локаль,после чего русские константы выводятся в консольное окно по-русски при использовании и printf, и cout.
Чтобы русификация консольного окна работала, необходимо, чтобы в операционной системе Windows в настройках языков и стандартов была установлена кириллица по умолчанию.
В любой программе требуется производить вычисления. Для
( a + 0.12 ) / 6 x y || ! z ( t * sin( x ) - 1.05e4 ) / ( ( 2 * k + 2 ) * (2 * k + 3 ) ) a = b = c b++ cout << a i++, j++
Операнды задают данные для вычислений. Операции задают действия, которые необходимо выполнить. Каждый
Язык С++ предоставляет в наше распоряжение внушительный набор операций: арифметические, логические, поразрядные,
| Операция | Краткое описание |
|---|---|
| ++ | постфиксный |
| -- | постфиксный |
sizeof |
размер объекта или типа |
| -- | префиксный |
| ++ | префиксный |
| ! | логическое |
| - | арифметическое |
| + | унарный плюс |
| (<тип>) | преобразование типа |
| Бинарные и | |
| * | |
| / | деление |
| % | |
| + | |
| - | |
| < | меньше |
| <= | меньше или равно |
| > | больше |
| >= | больше или равно |
| == | равно |
| != | не равно |
| логическое И | |
| || | |
| ? : | условная операция (тернарная) |
| = | присваивание |
| *= | |
| /= | деление с присваиванием |
| %= | |
| += | |
| -= | |
| , | последовательное вычисление |
Операции расположены в порядке убывания С++ огорчительно много, поэтому в случае сомнений надо не лениться обращаться к справочной информации. Основные правила, тем не менее, просты и соответствуют принятым в математике: например,
Если в одном выражении записано несколько операций одинакового приоритета, то a = b = c означает a = (b = c), а a + b + c означает (a + b) + c.
Порядок вычисления операндов в выражении не определен: например, нельзя считать, что в выражении (sin(x + 2) + обращение к синусу будет выполнено раньше, чем к косинусу. Только четыре операции гарантируют порядок вычислений слева направо: ,, ?:, и ||.
Результат вычисления выражения характеризуется значением и типом. Например, пусть описаны две переменные
Тогда выражение a + b имеет значение 7 и тип . В С++ различаются так называемые L-значения (L-value) и R-значения (R-value). Название произошло от
L -значением (от слова Left - левый), может располагаться как с левой, так и с правой стороны R -значением (от слова Right - правый), может располагаться только с правой, но никак не с левой стороны Выражения возвращают в качестве результата либо L -значения, либо R -значения. Переменная - частный случай L -значения, а константа - частный случай R -значения. Более общим случаем R -значения является обычное L -значением в общем случае может быть не только переменная, но и некоторое выражение, ссылающееся на область памяти. В дальнейшем мы будем указывать, какие операции возвращают L -значение.
Рассмотрим подробнее некоторые операции.
Операции присваивания ( =, +=, -=, *= и т. д.). Формат операции простого присваивания ( = ):
операнд_1 = операнд_2
Левым операндом должно быть L -значение, а правым - любое выражение. Сначала вычисляется выражение, стоящее в правой части операции, а потом его результат записывается в область памяти, ссылка на которую стоит в левой части (мнемоническое правило: "присваивание - это
Если
Выражение с операцией присваивания может участвовать в качестве операнда в других выражениях. Например, оно может быть
Результат выражения с присваиванием является L -значением, поэтому выражение с присваиванием может быть аргументом другой a = b = c: сначала вычисляется выражение b = c, а затем его результат становится правым операндом для a.
Выражения с операциями присваивания могут использоваться и как самостоятельные операторы. Для этого нужно после выражения поставить точку с запятой. Пример
#include <iostream>
using namespace std;
int main()
{ int a = 3, b = 5, с = 7; // инициализация
a = b; b = a; с = с + 1; // присваивание
cout << "a = " << a
<< "\t b = " << b
<< "\t c = " << c;
с = a + ( b = 5 );
cout << "\t c = " << c;
}
Результат работы программы:
a = 5 b = 5 c = 8 с = 10
В составных операциях присваивания ( +=, *=, /= и т. п.) при L -значение из левой части. Например, при сложении с присваиванием к значению левого операнда прибавляется значение правого, и результат записывается в левый a += b является более компактной записью выражения a = a + b.
Операции увеличения и уменьшения на 1 ( ++ и -- ). Эти операции, называемые также
#include <cstdio>
using namespace std;
int main()
{ int x = 3, y = 3;
printf( "Значение префиксного выражения: %d \n", ++x );
printf( "Значение постфиксного выражения: %d \n", y++ );
printf( "Значение х после приращения: %d \n", x );
printf( "Значение у после приращения: %d \n", у );
}
Результат работы программы:
Значение префиксного выражения: 4 Значение постфиксного выражения: 3 Значение х после приращения: 4 Значение у после приращения: 4
Как и выражения с присваиванием, выражения с
Операции отрицания ( !) дает в результате значение false, если true, и значение true, если false. bool.
Деление ( / ) и остаток от деления ( % ). Операция деления применима к операндам арифметического типа. Если оба операнда целочисленные, результатом операции является целая часть частного (дробная часть отсекается). Например, результатом 5/2 будет 2. Если же хотя бы один
#include <cstdio>
using namespace std;
int main()
{int x = 11, y = 4;
float z = 4;
printf( "Результаты деления: %d %f \n", x / y, x / z );
printf( "Остаток: %d \n", x % y );
}
Результат работы программы:
Результаты деления: 2 2.750000 Остаток: 3
Операции отношения (<, <=, >, >=, ==, !=) сравнивают первый true или false. Операции сравнения на равенство и неравенство имеют меньший приоритет, чем остальные операции сравнения.
ВНИМАНИЕ
Обратите внимание на разницу между операцией проверки на равенство ( == ) и операцией присваивания ( = ), результатом которой является значение, присвоенное левому операнду.
Логические операции ( и ||). bool, при этом true или false. Результат операции логическое И имеет значение true только если оба операнда имеют значение true. Результат операции логическое ИЛИ имеет значение true,
если хотя бы один из операндов имеет значение true. Логические операции выполняются слева направо. Если значения первого операнда достаточно, чтобы определить результат операции, второй
Условная операция ( ?:).Эта единственная в С++ тернарная операция (имеет три операнда), ее формат:
операнд_1 ? операнд_2 : операнд_3
bool. Если результат равен true, то результатом выполнения всей условной операции будет значение второго операнда, иначе - третьего операнда. Их типы могут быть различными.
Пример: пусть требуется, чтобы некоторая целая величина увеличивалась на 1, если ее значение не превышает n, а иначе принимала значение 1. Это можно записать с помощью одной строки кода:
i = ( i < n ) ? i + 1 : 1;
Операция последовательного вычисления "запятая" (,). Формат операции:
выражение_1, выражение_2
Операция выполняется слева направо: сначала вычисляется выражение слева от знака операции (его результат отбрасывается), а затем вычисляется выражение справа от знака и его результат принимается за результат операции. Вычисление левого выражения обязательно завершается до того, как начнется вычисление правого выражения. Это позволяет присваивать значения переменным в левом выражении, а затем использовать их в правом.
Например, результатом операции j = 2, j = 1 будет 1, результатом операции j = 2, j++ будет 2, а результатом операции j = 2, ++j будет 3.
Стандарт разрешает любое выражение заменить последовательностью выражений, разделенных операцией "запятая". Результатом вычисления последовательности выражений будет значение самого правого выражения.
Операции, не рассмотренные в этом разделе, будут описаны по мере необходимости.
В выражение могут входить
( char, short ) -> int -> unsigned int -> long -> unsigned long -> float -> double -> long double
Это не означает, что преобразование типа в double выполняется последовательно по цепочке, просто менее "объемный" тип преобразуется к более "объемному". Типы и перед выполнением операции обязательно преобразуются к . Типом результата выражения обычно является самый "объемный" из типов операндов.
Однако в выражениях с операцией присваивания встречается и обратный вариант, когда более "объемный" тип присваивается менее "объемному", например, в . Подобные преобразования связаны с потерей информации (дробная часть отбрасывается), поэтому называются сужающими приведениями (преобразованиями). Компилятор предупреждает о таких операциях.
В логических операциях и условной операции выполняется bool. При этом любое значение, не равное нулю (даже отрицательное), трактуется как true, а нуль считается false. При обратных преобразованиях величин типа bool к целому типу значение true преобразуется в целую константу 1, а значение false - в 0.
Программист может задать явное преобразование типа. Операция
( тип ) выражение тип ( выражение )
Результатом операции является значение заданного типа, например:
int a = 2; float b = 6.8; printf( "%lf %d", double ( a ), ( int ) b );
Величина a преобразуется к типу double, а переменная b - к типу с отсечением дробной части (сужающее приведение).
Явное преобразование типа в стиле С оставлено в С++ только для совместимости. Использовать его не рекомендуется, поскольку оно слишком универсально, а потому чревато плохо диагностируемыми ошибками.
В стандарте С++ определено четыре специализированных операций
static_cast<тип>( выражение ) reinterpret_cast<тип>( выражение ) dynamic_cast<тип>( выражение ) const_cast<тип>( выражение )
В зависимости от вида преобразования необходимо использовать соответствующую ему операцию приведения типа. Приведение типа static_cast<T>(e) используется между родственными типами. Его может проверить компилятор. Операция reinterpret_cast выполняет преобразование типов без проверки при компиляции. Оно часто необходимо тогда, когда точно известно, что объекты разных типов занимают в памяти одинаковое количество байт и фактического преобразования делать как раз не нужно. Операция const_cast аннулирует действие модификатора и применяется достаточно редко. Операция dynamic_cast выполняет преобразование во время работы программы и применяется для преобразования указателей и ссылок родственных полиморфных классов. Примеры применения этих операций вы увидите в следующих лекциях.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.