Существуют различные классификации языков программирования. По наиболее распространенной классификации все языки программирования делят на языки низкого, высокого и сверхвысокого уровня.
В группу языков низкого уровня входят машинные языки и языки символического кодирования: (Ассемблер). Операторы этого языка – это те же машинные команды, но записанные мнемоническими кодами, а в качестве операндов используются не конкретные адреса, а символические имена. Все языки низкого уровня ориентированы на определенный тип компьютера, т. е. являются машинно-зависимыми. Машинно-ориентированные языки – это языки, наборы операторов и изобразительные средства которых существенно зависят от особенностей ЭВМ (внутреннего языка, структуры памяти и т.д.).
Следующую, существенно более многочисленную группу составляют языки программирования высокого уровня. Это Фортран, Алгол, Кобол, Паскаль, Бейсик, Си, Пролог и т.д. Эти языки машинно-независимы, т.к. они ориентированы не на систему команд той или иной ЭВМ, а на систему операндов, характерных для записи определенного класса алгоритмов. Однако программы, написанные на языках высокого уровня, занимают больше памяти и медленнее выполняются, чем программы на машинных языках.
К языкам сверхвысокого уровня можно отнести лишь Алгол-68 и APL. Повышение уровня этих языков произошло за счет введения сверхмощных операций и операторов.
Языки высокого уровня делятся на:
- процедурные (алгоритмические) (Basic, Pascal, C и др.), которые предназначены для однозначного описания алгоритмов; для решения задачи процедурные языки требуют в той или иной форме явно записать процедуру ее решения;
- логические (Prolog, Lisp и др.), которые ориентированы не на разработку алгоритма решения задачи, а на систематическое и формализованное описание задачи с тем, чтобы решение следовало из составленного описания;
- объектно-ориентированные (Object Pascal, C#, Java и др.), в основе которых лежит понятие объекта, сочетающего в себе данные и действия над нами. Программа на объектно-ориентированном языке, решая некоторую задачу, по сути описывает часть мира, относящуюся к этой задаче. Описание действительности в форме системы взаимодействующих объектов естественнее, чем в форме взаимодействующих процедур.
1.3. Система программирования С++
Сотрудник фирмы Bell Labs Деннис Ритчи создал язык Си в 1972 г. во время совместной работы с Кеном Томпсоном над операционной системой UNIX. Прообразом послужил язык Би, разработанный Томпсоном. Отсюда и произошло его на первый взгляд, странное название.
За время своего существования язык Си послужил основой для целого ряда новых языков программирования. о непосредственных детях и внуках - языках С++ и С#. Значительное количество его элементов можно найти в других современных языках, таких как Java, PHP4 и ряде других.
Область применения языка Си практически не ограничена. Значительный объем эксплуатируемого программного обеспечения разработан на этом языке.
Как уже было сказано, язык С был реализован на самых разных платформах, т.е. существует набор инструментов - система программирования, обеспечивающая фактическое выполнение описанных в программе действий.
Системы программирования основываются на одном из двух подходов реализации языка: интерпретации или компиляции.
Интерпретация предполагает последовательный анализ текста программы с ее одновременным исполнением. Т.е. разобрали какое действие в тексте программы записано - выполнили его, разобрали следующее действие - снова выполнили.
Компиляция предполагает анализ всей программы целиком, по завершению анализа текст программы преобразуется в машинный код, который затем подается на исполнение.
Язык С относится к языкам компилируемого типа. Все известные системы программирования с этим языком включают в себя компилятор.
Обычно процесс преобразования текста программы в исполняемый код является многоэтапным (по крайней мере - двухэтапным).
Программа на языке С++ проходит следующие этапы подготовки к исполнению на ПЭВМ. Первоначально исходный текст программы на языке С++ подготавливается в файле с расширением.СРР. Далее после устранения синтаксических ошибок происходит компиляция. Создается объектный файл с расширением.OBJ. На следующем этапе происходит компоновка (дополнение объектного файла необходимыми библиотечными функциями). В результате создается исполняемый модуль программы с расширением.EXE.
Алфавит языка
Алфавит языка, или его символы — это основные неделимые знаки, с помощью которых пишутся все тексты на языке.
Лексема, или элементарная конструкция, — минимальная единица языка, имеющая самостоятельный смысл.
Выражение задает правило вычисления некоторого значения.
Оператор задает законченное описание некоторого действия.
Алфавитом языка называется совокупность символов, используемых в языке.
В алфавит языка Си входят:
· прописные и строчные буквы латинского алфавита (A,B,C,...,Z,a,b,c,...,z)
· цифры (0,1,2,3,4,5,6,7,8,9)
· специальные знаки " ' {} [] () | + - * / % \;.,:? < > _! & # ~ ^
· неизображаемые символы ("обобщенные пробельные символы"), такие как пробел, табуляция, переход на новую строку.
Из символов алфавита формируются лексемы. В программах на языке Си базовые элементы, опознаваемые компилятором, называются лексемами (английский термин - "token).". В их состав входят:
- идентификаторы;
- ключевые (зарезервированные) слова;
- управляющие последовательности;
- знаки операций;
- константы;
- комментарии;
- разделители (скобки, точка, запятая, пробельные символы).
Идентификаторы
Идентификаторы - это имена, которые вы используете для переменных, типов, функций и меток вашей программы.
Объявив идентификатор однажды, вы можете использовать его в программе, указывая тем самым на связанное с идентификатором значение. Выбор идентификатора синтаксически подчиняется следующим правилам:
1. первым символом имени должна быть либо буква, либо символ подчеркивания
2. после первого символа можно использовать любую комбинацию букв и цифр, нельзя использовать не буквенно-цифровые символы вроде # или $
3. в С имеет значение регистр букв, имена Name и name будут представлять два различных идентификатора
4. в качестве идентификаторов нельзя использовать ключевые слова
Стандарт ANSI разрешает 6 значащих символов для имен внешних идентификаторов и 31 для внутренних. На внешние идентификаторы (объявленные как глобальные или внешние extern) могут налагаться дополнительные ограничения, поскольку они могут быть связаны с иным программным обеспечением, по своему определяющем это понятие.
Существует несколько альтернативных правил именования, но всегда важно то, что имя должно облегчать понимание читаемой программы. Это значит, что имя Square переменной, предназначенной для хранения вычисляемой площади, лучше, чем имя s. Можно давать имена вида AgeInYears, т.е. состоящие из сплошь записанных слов, каждое из которых начинается с прописной буквы. Другой подход - age_in_years - отделение слов символом подчеркивания.
Ключевые слова — это зарезервированные идентификаторы, которые имеют специальное значение для компилятора. Их можно использовать только в том смысле, в котором они определены. Список ключевых слов C++ приведен в таблице:
asm | else | new | this |
auto | enum | operator | throw |
bool | explicit | - private | true |
break | export | protected | try |
case | extern | public | typedef |
catch | false | register | typeid |
char | float | reinterpretcast | typename |
class | for | return | union |
const | friend | short | unsigned |
cohstcast | goto | signed | using |
continue | if | sizeof | virtual |
default | inline | static | void |
delete | int | staticcast | volatile |
do | long | struct | wchart |
double | mutable | switch | while |
dynamiccast | namespace | template |
По смысловой нагрузке служебные слова группируются следующим образом:
Спецификаторы типов:
char символьный
double вещественный двойной точности
enum перечисляемый
float вещественный
int целый
long длинное целый
short короткое целое
struct структура
signed знаковый
union объединение
unsigned беззнаковый
void отсутствие значения
typedef синоним обозначения типа
Квалификаторы типа:
const квалификатор объекта, имеющего постоянное значение
volatile квалификатор объекта, значение которого может измениться без явных указаний программиста.
Классы памяти:
auto автоматический
extern внешний
register регистровый
static статический
Элементы операторов:
break прервать
continue продолжить
do выполнять
for для
goto перейти
if если
return возврат
switch переключатель
while пока
Специальные идентификаторы:
default по умолчанию
case вариант
else иначе
sizeof размер
Управляющая последовательность состоит из из обратной дробной черты, за которой следует буква или комбинация цифр
Управляющая последовательность | Наименование | Шестнадцатиричное значение |
\a \b \t \n \v \f \r \” \’ \\ \ddd \xddd | Звонок Возврат на шаг Горизонтальная табуляция Новая строка Вертикальная табуляция Перевод формата Возврат каретки Кавычки Апостроф Обратная дробная черта Символ из набора кодов ПЭВМ в восьмиричном представлении Символ из набора кодов ПЭВМ в шестнадцатиричном представлении | A B C D 5C ddd |
Знаки пунктуации и специальные символы используются в программах на языке Си в различных целях, но в основном служат для организации работы транслятора. Они не специфицируют выполняемые операции. Некоторые знаки пунктуации одновременно являются знаками операций. Их конкретное назначение транслятор выявляет по контексту программы.
К знакам пунктуации относятся:
[ ] () { } *,: =;... #
Эти символы имеют в Си специальное назначение, которое мы будем раскрывать по мере изучения языка. Заметим здесь лишь, что знак (pound sign (#)) может использоваться только в директивах препроцессора языка Си.
Operators - знаки операций. В качестве знаков операции в языке Си могут выступать:
[ ] (). -> ++ -- & * + - ~! sizeof / % << >> < > <= >= ==!= ^ | && ||?: = *= /= %= += -= <<= >>= &= ^= |=, # ##
Константы
Константами называют неизменяемые величины. Различаются целые, вещественные, символьные и строковые константы. Компилятор, выделив константу в качестве лексемы, относит ее к одному из типов по ее внешнему виду1.
Форматы констант, соответствующие каждому типу, приведены в таблице
Константа | формат | Примеры | |
Целая | Десятичный последовательность десятичных цифр, начинающаяся не с нуля, если это не число нуль | 8, 0,199226 | |
Восьмеричный нуль, за которым следуют восьмеричные цифры (0,1,2,3,4,5,6,7) | 01, 020, 07155 | ||
Шестнадцатеричный Ох или ОХ, за которым следуют шестнадцатеричные цифры (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F) | OxA, OxlB8, OXOOFF | ||
Вещественная | Десятичный [цифры] [цифры]2 | 5.7,.001,35. | |
Экспоненциальный [цифры][][цифры]{Е;е}[+;-][цифры]3 | 0.2E6,.11e-3 5Е10 | ||
Символьная | Один или два символа, заключенных в апострофы | ‘А’,’ю', '\0', '\n', '\х07' | |
Строковая | Последовательность символов, заключенная в кавычки | "Здесь был Vasia" |
Вещественная константа в экспоненциальном формате представляется в виде мантиссы и порядка. Мантисса записывается слева от знака экспоненты (Е или е), порядок — справа от знака Значение константы определяется как произведение мантиссы и возведенного в указанную в порядке степень числа 10. Обратите внимание, что пробелы внутри числа не допускаются, а для отделения целой части от дробной используется не запятая, а точка.
Символьные константы, состоящие из одного символа, занимают в памяти один байт и имеют стандартный тип char. Двухсимвольные константы занимают два байта и имеют тип int, при этом первый символ размещается в байте с меньшим адресом.
Здесь следует особо оговорить, что существует еще одна специальная константа - NULL. Эта константа задает "пустое" значение указателя - одного из элементов языка Си, который будет рассматриваться нами позже.
Комментарии
Комментарий либо начинается с двух символов «прямая косая черта» (//) и заканчивается символом перехода на новую строку, либо заключается между символами-скобками /* и */. Внутри комментария можно использовать любые допустимые на данном компьютере символы, а не только символы из алфавита языка C++, поскольку компилятор комментарии игнорирует.
Переменные и константы. Типы данных: целый, вещественный, символьный; их представление в оперативной памяти. Размеры данных.
Прежде всего отметим, что любая программа определяет некоторый набор действий над данными. Мы вводим в компьютер числа, буквы и слова и ожидаем, что он проводить над ними какие-то операции. Значения некоторых данных устанавливаются до начала выполнения программы и сохраняются неизменными в течение всего времени работы программы. Такие данные называются константами. Правила записи констант в программе, мы с вами уже рассмотрели. Значения других данных могут изменяться (в частности, путем присваивания новых значений) во время выполнения программы. Эти данные называются переменными. И переменные, и константы занимают определенные участки в памяти компьютера.
Помимо различий между переменными и константами, существуют также различия между данными разных типов. Одни данные являются числами, другие - символами. Компьютер должен каким-то способом идентифицировать и использовать эти различные виды данных. В языке С распознаются несколько основных типов данных.
Основная цель любой программы состоит в обработке данных. В программе на языке С все переменные перед использованием должны быть объявлены. Переменные могут быть объявлены в любом месте программы, но обязательно перед их первым использованием
Данные различного типа хранятся и обрабатываются по-разному. В любом алгоритмическом языке каждая константа, переменная, результат вычисления выражения или функции должны иметь определенный тип.
Тип данных определяет:
- внутреннее представление данных в памяти компьютера;
множество значений, которые могут принимать величины этого типа;
- операции и функции, которые можно применять к величинам этого типа.
Исходя из этих характеристик, программист выбирает тип каждой величины, используемой в программе для представления реальных объектов. Обязательное описание типа позволяет компилятору производить проверку допустимости различных конструкций программы. От типа величины зависят машинные команды, которые будут использоваться для обработки данных.
Основные типы данных
Основные (стандартные) типы данных часто называют арифметическими, поскольку их можно использовать в арифметических операциях. Для описания основных типов определены следующие ключевые слова:
- int (целый);
- char (символьный);
- wchar_t (расширенный символьный);
- bool (логический);
- float (вещественный);
- double (вещественный с двойной точностью).
Первые четыре типа называют целочисленными (целыми), последние два — типами с плавающей точкой. Код, который формирует компилятор для обработки
целых величин, отличается от кода для величин с плавающей точкой.
Существует четыре спецификатора типа, уточняющих внутреннее представление и диапазон значений стандартных типов:
- short (короткий);
- long (длинный);
- signed (знаковый);
- unsigned (беззнаковый).
Тип | .. Диапазон значений | Размер (байт) |
bool | true и false | |
signed char | -128...127 | |
unsigned char | 0...255 | |
signed short int | -32 768... 32 767 | |
unsigned short int | 0... 65 535 | |
signed long int | -2 147 483 648... 2 147 483 647 | |
unsigned long int | 0... 4 294 967 295 | |
float | 3.4е-38... 3.4е+38 | |
double | 1.7е-308... 1.7е+308 | |
long double | 3.4е-4932... З.4е+4932 |
Целый тип (int)
Размер типа int не определяется стандартом, а зависит от компьютера и компилятора. Для 16-разрядного процессора под величины этого типа отводится 2 байта, для 32-разрядного — 4 байта.,
Спецификатор short перед именем типа указывает компилятору, что под число требуется отвести 2 байта независимо от разрядности процессора. Спецификатор long означает, что целая величина будет занимать 4 байта. Таким образом, на 16-разрядном компьютере эквиваленты 1nt и short 1nt, а на 32-разрядном — int и long int.
Ключевые слова signed и unsigned необязательны. Они указывают, как интерпретируется старший бит в представлении переменной. Если указано ключевое слово unsigned, то старший бит рассматривается как часть числа. Если же указано ключевое слово signed, то старший бит интерпретируется как знак. По умолчанию все переменные целого типа считаются signed. Ключевые слова signed и unsigned могут предшествовать любому целому типу. Они могут употребляться и самостоятельно при определении переменной. В этом случае они рассматриваются соответственно как signed int и unsigned int.
Типы short int, long int, signed int и unsigned int можно сокращать до short, long, signed и unsigned соответственно.
Символьный тип (char)
Под величину символьного типа отводится количество байт, достаточное для размещения любого символа из набора символов для данного компьютера, что и обусловило название типа. Как правило, это 1 байт. Тип char, как и другие целые типы, может быть со знаком или без знака. В величинах со знаком можно хранить значения в диапазоне от -128 до 127. При использовании спецификатора unsigned значения могут находиться в пределах от 0 до 255. Этого достаточно для хранения любого символа из 256-символьного набора ASCII. Величины типа char применяются также для хранения целых чисел, не превышающих границы указанных диапазонов.
Стандарт C++ определяет три типа данных для хранения вещественных значений: float, double и long double.
Типы данных с плавающей точкой хранятся в памяти компьютера иначе, чем целочисленные. Внутреннее представление вещественного числа состоит из двух частей — мантиссы и порядка. В IBM PC-совместимых компьютерах величины типа float занимают 4 байта, из которых один двоичный разряд отводится под знак мантиссы, 8 разрядов под порядок и 23 под мантиссу. Мантисса — это число, большее 1.0, но меньшее 2.0. Поскольку старшая цифра мантиссы всегда равна 1, она не хранится.
Для величин типа double, занимающих 8 байт, под порядок и мантиссу отводится 11 и 52 разряда соответственно. Длина мантиссы определяет точность числа, а длина порядка — его диапазон. Как можно видеть из таблицы, при одинаковом количестве байтов, отводимом под величины типа float и long int, диапазоны их допустимых значений сильно различаются из-за внутренней формы представления.
Спецификатор long перед именем типа double указывает, что под величину отводится 10 байтов.
Константы с плавающей точкой имеют по умолчанию тип double
Тип void
Кроме перечисленных, к основным типам языка относится тип void, но множество значений этого типа пусто. Он используется для определения функций, которые не возвращают значения, для указания пустого списка аргументов функции (, как базовый тип для указателей и в операции приведения типов