Выделим основные инструментальные программные средства, позволяющие создавать, отлаживать, анализировать и выполнять программы. Реальные компиляторы с языков программирования высокого уровня превращают исходную программу не сразу в коды, а в некоторую промежуточную форму, называемую объектным кодом. После компиляции в такой промежуточный объектный код необходим еще один этап, во время которого из объектных кодов отдельных частей программы собирается вся программа в кодах целиком. На этом же этапе, называемом редактированием связей или сборкой, происходит подключение стандартных подпрограмм, если они нужны, и преобразование оставшихся имен в адреса.
Таким образом, программист с помощью служебной программы — редактора текстов — записывает исходный текст своей программы в какие-то файлы на диске, с помощью другой программы — компилятора — преобразовывает их в объектные коды, с помощью третьей — редактора связей (сборщика) — получает программу в кодах или загрузочный файл. После этого загрузочный файл можно выполнить средствами операционной системы. Эти три вида инструментальных средств составляют минимальный набор, позволяющий разрабатывать программы. Рассмотрим эти и другие средства подробнее.
Редактор (editor)— программа для ввода и редактирования исходного текста.
Компилятор (compiler) — программа, преобразующая исходный текст программы в выполняемый код. Как правило, компилятор порождает так называемый объектный файл — машинный код с незаполненными внешними ссылками, хотя могут генерировать и исполняемые файлы. По способу генерации кода компиляторы делятся на обычные и оптимизирующие. Оптимизирующие компиляторы работают гораздо дольше обычных, но генерируют код, оптимизированный по скорости или по объему.
Компоновщик или редактор связей (linker)— программа, собирающая из совокупности объектных файлов и библиотек исполняемую программу. По способу генерации кода компоновщики делятся на обычные и инкрементальные. Инкрементальные редакторы связей позволяют значительно ускорить процесс компоновки за счет учета информации о предыдущей компоновке.
Отладчик (debugger) — программа, позволяющая контролировать код и данные программы во время ее выполнения с целью обнаружения ошибок. В настоящее время распространены символьные отладчики, позволяющие кроме чисел отображать код на ассемблере либо на исходном языке высокого уровня.
Профилировщик (profiler) — программа, предназначенная для оценки эффективности выполнения различных участков кода. Профилировщики встраивают в программу специальный код, позволяющий подсчитать частоту вызова различных подпрограмм, время их работы с учетом и без учета вызываемых подпрограмм и большое количество других параметров. Накопленную информацию профилировщики отображают в численном виде, а наиболее совершенные из них — в виде графиков и диаграмм.
Библиотекарь (librarian) — программа, позволяющая создавать из объектных файлов библиотеки.
Библиотека (library) — набор данных и подпрограмм.Библиотеки по способу использования делятся на статические (static library) и динамически связываемые (dynamic link library — DLL). Статические используются только при компоновке программы, при которой из них извлекаются используемые модули. Динамические библиотеки постоянно находятся в памяти, вследствие чего их модулями могут пользоваться различные программы одновременно. Для этого используется специальный механизм динамического связывания.
В настоящее время для платформы Intel наиболее известны следующие проблемно-ориентированные библиотеки, предназначенные для построения пользовательского интерфейса:
- Object Windows Library (OWL) — для приложений Microsoft Windows;
- Microsoft Foundation Classes (MFC) — для приложений Microsoft Windows;
- Visual Component Library (VCL) — для приложений Microsoft Windows.
Для Unix-платформ принят более унифицированный подход к построению пользовательского интерфейса, получивший название X Window. В его основе лежит библиотеки нижнего уровня Xlib и среднего уровня — Xintrinsics, на основе которых предложены две конкурирующие библиотеки высокого уровня — OpenLook фирмы Sun и Motif объединения Open Software Foundation (OSF).
Все перечисленные инструментальные средства по способу вызова могут быть как автономными, так и встроенными в интегрированную среду программирования.
Интегрированная среда разработчика (Integrated Developer Environment). Это программа, интегрирующая в себе редактор, компилятор, отладчик и большинство других указанных выше инструментальных средств. Интегрированная среда может как содержать отдельные компоненты в себе, так и вызывать их извне, что определяется политикой фирм-разработчиков.
В настоящее время многие интегрированные среды поддерживают популярную технологию визуального программирования — так называемую технологию быстрой разработки приложений (Rapid Application Development — RAD). Эта технология позволяет быстро создавать и изменять графический интерфейс пользователя. Поскольку программирование графического интерфейса пользователя является достаточно объемной и сложной задачей, то путем сокращения затрат на его создание уменьшаются затраты на разработку приложения в целом.
В то же время, технология RAD не может ускорить создание прикладной части программы, которая занимается собственно обработкой данных. Эта часть работы, в любом случае, ложится на программистов.
Другие инструментальные средства. Кроме перечисленных, нередко используют другие инструменты, такие как генераторы дистрибутивов, построители файлов справки, генераторы документации и т.д.
3.4. Некоторые аспекты программирования на алгоритмическом языке С/С++
1. Компилятор языка чувствителен к коду символов (литер). Служебные слова в операторах, как правило, пишутся маленькими (не прописными) буквами. Существуют специальные случаи, например служебное слово EOF, написание которых оговорено в справочной или сопроводительной литературе.
2. В логических выражениях, с помощью которых записываются условия в управляющих структурах, используются логические величины (переменные), однако в яыке С/С++ отсутствует специальный тип для их описания. Если выражение может быть приведено к целому значений 1 или к любому ненулевому значению, то оно считается истинным, если к целому 0 – то ложным.
3. Во всех структурах языка С/С++ «оператор» может представлять собой как одиночный оператор, так и блок (составной оператор), т.е. совокупность операторов, заключенных в фигурные скобки {…}.
4. Для использования стандартных или входящих в комплект поставки функций С/С++ к исполняемой программе подключаются необходимые библиотечные файлы. Это можно сделать при помощи директивы препроцессору #include <имя библиотечного файла>. Эти директивы предписывают процессору поместить на место встретившегося в исполняемой программе имени функции содержимое функции-подпрограммы из указанного библиотечного файла.
5. Препроцессор расширяет все макровызовы и подставляет все внешние файлы. В результате работы препроцессора формируется исходный текст на С/С++, который далее обрабатывается компилятором.
6. Ввести данные в программу можно либо оператором присваивания, либо оператором ввода с экрана дисплея, либо с помощью генератора случайных чисел. Функции генерации случайных чисел описаны в библиотечном файле stdlib.h. Функция randomize() генерирует начальное значение последовательности случайных чисел, а функция random (n) определяет (возвращает) целое положительное число в диапазоне от 0 до n.
7. Следует помнить, что комментарии – это пояснения к оператору, блоку или тексту программы. Они используются либо по прямому своему назначению, либо на начальном этапе отладки программы, поскольку являются неисполняемой частью программы. Комментарии в С-программах заключаются в скобки /*…*/, а также пишутся после двойной косой черты //, тогда информация до конца строки воспринимается комментарием.
8. Язык программирования С мобилен и причудлив в описании типов и позволяет создавать сложные структуры данных. При описании сложных идентификаторов используются следующие правила:
- чем ближе модификатор стоит к идентификатору, тем выше его приоритет;
- модификаторы [] и () имеют более высокий приоритет, чем *;
- круглые скобки используются для объединения частей идентификаторов, имеющих самый высокий приоритет.
Пример. float (*ff)(); // указатель на функцию, возвращающую тип float.
float *fg[7] (); // массив указателей из семи элементов на функцию, возвращающую тип float.
9. Функции и операторы, позволяющие завершать или приостанавливать выполнение блока программы, а также приостанавливать вывод данных на экран:
void exit(int status) – функция описана в библиотеке stdlib.h, завершает выполнение программы и всех функций, буферы открыты для записи; status определяет статус или код завершения и равен 0, если осуществляется нормальное завершение программы;
void abort (void) – функция описана в библиотеке stdlib.h, завершает выполнение программы при наличии ошибок выполнения, соответствует функции exit(3);
break – завершает выполнение управляющих операторов ветвления и цикла;
continue – возвращает управление к началу цикла, пропуская оставшуюся его часть;
return– прерывает выполнение функции и возращает ей значение выражения;
void delay (unsigned int) – функция описана в библиотеке dos.h и приостанавливает выполнение программы на заданное число миллисекунд;
int getch(void) – функция описана в библиотеке conio.h, читает символ с клавиатуры и приостанавливает выполнение программы до нажатия на любую клавишу;
kbhit(void) – функция описана в библиотеке conio.h, возвращает целое ненулевое значение, если на клавиатуре была нажата клавиша или 0 в противном случае.
4. Основы языка программирования С/С++
При написании программ в языках С и С++ используются следующие понятия:
· алфавит;
· константы;
· идентификаторы;
· ключевые слова;
· комментарии.
Алфавит (или множество литер) языка программирования C++ основывается на множестве символов таблицы кодов ASCII. Алфавит C++ включает:
· строчные и прописные буквы латинского алфавита (мы их будем называть буквами),
· цифры от 0 до 9 (назовём их буквами-цифрами),
· символ '_' (подчерк - также считается буквой),
· набор специальных символов: " { } , | [ ] + - %? < > = ! / \ ; ' : & # ~ ^ . *
· прочие символы.
Алфавит C++ служит для построения слов, которые в C++ называются лексемами. Различают пять типов лексем:
· идентификаторы;
· ключевые слова;
· знаки (символы) операций;
· литералы;
· разделители.
Почти все типы лексем (кроме ключевых слов и идентификаторов) имеют собственные правила словообразования, включая собственные подмножества алфавита.
Лексемы разделяются разделителями. Этой же цели служит множество пробельных символов, к числу которых относятся пробел, символы горизонтальной и вертикальной табуляции, символ новой строки, перевода формата и комментарии.
В языке программирования С++ существуют правила построения идентификаторов из букв алфавита:
1. Первым символом идентификатора C++ может быть только буква.
2. Следующими символами идентификатора могут быть буквы, буквы-цифры и буквы-подчерки.
3. Длина идентификатора неограниченна (фактически же длина зависит от реализации системы программирования).
Вопреки правилам словообразования в C++ существуют ограничения относительно использования подчерка в качестве самой первой буквы в идентификаторах. Особенности реализации делают нежелательными для использования идентификаторы, которые начинаются с этого символа.
Часть идентификаторов C++ входит в фиксированный словарь ключевых слов. Эти идентификаторы образуют подмножество ключевых слов. Прочие идентификаторы после специального объявления становятся именами. Имена служат для обозначения переменных, типов данных, функций и меток.