Компиляциейпрограммы называется преобразование программой-компилятором (входящей в состав Visual Studio) исходного текста программы, написанного на языке программирования (например, на C или C++), в машинный код.
Однако часто в программах содержатся ошибки. Некоторые из этих
ошибок автоматически обнаруживаются средствами VS. После обнаружения ошибки выдается соответствующее диагностическое сообщение для пользователя. Такие программные ошибки (фатальные для процесса сборки приложения) можно разделить на две категории: синтаксическиеи ошибки компоновки.
Синтаксические ошибки – это ошибки, обнаруживаемые во время компиляции исходного текста программы и связанные с нарушениями каких-либо синтаксических правил языка программирования. Ошибки компоновки – это ошибки, обнаруживаемые во время объединения объектных файлов для получения исполняемого файла.
Объектный файл – промежуточный файл отдельного модуля программы, полученный в результате компиляции. Содержит в себе особым образом подготовленный код, который может быть объединён с другими объектными файлами для получения готового исполняемого файла.
Исполняемый файл - файл, содержащий программу в том виде, в котором она может быть исполнена компьютером.
Рассмотрим автоматическое обнаружение указанных видов ошибок на
отдельных примерах. Для этого создадим консольное приложение способом, указанным в предыдущем разделе. В окне редактора кода наберите приведенный ниже текст программы (см. пример 2). Затем выполните сборку приложения, выбрав в меню Build► Build Solution. После этого в окне Outputдолжны появиться сообщения об обнаруженных ошибках (рис. 10).
Для более удобной работы со списком ошибок в VS предусмотрено окноError list, которое можно открыть, выбрав в меню View ► Other windows ► Error list. В открытом окне Error listдважды щелкните по первой обнаруженной ошибке и убедитесь, что при
этом в редакторе кода курсор переместится на строку с ошибкой (рис. 11).
СОВЕТ.Полезно просматривать список ошибок, начиная с первой, потому что одна-единственная ошибка может вызвать цепную реакцию, появление «наведенных» ошибок. Исправление этой единственной ошибки приведет и к исчезновению остальных. Однако ограничиваться исправлением только одной ошибки все же не стоит, поскольку вы будете терять время на повторную сборку решения (а оно может составлять в серьезных приложениях до нескольких часов!). С опытом вы научитесь легко отличать «наведенные» ошибки от реальных.
Пример 2.Программа для преобразования массива, содержащая в своем тексте ошибки
// Дан массив размера N из различных целых чисел.
// Ввести элементы массива с клавиатуры. Затем обнулить
// те элементы, массива которые расположены между его
// минимальным и макcимальным элементами (не включая
// эти минимальный и максимальный элементы)
#include "stdafx.h"
const int Nmax = 10;
int _tmain(int argc, _TCHAR* argv[])
{
int a[Nmax], N = 0 /* Ошибка cинтаксиса: отсутсвует ; в конце объявления переменных */
printf("Vvedite razmer massiva N: ");
scnf("%d", &N); /* Ошибка cинтаксиса: неверное имя функции (должно быть scanf_s) */
printf("Vvod elementov massiva a:\n");
for (int i = 0; i < N; i++) {
printf("Vvedite element a[%d]: ", i);
scanf("%d", &a[i]);
/* Ошибка синтаксиса: нет закрывающей скобки } */
// Поиск максимального и минимального элементов
int iMax = 0, iMin = 0;
for (int i = 1; i < N; i++) {
if (a[iMax] < a[i]) iMax = i;
else
if (a[iMin] > a[i]) iMin = i;
}
// Обнуление элементов массива между
// максимальным и минимальным его элементами
i1 = iMin; /* Ошибка cинтаксиса: не объявлен тип переменной i1 (должно быть int i1 = iMin) */
int i2 = iMax;
if (iMin > iMax) {
i1 = iMax; i2 = iMin;
}
for (int i = i1; i < i2; i++) /* Логическая ошибка: должно быть i = i1 + 1 */
a[i] = 0;
printf("Vyvod elementov massiva a:\n");
for (int i = 0; i < N; i++)
printf("Element a[%d] = %d\n", i, a[i]);
getch(); /* Ошибка синтаксиса: в программе отсутсвует описание функции _getch() */ /* Чтобы исправить ошибку, добавьте в начало программы #include <conio.h> */
return 0;
}
Рисунок 10. Окно Выводс сообщениями об ошибках компиляции
Рисунок 11. Окно Список ошибок
Просмотрите весь список обнаруженных при компиляции ошибок. Точно установите строки текста программы, содержащие ошибки (для этого следует дважды щелкнуть по ошибке в списке и курсор в редакторе кода переместится на строку с ошибкой). Используя указания в комментариях в тексте программы, исправьте ошибки, а затем перекомпилируйте программу. Если все синтаксические ошибки были исправлены, то компиляция пройдет успешно и будет собран исполняемый файл.
Проверьте работу программы, запустив ее на выполнение командой меню Debug► Start Debugging(или нажав клавишу F5). На рис. 12 показан пример ввода-вывода программы, из которого видно, что программа, хотя и работает, но выдает неверный результат, поскольку максимальный элемент массива тоже обнуляется.
Рисунок 12. Ввод-вывод элементов массива
Это значит, что в коде программы содержится ошибка, которую автоматически не удалось обнаружить. Средства поиска такого рода ошибок (называемых логическими) будут рассмотрены в следующем разделе.
Теперь рассмотрим пример ошибки, которая обнаруживается на этапе компоновки объектных файлов в исполняемый файл. Представленная ниже программа (пример 3) должна выводить сообщение о том, является ли введенное целое число четным или нечетным.
Пример 3.Программа с ошибкой, обнаруживаемой на этапе компоновки
#include "stdafx.h"
#include <conio.h>
int isEven (int a);
int _tmain(int argc, _TCHAR* argv[])
{
// функция проверки числа на четность
// прототип фукции есть, поэтому
// компилятор не обнаружит ошибку
int a = 0;
printf("Vvedite chislo a: ");
scanf("%d", &a);
if (isEven(a)) // Ошибка компоновки: в программе
// нет описания функции isEven
printf("Chislo a = %d - chet\n", a);
else
printf("Chislo a = %d - nechet\n", a);
getch();
}
//int isEven (int a) { return 0 == a % 2; }
В процессе компиляции этой программы ошибок не будет обнаружено, поскольку вся необходимая компилятору информация о функции isEven дана в прототипе (имя функции, тип возвращаемого ею значения, количество, имена и типы ее формальных параметров).
Однако на этапе сборки компоновщику потребуется определение функции isEven, которое отсутствует (закомментировано) в программе, что вызовет появление соответствующего диагностического сообщения (рис. 13). Внимательное изучение содержимого окна Output(рис. 14) показывает, что программа действительно успешно скомпилировалась, а фатальная ошибка произошла при компоновке.
Для того чтобы исправить ошибку в нашем случае, достаточно убрать знак комментария с последней строки кода в данной программе, после чего следует повторно сделать сборку приложения и проверить его работу. Работа программы после исправления ошибок показана на рисунке 15.
Рисунок 13 Сообщение компоновщика об ошибке
Рисунок 14. Сообщения компилятора и компоновщика в окне Output
Рисунок 15. Работа программы, после исправления ошибок