§3 Алфавит С++. Литералы. Идентификаторы. Выражение. Операции. Инструкции

Алфавит языка C++

Алфавит языка C++ составляют символы включенные в 7-битную кодировку ISO 646/ECMA-6:
space, !, ", %, &, (, ), *, +, -, ., /, 0..9, :, ;, <, =, >, ?, A..Z, _, a..z.
Тем не менее, часть символов, используемых в алфавите C++, не входит в кодовую базу этой кодировки: {, }, [, ], #, \, ^, |, ~. Чтобы обеспечить совместимость с кодировками, в которых отсутствуют эти символы, определены альтернативные ключевые слова, а также двух-символьные замены с помощью ISO646-совместимых символов:

Альтернативные ключевые слова
Операция Альтернативное представление
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
||= or_eq
^ xor
^= xor_eq
Диграфы
Символ Диграф
{ <%
} %>
[ <:
] :>
# %:
\
^
|
~

Двух-символьная замена воспринимается как один несуществующий символ ISO 646. (Существовавшие до С++17 триграфы упразднены). В нашем курсе диграфы применяться не будут

Лексема

Символы алфавита образуют лексемы. Лексема (token) - это минимальная единица языка, имеющая самостоятельный смысл. Лексемы - формируют базовый словарь языка, понятный компилятору. Всего существует пять видов лексем:

  • Ключевые слова (keywords)
  • Идентификаторы (identifiers)
  • Литералы (literals)
  • Операции (operators)
  • Знаки пунктуации (разделители, punctuators)
Лексемы (как и слова в естественном языке) разделяются непечатаемыми (пробельными) символами (пробел, символы табуляции, перевода строки, возврат каретки, перевода страницы) и знаками пунктуации: [, ], (, ), {, }, *, ,, :, =, ;, ..., #.

8-2

Идентификаторы

Идентификатор - это имя программного объекта: переменной, константы, массива, функции, класса и т. п. В идентификаторах могут использоваться латинские буквы, цифры и знак нижнего подчеркивания ( _ ). В C++ различаются строчные и прописные буквы (т. е. имена регистро-зависимы), так: Name, name и NAME - это разные идентификаторы. Правила использования идентификаторов:

  1. можно использовать латинские символы: A..Z, a..z;
  2. можно использовать арабские цифры: 0..9 и символ нижнего подчеркивания, но не в начале;
  3. пробелы в имени не допускаются;
  4. не рекомендуется начинать с нижнего подчеркивания или с двух нижних подчеркиваний и заглавной буквы, например: _S (такие идентификаторы имеют специальное назначение);
  5. двойное подчеркивание используется только для служебных целей to__boo
  6. не допускается использования ключевых слов;
  7. необходимо воздерживаться от использования ключевых слов, как части имени, например: for_and_if (за исключением наименования типов)

При составлении имен желательно придерживаться какого-либо стиля, например, стиля CamelCase: имена пишутся слитно, каждое слово, описывающее назначение идентификатора, пишется с заглавной буквы. Этот стиль используется в двух вариантах: UpperCamelCase и lowerCamelCase. Первый используется для именования классов, второй для прочего: переменных, методов и т.п.

Ключевые слова

Ключевые слова - это лексемы специального назначения. Они зарезервированы, использовать их в качестве идентификаторов запрещено.

alignas
alignof
and
and_eq
asm
auto
bitand
bitor
bool
break
case
catch
char
char16_t
char32_t
class
compl
const
constexpr
const_cast
continue
decltype
default
delete
do
double
dynamic_cast
else
enum
explicit
export
extern
false
float
for
friend
goto
if
inline
int
long
mutable
namespace
new
noexcept
not
not_eq
nullptr
operator
or
or_eq
private
protected
public
register
reinterpret_cast
return
short
signed
sizeof
static
static_assert
static_cast
struct
switch
template
this
thread_local
throw
true
try
typedef
typeid
typename
union
unsigned
using
virtual
void
volatile
wchar_t
while
xor
xor_eq

Литералы

Литералы, иначе константы - это неизменяемые величины. Примеры различных констант:

    Целые

    Без суффикса: 0, -1, 10000
    По умолчанию целочисленные лексемы имеют тип int. Суффиксы позволяют изменить тип.
    С использованием суффиксов (суффиксы не чувствительны к регистру): 2015u, 100000ULL
    u   – unsigned int
    l   – long
    ul  – unsigned long
    ll  – long long
    ull – unsigned long long

    Примечание: поскольку компилятор определяет тип данных константы по её внешнему виду – суффиксы подсказывают компилятору какой тип данных необходимо использовать: так, если константа 100 займет в памяти 4 байта (тип int), то 100LL займет уже 8 байтов памяти.

    Представление целых литералов в различных системах счисления (также можно использовать суффиксы):
    Двоичной: 0b1010, 0B111100111
    Восьмеричной: 01, 020, 07155
    Шестнадцатеричной: 0xA, 0x1B8, 0X00FF

    Действительные

    С фиксированной точкой: 5.7, .001, -35., 0.0
    С плавающей точкой (экспоненциальный): -0.2E6, .11e-3, 5E10, 2.e-10
    По умолчанию они имеют тип double. Для явного указания типа float нужно использовать суффикс F или f, а для long doubleL или l, но только в случае записи с десятичной точкой:
    3.14159F, 12.345L

    Примечание: стандарт C++14 ввёл использование апострофа для произвольного разделения разрядов в числовых литералах: 0b0100’1100’0110, 0.000’015’3
    Символьные

    Один или два символа заключенные в апострофы: 'S', 'щ', '\t', '\012', '\x07\x07', 'db'

    Примечание: к символьным константам относятся специальные управляющие символы (escape-последовательности).
    Escape-последовательности

    Escape-последовательности (или управляющие последовательности) используются для описания определённых специальных символов внутри строковых литералов, то есть внутри ограничителей "". Полный список приведен в методичке (Таб. 12). Вот некоторые из них:
    \n – новая строка
    \t – горизонтальная табуляция
    \v – вертикальная табуляция
    \0 – нулевой символ
    Например: "Ветер на море гуляет\nИ кораблик подгоняет;\nОн бежит себе в волнах\nНа раздутых парусах."

    Строковые

    Последовательность символов, заключенные в кавычки:
    "Hello world!", "Здесь был Вася :-))"
    Суффиксы (чувствительны к регистру) в зависимости от типа не-ASCII символа:
    L"a wide string literal"
    – char16_t (unicode)
    – char32_t (unicode)
    u8 – строка в кодировке UTF-8 (unicode, до C++20, начиная с C++20, тип char8_t)
    – wchar_t (широкий символ)
    – сырая строка: R"&%$(string with \backslash)&%$"

    Примечание: в сырой строке могут быть символы /, ' и ". Префикс R может быть использован в сочетании с любыми другими, например: RU, Ru8.

    В стандарте C++17 символьные литералы представлены в единой кодировке UTF-8.

    Примечание: к строковому литералу автоматически добавляется признак конца строки ('\0').
    Прочие

    Булевские (логические): false, true
    Нулевой указатель: nullpt

Литералы определенные пользователем

Для удобства и придания программе более лаконичного и изящного вида можно создавать свои собственные литералы (user-defined literals). Для создания собственного литерала используется синтаксис похожий на перегрузку операций. Например, для преобразования величины из градусной меры в радианную можно использовать следующий синтаксис, в виде суффикса:

double t = 60_deg;

Для этого, в программе, нужно объявить и определить функцию следующего вида:

constexpr long double operator"" _deg (long double deg)
{
    return deg * M_PI / 180;
}
Примечание. Предваряющее нижнее подчеркивание в имени литерала - обязательно! Для целых типов используется тип unsigned long long. Для использования константы M_PI необходимо подключить библиотеку cmath

Комментарии

Комментарии служат для описания и документирования исходного кода. В C++ применяются два вида комментариев: многострочный и однострочный. Например:

/* Многострочный комментарий часто используется
   для заголовков в описании исходного кода */

/*******************************************************
***     Версия: 1.4.3                                ***
***     Автор:  Леонид Зеленцов                      ***
***     Описание: Класс сортировки структур          ***
***     Лицензия: GPL v. 3                           ***
********************************************************/

// Однострочный комментарий используется в пределах одной строки
// но также может быть использован для описания заголовков:

//========================================================
// Name        : test.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//========================================================

В комментариях можно использовать любые, доступные в среде, символы - компилятор игнорирует содержимое закомментированного блока или строки. Комментарии также используют системы генерации документации. Однако, при этом, необходимо соблюдать правила оформления таких комментариев. Например:

/*!< Однострочный и многострочный стиль Qt */
/*! \brief This is a brief description.
 * \param	p1 The first parameter.
 * \param	p2 The second parameter.
 * \return	Return value.
 * This is a detailed description.
 */

//!< Однострочный и многострочный стиль C++ Exclamation
//! \brief This is a brief description.
//! \param	p1 The first parameter.
//! \param	p2 The second parameter.
//! \return	Return value.
//! This is a detailed description.

Синтаксис и семантика

Синтаксис определяет правила по которым пишутся слова и составляются предложения языка. Современные IDE производят синтаксический анализ в процессе кодирования и способны предупреждать разработчика, например, о неопределенном объекте, но более естественный способ выявления ошибок - это синтаксический анализ, который производит компилятор и процесс отладки. Однако, отсутствие сообщений об ошибках в процессе компиляции является необходимым, но недостаточным для правильной работы программы.
Помимо синтаксических ошибок могут существовать семантические - ошибки в алгоритмах.
Семантика определяет смысловые значения предложений языка, какой алгоритм описан текстом программы. Семантические ошибки компилятор выявить не может. Такие ошибки выявляются в процессе тестирования.

Выражение

Выражение (expression) - это произвольная комбинация констант, переменных и операций приводящая к вычислению некоторого значения. В простейшем случае выражение может быть представлено одним литералом или переменной. Например:

0
-12.4
(x + 5) / 2
cout << ++num
c == 2 && (c < 5 || d > sqrt(3 * a))
Примечание: выражение и инструкция (см. ниже) - это не одно и тоже!
Операнды

Операнд (operand) ― это аргумент операции. В выражении один или несколько операндов связаны (по аналогии с математическим способом записи) операциями. В простейшем случае операнд может быть литералом, константой или переменной. В более общем случае - это выражение (в котором тоже свои операнды). В одно выражение могут входить операнды разных числовых типов. Преобразования типов мы рассмотрели на предыдущем уроке.
9

Операции

Операции (operator) - выполняют определенные действия над операндами. Полный список операций смотрите в методичке «Краткий справочник по языку С++» (таблица 5). В соответствии с количеством операндов операции делятся на унарные (один операнд), бинарные (два операнда) и, единственную, тернарную (в которой три операнда). Операция вызова функции может содержать неограниченное количество операндов. Фактически, операция — это та же функция, но записываемая особым образом. В C++ имеется возможность определять операции для произвольных типов как функции (методы) — чтобы можно было работать с ними точно так же, как и с фундаментальными типами. Эта возможность называется «перегрузка операций». Операции имеют приоритет и ассоциативность.
Приоритет (precedence) определяет старшинство операции. Несколько операций могут иметь равный приоритет. В этом случае включается порядок вычисления - ассоциативность (associativity). Ассоциативность может быть либо слева-направо, либо справа-налево. Приоритет и ассоциативность определяют направление вычислительного процесса. Например:

2 + 4 * 6 / 3 
// результат 10, а не 12!
10 - 5 - 2
// результат 3, а не 7!

Первое выражение будет равносильно: (2 + ((4 * 6) / 3))
Второе выражение будет равносильно: ((10 - 5) - 2)
Для изменения порядка вычисления используются круглые скобки ().

Примечание: иногда в переводной литературе допускается неверный перевод, что приводит к некоторой путанице. Operator (операция) переводится как оператор, но в отечественной литературе за оператором (исторически, но не повсеместно) закреплено понятие statement (инструкция). В нашем курсе, в целях определенности, понятие оператор использоваться не будет.

Инструкция

Инструкция (statement) - представляет собой законченное предложение на языке C++. Инструкция указывает компьютеру выполнить некоторые действия. Чаще всего используется инструкция выражение (expression statement). Такая инструкция всегда завершается точкой с запятой;, даже если она находится в конце блока (см. ниже). Инструкции делятся на неисполняемые (например, для описания данных) и исполняемые (например, присваивание, ввод, вывод). Иногда, требуется использовать пустую инструкцию, состоящую из одиночной ";". Такая ситуация возникает, например, в циклах, когда все выражения заключены в заголовке цикла.

int a;
a = a + 1;
a++;

Решение задач линейной структуры

Задачи в которых все действия выполняются последовательно, т. е. инструкции следуют одна за другой (алгоритмическая структура следование), относятся к задачам линейной структуры. Алгоритмы таких задач состоят из следующих частей:

  • Описание переменных и констант
  • Реализация диалога с компьютером
  • Инструкции реализации задачи
  • Вывод результатов

Разработка программ такого типа позволяет получить навыки работы с различными типами данных, умение создавать дружественные интерфейсы программ и составлять арифметические выражения на языке программирования C++.
Рассмотрим пример типичной задачи линейной структуры:
Решим следующую задачу: По двум катетам прямоугольного треугольника произвести полный расчет параметров треугольника. Найти: гипотенузу, радиусы вписанной и описанной окружностей, площадь и периметр.
Программа 3.1

#include <iostream>
#include <iomanip>
#include <cmath> // для sqrt
using namespace std;

int main() {
	double a, b; // вещественный тип данных
	cout << "a = "; cin >> a; // реализация диалога
	cout << "b = "; cin >> b;
	// гипотенуза
	double c = sqrt(a * a + b * b); // или hypot(a, b);
	double S = 0.5 * a * b; // площадь
	double P = a + b + c; // периметр
	double R = c / 2; // радиусы: описанной окружности
	double r = (a + b - c) / 2; // и вписанной окружности
	cout << setprecision(3) // количество дробных знаков
		 << fixed // формат с фиксированной точкой
		 << "c = " << setw(7) << c << "\n"
		 << "S = " << setw(7) << S << "\n"
		 << "P = " << setw(7) << P << "\n"
		 << "R = " << setw(7) << R << "\n"
		 << "r = " << setw(7) << r << endl;
	return 0;
}

Вывод программы

a = 17
b = 19
c =  25.495
S = 161.500
P =  61.495
R =  12.748
r =   5.252
Вопросы
  1. Перечислите правила использования идентификаторов
  2. Для чего нужны суффиксы литералах?
  3. Что произойдет, если вывести строковый литерал в котором встретился символ '\n'? '\t'?
  4. Для чего нужны комментарии?
  5. Допустимы ли такие строковые литералы:
  6. "Однажды в студёную зимнюю пору\nСижу за решёткой в темнице сырой.\nГляжу — поднимается медленно в гору\nВскормлённый в неволе орёл молодой."
    -----------------------------------------------------------
    R"Однажды в горячую летнюю пору'\n'Я шел по бархану; был зной очень лют.'\n'Гляжу - поднимается медленно в гору'\n'Hагруженный тяжко двугорбый верблюд."
    -----------------------------------------------------------
    u8"Однажды в студеную зимнюю пору Пешком не ходил я, как "лох", по лесам На "джипе" своем поднимался я в гору Вдруг - хворосту воз, из-за угла!"
    -----------------------------------------------------------
    R"Однажды зимою, денек был пpохладен"\n"По Цельсию, гpадусов так соpок два,"\n"Гляжу, поднимается по автостpаде"\n"Машина, котоpая возит дpова."
    -----------------------------------------------------------
    "Как-то раз зимой холодной выглянул я на мороз.'\n'Вдоль забора чья-то лошадь увлекала дряхлый воз,'\n'На возу дрова лежали вперемешку с мужиком.'\n'Вот такой вот груз по склону был лошадкою влеком."
    
  7. Какие из этих идентификаторов не содержат ошибок:
  8. A, A1, a1, _1a, 1A, a_1, A1, A 1, _A1, aA, Aa, A_a, a_A, 10A, 10a, 10_A, a10_, 10 a, a__10, A10a, a10A, a_10A, A_10A?

Темы сообщений
  • Венгерская нотация
  • Строковые литералы (включая стандарт C++17)
  • Системы генерации документации
  • Системы контроля версий
  • Unicode
  • Кодировка utf-8
Презентации

ODP
PDF
Презентация к уроку [PDF] [ODP]

Литература
  1. Прата, Стивен. Язык программирования C++. Лекции и упражнения, 6-е изд.: Пер. с англ. — М.: ООО «И.Д. Вильяме», 2012
  2. Стенли Липпман, Жози Лажойе, Барбара Му. Язык программирования С++. Вводный курс. — Вильямс: 2007
  3. Павловская Т. А. C/C++. Программирование на языке высокого уровня. - СПб.: Питер, 2003.
  4. Alternative operator representations
  5. Такие разные литералы
  6. C++ для начинающих. Часть II. Основы языка
  7. C++11 — Википедия
  8. C++14 — Википедия


Print Friendly, PDF & Email

Comments are closed.