Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Введение в язык с 69
В качестве примера рассмотрим предложение “Быть программные ошибки катастрофическими могут”. В этом предложении используются правильные слова, однако порядок их следования некорректен. Синтаксические ошибки в С связаны с тем, что допустимые символы языка размещаются в неправильных местах.
Итак, какие синтаксические ошибки присутствуют в программе nogood, с? Во- первых, для пометки тела функции применены круглые скобки, а не фигурные, т.е. допустимые в целом символы языка С находятся в неподходящем месте. Во-вторых, объявления должны выглядеть так:
int n, n2, nЗ;
или, возможно, так:
int n;
int n2;
int nЗ;
Далее, в коде отсутствует пара символов */, необходимая для завершения комментария. (Пару символов /* можно было бы заменить новой формой комментария //.) Наконец, в коде пропущен обязательный символ точки с запятой, который должен завершать оператор printf().
Как обнаруживать синтаксические ошибки? Во-первых, перед компиляцией нужно просмотреть исходный код — возможно, удастся найти какие-то очевидные ошибки. Во-вторых, можно исследовать ошибки, найденные компилятором, т.к. одной из его задач является именно выявление синтаксических ошибок. При попытке компиляции такой программы компилятор сообщает об обнаруженных им ошибках, идентифицируя природу и местоположение каждой ошибки.
Однако и сам компилятор может ошибаться. Настоящая синтаксическая ошибка в одном месте может ввести компилятор в заблуждение и заставить его предполагать, что он нашел другие ошибки. Например, поскольку в примере неправильно объявлены переменные n2 и n3, компилятор может посчитать, что он обнаружил еще несколько ошибок там, где используются эти переменные. В действительности, если не удается разобраться во всех обнаруженных ошибках, то вместо того, чтобы пытаться исправлять сразу все ошибки, сначала следует исправить первые одну или две ошибки, после чего выполнить повторную компиляцию; вполне возможно, что какие-то другие ошибки исчезнут. Продолжайте в том же духе, пока программа не заработает. Еще одна распространенная особенность компилятора заключается в том, что он сообщает об ошибке на одну строку позже. Например, компилятор может не догадаться, что не хватает точки с запятой, пока не наступит очередь компиляции следующей строки. Таким образом, если компилятор жалуется на отсутствие точки с запятой в строке, в которой этот символ имеется, проверьте предыдущую строку.
Семантические ошибки
Семантические ошибки — это смысловые ошибки. В качестве примера рассмотрим следующее предложение: “Презрительные наследники напевают зелено”. Синтаксических ошибок оно не содержит, т.к. прилагательное, существительное, глагол и наречие находятся на своих местах, тем не менее, само предложение бессмысленно. В языке С семантическая ошибка возникает, когда вы соблюдаете все требования языка, но получаете некорректный результат. В рассматриваемом примере присутствует одна такая ошибка:
nЗ = n2 * n2;
70 глава 2
В данном случае предполагается, что n3 представляет куб числа n, в то время как код вычисляет четвертую степень n.
Компилятор не обнаруживает семантических ошибок, поскольку они не нарушают правила языка С. Компилятор не способен предугадывать ваши истинные намерения. Поэтому искать ошибки такого рода придется самостоятельно. Один из способов предусматривает сравнение того, что программа делает, с тем, что вы хотели от нее получить. Например, предположим, что вы исправили синтаксические ошибки в рассмат риваемом примере, так что код теперь приобрел вид, представленный в листинге 2.5.
Листинг 2.5. Программа stillbad.c
Вывод программы выглядит следующим образом:
n = 5, n в квадрате = 25, n в кубе = 625
Несложно заметить, что 625 не является правильным результатом возведения числа в третью степень. Следующий этап предусматривает отслеживание того, как был получен такой результат. В рассматриваемом примере ошибку, скорее всего, удастся выявить путем инспекции кода. Однако в общем случае нужно применять более систематизированный подход. Один из методов — пошаговое отслеживание инструкций программы. Воспользуемся этим методом и в данном случае.
Тело программы начинается с объявления трех переменных: n, n2, и n3. Эту ситуацию можно смоделировать, нарисовав три прямоугольника и пометив их именами переменных (рис. 2.6). Далее программа присваивает переменной n значение 5. Смоделируйте это действие, записав 5 в прямоугольник n. Затем программа умножает n на n и присваивает результат переменной n2. Посмотрев в прямоугольник n, вы увидите, что в нем находится значение 5. Умножьте 5 на 5 и получите 2 5, после чего поместите 25 в прямоугольник n2. Чтобы воспроизвести следующий оператор С (n3 = n2 * n2;), загляните в прямоугольник n2; вы там найдете 25. Умножьте 25 на 25, получите 625 и поместите это значение в прямоугольник n2. Итак, вы возводите n2 в квадрат вместо того, чтобы умножить его на n.
Возможно, эта процедура и избыточна для данного простого примера, однако подобного рода пошаговое выполнение программы часто является наилучщим способом посмотреть, что в ней происходит.
Состояние программы
Выполняя пошаговый просмотр программы вручную с отслеживанием каждой переменной, вы осуществляете мониторинг состояния программы.
Введение в язык С 71
Рис. 2.6. Трассировка программы
Состояние программы -- это просто набор значений всех переменных в заданной точке ее выполнения. Другими словами, это моментальный снимок текущего состояния вычислений.
Мы обсудили только один метод отслеживания состояния: самостоятельное пошаговое выполнение программы. В программе, которая делает, скажем, 10 000 итераций, вы не справитесь с такой задачей. Но можно выполнить несколько итераций, чтобы узнать, делает ли программа то, что от нее ожидается. Тем не менее, всегда существует возможность, что вы выполните эти шаги, как задумали, а не так, как действительно реализовали их в программе, поэтому старайтесь неукоснительно придерживаться фактического кода.
Еще один подход к выявлению семантических ошибок заключается в помещении в разные места кода дополнительных операторов printf() для текущего контроля избранных переменных в ключевых точках программы. Наблюдение за тем, как меняются эти значения, возможно, подскажет вам, что происходит. После того, как вы добьетесь от программы удовлетворительной работы, можете убрать дополнительные операторы и выполнить повторную компиляцию.
Читать дальшеИнтервал:
Закладка: