Тема 1 — Базовые средства языка Си

Тема 1. Базовые средства языка С++.

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

Типы данных С++.

Константы.

Переменные и выражения.

Базовые конструкции структурного программирования.

Указатели и массивы.

Типы данных, определяемые пользователем.

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

Алфавит языка С++ включает:

прописные и строчные латинские буквы и знак подчеркивания;

арабские цифры от 0 до 9 и шестнадцатеричные цифры от A до F;

специальные знаки: “ { } , | [ ] ( ) + — / % * . \ ‘ : ? ! & # ~ ; ^

пробельные символы: пробел, символы табуляции, символы перехода на новую строку.

Из символов алфавита формируются лексемы языка: идентификаторы, ключевые (зарезервированные) слова, знаки операций, константы, разделители.

Идентификатор – имя программного объекта. В идентификаторе могут использоваться латинские буквы, цифры и знак подчеркивания. Прописные и строчные буквы различаются. Первым символом идентификатора может быть буква или знак подчеркивания, но не цифра. Пробелы внутри имен не допускаются.

При выборе идентификатора следует учитывать правила:

идентификатор не должен совпадать с ключевыми словами и именами используемых стандартных объектов языка;

не рекомендуется начинать идентификаторы с символа подчеркивания, поскольку они могут совпасть с именами системных функций или переменных;

длина идентификатора по стандарту не ограничена, но некоторые компиляторы и компоновщики налагают на нее ограничения;

на идентификаторы, используемые для определения внешних переменных, налагаются ограничения компоновщика.

Ключевые слова – это зарезервированные идентификаторы, которые имеют специальное значение для компилятора. Их можно использовать только в том смысле, в котором они определены.

Знак операции – это один или более символов, определяющих действие над операндами. Внутри знака операции пробелы не допускаются.

Комментарий либо начинается с двух символов // и заканчивается символом перехода на новую строку, либо заключается между символами-скобками /* и */. Внутри комментария можно использовать любые символы, так как компилятор комментарии игнорирует.

Рекомендуется использовать для пояснений //-комментарии, а скобки /* */ применять для временного исключения блоков кода при отладке.

Типы данных С++.

В любом алгоритмическом языке каждая константа, переменная, результат вычисления выражения должны иметь определенный тип.

Тип данных определяет:

внутреннее представление данных в памяти компьютера;

множество значений, которые могут принимать величины этого типа;

операции и функции, которые можно применять к величинам этого типа.

Обязательное описание типа позволяет компилятору производить проверку допустимости различных конструкций программы. От типа величины зависят машинные команды, которые будут использоваться для обработки данных.

Все типы языка С++ можно разделить на основные и составные. В языке С++ определено шесть основных типов данных для представления целых, вещественных, символьных и логических величин. На основе этих типов программист может вводить описание составных типов. К ним относятся массивы, перечисления, функции, структуры, ссылки, указатели, объединения и классы.

Основные типы данных часто называют арифметическими, так как их можно использовать в арифметических операциях. Для описания таких типов определены следующие слова:

int (целый);

char (символьный);

wchar_t (расширенный символьный);

bool (логический);

float (вещественный);

double (вещественный с двойной точностью).

Первые четыре типа называют целочисленными, последние два – типами с плавающей точкой.

Существует четыре спецификатора типа, уточняющих внутреннее представление и диапазон значений стандартных типов:

short (короткий);

long (длинный);

signed (знаковый);

unsigned (беззнаковый).

Размер типа int не определяется стандартом, а зависит от компьютера и компилятора. Для 16-разрядного процессора под величины этого типа отводится 2 байта, для 32-разрядного – 4 байта.

Спецификатор short перед именем типа указывает компилятору, что под число требуется отвести 2 байта независимо от разрядности процессора. Спецификатор long означает, что целая величина будет занимать 4 байта.

Внутреннее представление величины целого типа – целое число в двоичном коде. При использовании спецификатора signed старший бит числа интерпретируется как знаковый (0 – положительное число, 1 – отрицательное). Спецификатор unsigned позволяет представлять только положительные числа, так как старший разряд рассматривается как часть кода числа. По умолчанию все целочисленные типы считаются знаковыми.

Тип

Диапазон значений

Размер (байт)

signed short int

-32768 … 32767

2

unsigned short int

0 … 65535

2

signed long int

-2147483648 … 2147483647

4

unsigned long int

0 … 4294967295

4

Под величину символьного типа отводится количество байт, достаточное для размещения любого символа из набора символов для данного компьютера. Как правило, это 1 байт. Тип char может быть со знаком и без знака. В величинах со знаком можно хранить значения в диапазоне от -128 до 127. При использовании спецификатора unsigned значения могут находиться в пределах от 0 до 255. Величины этого типа могут применяться для хранения целых чисел из указанных диапазонов.

Расширенный символьный тип предназначен для работы с набором символов, для кодировки которых недостаточно 1 байта, например, Unicode.

Величины логического типа могут принимать только значения true и false, являющиеся зарезервированными словами. Внутренняя форма представления значения false – 0. Любое другое значение интерпретируется как true. При преобразовании к целому типу оно имеет значение 1.

Стандарт С++ определяет три типа данных для хранения вещественных значений: float, double, long double.

Тип

Диапазон значений

Размер (байт)

float

3.4е-38…3.4е+38

4

double

1.7е-308…1.7е+308

8

long double

3.4е-4932…3.4е+4932

10

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

Константы.

Константами называют неизменяемые величины. Различают целые, вещественные, символьные и строковые константы.

Константа

Формат

Примеры

Целая

Десятичный: последовательность десятичных цифр, начинающаяся не с нуля, если это не число ноль

Восьмеричный: ноль, за которым следуют восьмеричные цифры

Шестнадцатеричный: 0х или 0Х, за которым следуют шестнадцатеричные цифры

8, 0, 199226

01, 020, 07155

0хA, 0x1B8, 0XFF

Вещественная

Десятичный:

[цифры].[цифры]

Экспоненциальный:

[цифры][.][цифры]{Е|е}[+|-][цифры]

5.7, .001, 35.

0.2Е6, .11е-3, 5Е10

Символьная

Один или два символа, заключенных в апострофы

‘А’, ‘ю’, ‘*’, ‘db’, ‘\0’, ‘\n’, ‘\х07\х07’

Строковая

Последовательность символов, заключенная в кавычки

“Мама мыла раму”, “3,14”

Если требуется сформировать отрицательную целую или вещественную константу, то перед константой ставится знак «-».

Символ обратной косой черты используется для представления:

кодов, не имеющих графического изображения: \a – звуковой сигнал, \b – возврат на шаг, \f – перевод страницы, \n – перевод строки, \r – возврат каретки, \t — горизонтальная табуляция, \v – вертикальная табуляция;

символов апострофа (\’), кавычек (\”), вопросительного знака (\?), обратной косой черты (\\);

любого символа с помощью его шестнадцатеричного или восьмеричного кода.

Последовательности символов, начинающиеся с обратной косой черты, называют управляющими, или escape-последовательностями. Управляющие последовательности могут использоваться и в строковых константах, называемых строковыми литералами. Например, “Издательский дом \ “Питер \””.

Строковые константы, отделенные в программе только пробельными символами, при компиляции объединяются в одну. Длинную строковую константу можно разместить на нескольких строках, используя в качестве знака переноса обратную косую черту, за которой следует перевод строки.

В конец каждого строкового литерала компилятором добавляется нулевой символ, представляемый управляющей последовательностью \0. Поэтому длина строки всегда на единицу больше количества символов в ее записи. Таким образом, пустая строка имеет длину 1 байт. Пустая символьная константа недопустима.

Переменные и выражения.

В любой программе требуется производить вычисления. Для этого используются выражения, которые состоят из операндов, знаков операций и скобок. Каждый операнд, в свою очередь, является выражением или одним из его частных случаев, например, константой или переменной.

Переменная – это именованная область памяти, в которой хранятся данные определенного типа. У переменной есть имя и значение. Имя служит для обращения к области памяти, в которой хранится значение. Перед использованием любая переменная должна быть описана конструкцией вида:

[класс памяти] [const] тип имя [инициализатор];

Необязательный класс памяти может принимать одно из значений auto, extern, static и register.

Модификатор const показывает, что значение переменной изменять нельзя. Такую переменную называют именованной константой, или просто константой.

При описании можно присвоить переменной начальное значение, это называется инициализацией. Инициализатор можно записывать в двух формах – со знаком равенства: = значение или в круглых скобках: (значение). Константа должна быть инициализирована при объявлении.

В одном операторе можно описать несколько переменных одного типа, разделяя их запятыми.

Если тип инициализирующего значения не совпадает с типом переменной, то выполняются преобразования типа по определенным правилам.

Описание переменной явно или по умолчанию задает ее область действия. Однако класс памяти и область действия зависят не только от описания, но и от места размещения его в программе.

Область действия идентификатора – это часть программы, в которой его можно использовать для доступа к связанной с ним области памяти. в зависимости от области действия переменная может быть локальной или глобальной.

Если переменная определена внутри блока, она называется локальной, область ее действия – от точки описания до конца блока, включая все вложенные блоки. Если переменная определена вне любого блока, она называется глобальной и областью ее действия считается файл, в котором она определена, от точки описания до его конца.

Класс памяти определяет время жизни и область видимости программного объекта. Если класс памяти не указан явным образом, он определяется компилятором исходя из контекста объявления.

Время жизни может быть постоянным (в течение выполнения программы) и временным (в течение выполнения блока).

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

Для задания класса памяти используются следующие спецификаторы:

auto – автоматическая переменная. Память под нее выделяется в стеке и при необходимости инициализируется каждый раз при выполнении оператора, содержащего ее определение. Освобождение памяти происходит при выходе из блока, в котором описана переменная. Время ее жизни – с момента описания до конца блока. Для глобальных переменных этот спецификатор не используется, а для локальных он принимается по умолчанию;

extern – означает, что переменная определяется в другом месте программы (в другом файле или дальше по тексту). Используется для создания переменных, доступных во всех модулях программы, в которой они объявлены. Если переменная в том же операторе инициализируется, то данный спецификатор игнорируется;

static – статическая переменная. Время жизни – постоянное. Инициализируется один раз при первом выполнении оператора, содержащего определение переменной. В зависимости от расположения оператора описания статические переменные могут быть глобальными и локальными. Глобальные статические переменные видны только в том модуле, в котором они описаны;

register – аналогично auto, но память выделяется по возможности в регистрах процессора. Если такой возможности у компилятора нет, переменные обрабатываются как auto.

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

Описание переменной может выполняться в форме объявления или определения. Объявление информирует компилятор о типе переменной и классе памяти, а определение содержит, кроме этого, указание компилятору выделить память в соответствии с типом переменной. В С++ большинство объявлений являются одновременно и определениями.

Рассмотрим основные операции.

Операции увеличения и уменьшения на 1 (++ и —). Эти операции, называемые также инкрементом и декрементом, имеют две формы записи – префиксную, когда операция записывается перед операндом, и постфиксную. В префиксной форме сначала изменяется операнд, а затем его значение становится результирующим значением выражения, а в постфиксной форме значением выражения является исходное значение операнда, после чего он изменяется.

Пример.

#include

int main() {

int x=3, y=3;

printf(“Значение префиксного выражения: %d\n”, ++x);

printf(“Значение постфиксного выражения: %d\n”, y++);

printf(“Значение х после приращения: %d\n”, x);

printf(“Значение y после приращения: %d\n”, y);

return 0;

}

Результат работы программы:

Значение префиксного выражения: 4

Значение постфиксного выражения: 3

Значение х после приращения: 4

Значение y после приращения: 4

Операндом операции инкремента в общем случае является так называемое L-значение. Так обозначается любое выражение, адресующее некоторый участок памяти, в который можно занести значение. Переменная является частным случаем L-значения.

Операция определения размера sizeof предназначена для вычисления размера объекта или типа в байтах, и имеет две формы: sizeof выражение или sizeof (тип).

Операции отрицания (-, ! и ~). Арифметическое отрицание (унарный минус -) изменяет знак операнда целого или вещественного типа на противоположный. Логическое отрицание (!) дает в результате значение 0, если операнд есть истина (не нуль), и значение 1, если операнд равен нулю. Операнд должен быть целого или вещественного типа, а может иметь тип указатель. Поразрядное отрицание (~), часто называемое побитовым, инвертирует каждый разряд в двоичном представлении целочисленного операнда.

Деление (/) и остаток от деления (%). Операция деления применима к операндам арифметического типа. Если оба операнда целочисленные, результат операции округляется вниз до целого числа, в противном случае тип результата определяется правилами преобразования. Операция остатка от деления применяется только к целочисленным операндам.

Операции сдвига (>) применяются к целочисленным операндам. Они сдвигают двоичное представление первого операнда влево или вправо на количество двоичных разрядов, заданное вторым операндом. При сдвиге влево ( освободившиеся разряды обнуляются. При сдвиге вправо (>>) освободившиеся биты заполняются нулями, если первый операнд беззнакового типа, и знаковым разрядом в противном случае. операции сдвига не учитывают переполнение и потерю значимости.

Операции отношения (, >=, ==, !=) сравнивают первый операнд со вторым. Операнды могут быть арифметического типа или указателями. Результатом операции является значение true или false. Операции сравнения на равенство и неравенство имеют меньший приоритет, чем остальные операции сравнения.

Поразрядные операции (&, |, ^) применяются только к целочисленным операндам и работают с их двоичными представлениями. При выполнении операций операнды сопоставляются побитово. При поразрядной конъюнкции, или поразрядном И (&) бит результата равен 1 только тогда, когда соответствующие биты обоих операндов равны 1. При поразрядной дизъюнкции, или поразрядном ИЛИ (|) бит результата равен 1 тогда, когда соответствующий бит хотя бы одного из операндов равен 1. При поразрядном исключающем ИЛИ (^) бит результата равен 1 только тогда, когда соответствующий бит только одного из операндов равен 1.

Логические операции (&& и ||). Операнды логических операций И (&&) и ИЛИ (||) могут иметь арифметический тип или быть указателями, при этом операнды в каждой операции могут быть различных типов.

Операции присваивания (=, +=, -=, *= и т.д.). В операции простого присваивания (=) слева от знака должно находиться L-значение, а справа – выражение. При присваивании производится преобразование типа выражения к типу L-значения, что может привести к потере информации. В сложных операциях присваивания при вычмслении выражения, стоящего в правой части, используется и L-значение из левой части. Например, выражение a+=b является более компактной записью выражения a=a+b.

Условная операция (?:). Эта операция тернарная, то есть имеет три операнда. Ее формат: операнд1 ? операнд2 : операнд3. Первый операнд может иметь арифметический тип или быть указателем. Он оценивается с точки зрения его эквивалентности нулю. Если результат вычисления операнда1 равен истина, то результатом условной операции будет значение второго операнда, иначе – третьего операнда. Условная операция является сокращенной формой условного оператора if.

Стандартно выполняются операции умножения (*), сложение (+) и вычитание (-).

Операции выполняются в соответствии с приоритетами. Для изменения порядка выполнения операций используются круглые скобки. Если в одном выражении записано несколько операций одинакового приоритета, унарные операции, условная операция и операции присваивания выполняются справа налево, остальные – слева направо.

Результат вычисления выражения характеризуется значением и типом. В выражение могут входить операнды различных типов. Если операнды имеют одинаковый тип, то результат операции будет иметь тот же тип. Если операнды разного типа, те перед вычислениями выполняются преобразования типов по определенным правилам, обеспечивающим преобразование более коротких типов в более длинные для сохранения значимости и точности.

Преобразования бывают двух типов:

изменяющие внутреннее представление величин (с потерей точности или без потери точности);

изменяющие только интерпретацию внутреннего представления.

К первому типу относится, например, преобразование целого числа в вещественное (без потери точности) и наоборот, ко второму – преобразование знакового целого в беззнаковое.

Базовые конструкции структурного программирования.

В теории программирования доказано, что программу для решения задачи любой сложности можно составить только из трех структур, называемых следованием, ветвлением и циклом. Этот результат установлен Боймом и Якопини в 1966 году путем доказательства того, что любую программу можно преобразовать в эквивалентную, состоящую только из этих структур и их комбинаций.

Следование, ветвление и цикл называют базовыми конструкциями структурного программирования. Следованием называется конструкция, представляющая собой последовательное выполнение двух или более операторов. Ветвление задает выполнение либо одного, либо другого оператора в зависимости от выполнения какого-либо условия. Цикл задает многократное выполнение оператора. Каждый блок имеет один вход и один выход. Допустимо вложение конструкций друг в друга. Целью использования базовых конструкций является получение программы простой структуры.

Рассмотрим операторы языка, реализующие базовые конструкции структурного программирования.

Оператор «выражение»

Любое выражение, завершающееся точкой с запятой, рассматривается как оператор, выполнение которого заключается в вычислении выражения. Частным случаем является пустой оператор ; (он используется, когда по синтаксису оператор требуется, а по смыслу – нет).

Операторы ветвления

Условный оператор if используется для разветвления процесса вычислений на два направления. Формат оператора:

if (выражение) оператор1; [else оператор2;]

Сначала вычисляется выражение, которое может иметь арифметический тип или тип указателя. Если оно не равно 0 (имеет значение true), выполняется первый оператор, иначе – второй. После этого управление передается на оператор, следующий за условным. Одна из ветвей может отсутствовать. Если в какой-либо ветви требуется выполнить несколько операторов, их необходимо заключить в блок, иначе компилятор не сможет понять, где заканчивается ветвление. Блок может содержать любые операторы, в том числе описания и другие условные операторы (но не может состоять из одних описаний). Необходимо учитывать, что переменная, описанная в блоке, вне блока не существует.

Если какая-либо переменная используется только внутри условного оператора, рекомендуется объявить ее внутри скобок. Объявление переменной в тот момент, когда она требуется, то есть когда ей необходимо присвоить значение, является признаком хорошего стиля и позволяет избежать случайного использования переменной до ее инициализации. Объявлять внутри оператора if можно только одну переменную. Область ее видимости начинается в точке объявления и включает обе ветви оператора.

Оператор switch (переключатель) предназначен для разветвления процесса вычислений на несколько направлений. Формат оператора:

switch (выражение) {

case константное выражение1: [операторы1]

case константное выражение2: [операторы2]

case константное выражениеn: [операторыn]

[default: операторы]

}

Выполнение оператора начинается с вычисления выражения, а затем управление передается первому оператору из списка, помеченного константным выражением, значение которого совпало с вычисленным. После этого, если выход из переключателя явно не указан, последовательно выполняются все остальные ветви.

Выход из переключателя обычно выполняется с помощью операторов break или return.

Все константные выражения должны иметь разные значения, но быть одного и того же целочисленного типа. Несколько меток могут следовать подряд. Если совпадения не произошло, выполняются операторы, расположенные после слова default, а при его отсутствии управление передается следующему за switch оператору.

Операторы цикла

Любой цикл состоит из тела цикла, начальных установок, модификации параметра цикла и проверки условия продолжения выполнения цикла. Один проход цикла называется итерацией. Проверка условия выполняется на каждой итерации.

Переменные, изменяющиеся в теле цикла и используемые при проверке условия продолжения, называются параметрами цикла. Целочисленные параметры цикла, изменяющиеся с постоянным шагом на каждой итерации, называются счетчиками цикла.

Начальные установки могут явно не присутствовать в программе, их смысл состоит в том, чтобы до входа в цикл задать значения переменным, которые в нем используются.

Цикл завершается, если условие его продолжения не выполняется. Возможно принудительное завершение как текущей итерации, так и цикла в целом. Передавать управление извне внутрь цикла не рекомендуется.

Для удобства в С++ есть три разных оператора цикла – while, do while, for.

Цикл с предусловием while имеет вид:



Страницы: Первая | 1 | 2 | 3 | Вперед → | Последняя | Весь текст