Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

Что произойдет, если мы вызовем функцию area следующим образом:

int s1 = area(7;   // ошибка: пропущена скобка )

int s2 = area(7)   // ошибка: пропущена точка с запятой ;

Int s3 = area(7);  // ошибка: Int — это не тип

int s4 = area('7); // ошибка: пропущена кавычка '

Каждая из этих строк содержит синтаксическую ошибку; иначе говоря, они не соответствуют грамматике языка С++, поэтому компилятор их отклоняет. К сожалению, синтаксические ошибки не всегда можно описать так, чтобы программист легко понял, в чем дело. Это объясняется тем, что компилятор должен проанализировать немного более крупный фрагмент текста, чтобы понять, действительно ли он обнаружил ошибку. В результате даже самые простые синтаксические ошибки (в которые даже невозможно поверить) часто описываются довольно запутанно, и при этом компилятор ссылается на строку, которая расположена в программе немного дальше, чем сама ошибка. Итак, если вы не видите ничего неправильного в строке, на которую ссылается компилятор, проверьте предшествующие строки программы.

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

“Вы неправильно написали слово int; не следует употреблять прописную букву i.”

Скорее, он выразится так:

“Синтаксическая ошибка: пропущена ';' перед идентификатором 's3'

“У переменной 's3' пропущен идентификатор класса или типа”

“Неправильный идентификатор класса или типа 'Int'

Такие сообщения выглядят туманными, пока вы не научитесь их понимать и использовать. Разные компиляторы могут выдавать разные сообщения, анализируя один и тот же код. К счастью, вы достаточно скоро научитесь понимать эти сообщения без каких-либо проблем. В общем, все эти зашифрованные сообщения можно перевести так:

“Перед переменной s3 сделана синтаксическая ошибка, и надо что-то сделать либо с типом Int, либо с переменной s3.”

Поняв это, уже нетрудно решить проблему.

ПОПРОБУЙТЕ

Попробуйте скомпилировать эти примеры и проанализируйте ответы компиляторов.

<p id="AutBody_Root067"><strong>5.3.2. Ошибки, связанные с типами</strong></p>

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

int x0 = arena(7); // ошибка: необъявленная функция

int x1 = area(7);  // ошибка: неправильное количество аргументов

int x2 = area("seven",2); // ошибка: первый аргумент

                          // имеет неправильный тип

Рассмотрим эти ошибки.

1. При вызове функции arena(7) мы сделали опечатку: вместо area набрали arena, поэтому компилятор думает, что мы хотим вызвать функцию с именем arena. (А что еще он может “подумать”? Только то, что мы сказали.) Если в программе нет функции с именем arena, то вы получите сообщение об ошибке, связанной с необъявленной функцией. Если же в программе есть функция с именем arena, принимающая число 7 в качестве аргумента, то вы столкнетесь с гораздо худшей проблемой: программа будет скомпилирована как ни в чем ни бывало, но работать будет неправильно (такие ошибки называют логическими; см. раздел 5.7).

 2. Анализируя выражение area(7), компилятор обнаруживает неправильное количество аргументов. В языке C++ вызов каждой функции должен содержать ожидаемое количество аргументов, указанных с правильными типами и в правильном порядке. Если система типов используется корректно, она становится мощным инструментом, позволяющим избежать ошибок на этапе выполнения программы (см. раздел 14.1).

3. Записывая выражение area("seven",2), вы могли рассчитывать, что компилятор увидит строку "seven" и поймет, что вы имели в виду целое число 7. Напрасно. Если функция ожидает целое число, то ей нельзя передавать строку. Язык C++ поддерживает некоторые неявные преобразования типов (см. раздел 3.9), но не позволяет конвертировать тип string в тип int. Компилятор даже не станет угадывать, что вы имели в виду. А что вы могли бы ожидать от вызовов area("Hovel lane",2), area("7,2") и area("sieben","zwei")?

Мы перечислили лишь несколько примеров. Существует намного больше ошибок, которые компилятор может найти в вашей программе.

ПОПРОБУЙТЕ

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже