Что такое текстовый редактор?
Текстовый редактор создает и редактирует файлы, содержащие текст. Для написания текстов программ не требуется никаких атрибутов форматирования или специальных символов. Текстовые файлы с листингами программ не обладают такими свойствами, как автоматический перенос слов либо начертание букв полужирным шрифтом или курсивом и т.д.
Если мой компилятор имеет встроенный редактор, то обязан ли я использовать его?
Почти все компиляторы будут компилировать программы, созданные в любом текстовом редакторе. Однако преимущества использования встроенного текстового редактора состоит в том, что он может быстро переключаться между режимами редактирования и компиляции. Высокоорганизованные компиляторы включают полностью интегрированную среду разработки, позволяя программисту легко получать доступ к справочным файлам, редактировать, компилировать и сразу же исправлять ошибки компиляции и компоновки, не выходя из среды разработки.
Могу ли я игнорировать предупреждающие сообщения, поступающие от компилятора?
Среди программистов распространено мнение, что на предупреждающие сообщения компилятора можно не обращать внимания, но я придерживаюсь другого мнения. Возьмите за правило реагировать на предупреждения компилятора как на сообщения об ошибках. Компилятор C++ генерирует предупреждающие сообщения в тех случаях, когда, по его мнению, вы делаете то, что не входит в ваши намерения. Внимательно отнеситесь к этим предупреждениям и сделайте все, чтобы они исчезли.
Что означает время компиляции?
Это время работы вашего компилятора, в отличие от времени компоновки (когда работает компоновщик) или времени выполнения программы (когда выполняется программа). Эти термины придумали программисты, чтобы кратко обозначить временные периоды, в течение которых обычно и проявляются различные ошибки.
Коллоквиум
В этом разделе предлагаются вопросы для самоконтроля и укрепления полученных знаний и приводится несколько упражнений, которые помогут закрепить ваши практические навыки. Попытайтесь самостоятельно ответить на вопросы теста и выполнить задания, а потом сверьте полученные результаты с ответами в приложении Г. Не приступайте к изучению материала следующей главы, если для вас остались неясными хотя бы некоторые из предложенных ниже вопросов.
Контрольные вопросы
1. В чем разница между интерпретатором и компилятором?
2. Как происходит компиляция исходного кода программы?
3. В чем состоит назначение компоновщика?
4. Какова обычная последовательность действий в цикле разработки?
Упражнения
1. Просмотрите следующую программу и попытайтесь понять, что она делает, не запуская ее на выполнение.
1: #include <iostream.h>
2: int main()
3: {
4: int x = 5;
5: int у = 7;
6: cout << "\n";
7: cout << x + у << " " << x * у;
8: cout << "\n";
9: return 0;
10: }
2. Введите программу из упражнения 1, а затем скомпилируйте и запустите ее. Что она делает? Так ли вы все это предполагали?
3. Введите следующую программу и скомпилируйте ее. Какие сообщения об ошибках вы получили?
1: include <iostream.h>
2: int main()
3: {
4: cout << "Hello World\n";
5: return 0;
6: }
4. Исправьте ошибку в программе из упражнения 3, а затем перекомпилируйте, скомпонуйте и выполните ее. Что делает эта программа?
День 2-й. Составные части программы на языке C++
Программы на языке C++ состоят из объектов, функций, переменных и других элементов. Большая часть этой книги посвящена подробному описанию каждого из них, но, для того чтобы получить представление о слаженной работе всех этих элементов, нужно рассмотреть какую-нибудь законченную рабочую программу. Сегодня вы узнаете:
• Из каких частей состоят программы на языке C++
• Как эти части взаимодействуют друг с другом
• Что такое функция и каково ее назначение
Простая программа на языке C++
Даже простенькая программа HELLO.CPP, приведенная на занятии 1, состоит из нескольких элементов, которые представляют для нас интерес. В этом разделе упомянутая программа рассматривается более подробно. В листинге 2.1 ради удобства обсуждения приведена оригинальная версия файла HELLO.CPP.
Листинг 2.1. Демонстрация частей программы C++ на примере программы HELLO. CPP
1: #include <iostream.h>
2:
3: int main()
4: {
5: cout << "Hello World!\n";
6: return 0;
7: }
Результат: Hello World!
АНАЛИЗ: В строке 1 выполняется включение файла iostream.h в текущий файл. Первым в программе стоит символ #, который служит сигналом для препроцессора. При каждом запуске компилятора запускается и препроцессор. Он читает исходный текст программы, находит строки, которые начинаются с символа фунта (#), и работает с этими строками до того, как начнется компиляция программы. Подробнее работа препроцессора рассматривается на занятии 21.
Include — это команда препроцессору, которую можно расшифровать следующим образом: "За именем команды следует имя файла. Нужно найти этот файл и вставить его содержимое прямо в это место программы". Угловые скобки, в которые заключено имя файла, означают, что этот файл нужно искать во всех папках, отведенных для хранения подобных файлов. Если ваш компилятор настроен корректно, то угловые скобки укажут препроцессору на то, что файл iostream.h следует искать в папке, содержащей все файлы с расширением .h, предназначенные для вашего компилятора. Файл iostream.h (input-output-stream — поток ввода-вывода) используется объектом cout, который обслуживает процесс вывода данных на экран. После выполнения строки 1 файл iostream.h будет включен в эту программу, таким образом, как если бы вы собственноручно ввели сюда его содержимое, Препроцессор запускается перед компилятором и выполняет все строки, начинающиеся с символа (#), подготавливая код программы к компиляции.
Основной код программы начинается в строке 3 с вызова функции main(). Каждая программа на языке C++ содержит функцию main(). Функция — это блок программы, который выполняет одно или несколько действий. Обычно функции вызываются другими функциями, но main() — особая функция: она вызывается автоматически при запуске программы.
Функция main(), подобно всем другим функциям, должна объявить тип возвращаемого значения. В программе HELLO.CPP функция main() возвращает значение типа int (от слова integer — целый), а это значит, что по окончании работы эта функция возвратит операционной системе целочисленное значение. В данном случае будет возвращено целое значение 0, как показано в строке 6. Возвращение значения в операционную систему не столь важно, и в общем-то это значение самой системой никак не используется, но стандарт языка C++ требует, чтобы функция main() была объявлена по всем правилам (как показано в этом листинге).
Примечание:Некоторые компиляторы позволяют объявить функцию main() таким образом, чтобы она возвращала значение типа void. Этого больше нельзя делать в C++, поэтому вам следует избавляться от старых привычек. Позвольте функции main() возвращать значения типа int и ради этого поместите в последней строке этой функции выражение return 0;.
Примечание:В некоторых операционных системах предусмотрена возможность проверки значения, возвращаемого программой. Удобно возвращать значение 0 как флаг нормального завершения функции.
Все функции начинаются открывающей фигурной скобкой ({) и оканчиваются закрывающей фигурной скобкой (}). Фигурные скобки функции main() помешены в строках 4 и 7. Все, что находится между открывающей и закрывающей фигурными скобками, считается телом функции.
Вся функциональность нашей простейшей программы заключена в строке 5. Объект cout используется для вывода сообщений на экран. Об объектах пойдет речь на занятии 6, а объект cout и близкий ему объект cin будут подробно рассмотрены на занятии 16. Эти два объекта, cin и cout, используются в языке C++ для организации соответственно ввода данных (например, с клавиатуры) и их вывода (например, на экран).
Вот как используется объект cout: вводим слово cout, за которым ставим оператор перенаправления выходного потока << (далее будем называть его оператором вывода). Все, что следует за этим оператором, будет выводиться на экран. Если вы хотите вывести на экран строку текста, не забудьте заключить ее в двойные кавычки ("), как показано в строке 5.
Строка текста — это набор печатаемых символов.
Два заключительных символа текстовой строки (\n) означают, что после слов Hello world! нужно выполнить переход на новую строку. Этот специальный код подробно объясняется при рассмотрении объекта cout на занятии 17. Функция main() оканчивается в строке 7.
Кратко об объекте cout
На занятии 16 вы узнаете, как использовать объект cout для вывода данных на экран. А пока, не вдаваясь в детали использования объекта cout, скажем, что для вывода значения на экран нужно ввести слово cout, а за ним оператор вывода (<<), который состоит из двух символов "меньше" (<). Несмотря на то что вы вводите два символа, компилятор C++ воспринимает их как один оператор.
Листинг 2.2. Использование обьекта cout
1: // Листинг 2.2. Использование объекта cout
2: #include <iostream.h>
3: int main()
4: {
5: cout << "Hello there.\n";
6: cout << "Here is 5: " << 5 << "\n";
7: cout << "The manipulator endl writes а new line to the screen.";
8: cout <<
9: endl;
10: cout << "Here is a very big number:\t" << 70000 << endl;
11: cout << "Here is the sum of 8 and 5:\t" << 8+5 << endl;
12: cout <<'"Here's a fraction:\t\t" << (float) 5/8 << endl;
13: cout << "And a very very big number:\t";
14: cout << (double) 7000 * 7000 <<
15: endl;
16: cout << "Don't forget to replace Jesse Liberty with your name...\n";
17: cout << "Jesse Liberty is a C++ programmer!\n";
18: return 0;
19: }
За символом вывода укажите выводимые данные. Использование объекта cout показано в листинге 2.2. Введите текст этой программы в точности так, как написано, за исключением одного: вместо имени Jesse Liberty подставьте свои имя и фамилию, лучше латинскими буквами.
Результат:
Hello there.
Here is 5: 5
The manipulator endl writes а new line to the screen.
Here is a very big number: 70000
Here is the sum of 8 and 5: 13
Here's a fraction: 0.625
And a very very big number: 4.9e+07
Don't forget to replace Jesse Liberty with your name...
Jesse Liberty is a C++ programmer!
Примечание: Некоторые компиляторы требуют, чтобы математические операции в случае использования после объекта cout заключались в круглые скобки. В этом случае строку 11 пришлось бы изменить следующим образом:
11: cout << "Here is the sum of 8 and 5:\t" << (8+5) << endl;
В строке 2 по команде #include <iostream.h> препроцессор вставляет содержимое файла iostream.h в исходный текст программы. Включать файл iostream.h необходимо, если в программе используется объект cout и связанные с ним функции-члены.
В строке 5 демонстрируется простейший вариант использования объекта cout: вывод строки символов. Символ \n — это специальный символ форматирования, который указывает объекту cout на необходимость вывода на экран символа новой строки (он произносится "слэш-эн" или просто разрыв строки).
В строке 6 объекту cout передаются три значения, и каждое из них отделяется оператором вывода. Первое значение представляет собой строку "Here is 5: ". Обратите внимание на наличие пробела после двоеточия: пробел является частью текстовой строки. Затем объекту cout с помощью оператора вывода передается значение 5, а за ним — символ разрыва строки (этот символ всегда должен быть заключен в двойные или в одинарные кавычки). При выполнении этого выражения на экране появится строка
Here is 5: 5
Поскольку после первого значения нет символа разрыва строки, следующее значение выводится сразу за предыдущим. Этот процесс называется конкатенацией двух значений.
В строке 7 на экран выводится информационное сообщение, после чего используется оператор endl. Этот оператор также выводит на экран символ разрыва строки. (Другое назначение оператора endl рассматриваются на занятии 16.)
Примечание: Оператор endl расшифровывается как end line (конец строки) и читается как "энд-эл", а не "энд-один" (иногда букву l принимают за единицу).
В строке 10 используется еще один символ форматирования — \t, который вставляет символ табуляции, используемый обычно для выравнивания выводимой информации (строки 10-13). Строка 10 демонстрирует возможность вывода значений типа long int. В строке 11 показано, что объект cout может выводить результат математической операции. Объекту cout передается не значение, а целое математическое выражение 8+5, но на экран выводится число 13.
В строке 12 объект cout выводит результат другой математической операции — 5/8. Идентификатор (float) указывает объекту cout, что результат должен выводиться как дробное число. В строке 14 объекту cout передается выражение 7000 * 7000, а идентификатор (double) устанавливает вывод результата в экспоненциальном представлении. Использование идентификаторов double и float для установки типов значений рассматривается на занятии 3.
В строке 16 нужно вставить свое имя. Если при выполнении программы вы увидите свое имя на экране, шансы стать профессиональным программистом у вас существенно возрастут, хотя в этом и так нет никаких сомнений. Даже компьютер это знает!
Комментарии
Когда вы пишете программу, вам всегда ясно, что вы стараетесь сделать. Однако если через месяц вам придется вернуться к этой программе, то, как это ни удивительно, окажется, что вы почти совсем не помните, о чем идет речь, а о деталях и говорить не приходится.
Чтобы не казнить себя за пробелы в памяти и помочь другим понять вашу программу, используйте комментарии. Комментарии представляют собой текст, который игнорируется компилятором, но позволяет описать прямо в программе назначение отдельной строки или целого блока.
Виды комментариев
В языке C++ используется два вида комментариев: с двойным слешем (//) и сочетанием слеша и звездочки (/*). Комментарий с двойным слешем (его называют комментарием в стиле C++) велит компилятору игнорировать все, что следует за этими символами вплоть до конца текущей строки.
Комментарий со слешем и звездочкой (его называют комментарием в стиле С) велит компилятору игнорировать все, что следует за символами (/*) до того момента, пока не встретится символ завершения комментария: звездочка и слеш (*/). Каждой открывающей паре символов /* должна соответствовать закрывающая пара символов */.
Нетрудно догадаться, что комментарии в стиле С используются также и в языке С, но следует предупредить, что двойной слеш в языке С не воспринимается как символ комментария.
При программировании на C++ для выделения комментариев в основном используются символы двойного слеша, а комментарии в стиле С используются только для временного отключения больших блоков программы. Впрочем, двойной слеш часто используется и для временного отключения отдельных строк программного кода.
Использование комментариев
Раньше считалось хорошим тоном предварять блоки функций и саму программу комментариями, из которых должно было быть понятно, что делает эта функция и какое значение она возвращает.
Исходя из собственного опыта, могу сказать, что такие комментарии не всегда целесообразны. Комментарии в заголовке программы очень быстро устаревают, поскольку практически никто их не обновляет при обновлении текста программы. Функции должны иметь такие имена, чтобы у вас не оставалось ни тени сомнения в том, что они делают, в противном случае имя функции нужно изменить. Зачем использовать бессмысленные и труднопроизносимые имена, чтобы потом раскрывать их смысл с помощью комментариев?
Впрочем, одно другому не помеха. Лучше всего использовать понятные имена и дополнительно вносить краткие разъяснения с помощью комментариев.
Листинг 2.3 демонстрирует использование комментариев, доказывая, что они не влияют на выполнение программы и ее результаты.
Листинг 2.3. Демонстрация комментариев на примере программы HELLO.CPP
1: #include <iostream.h>
2:
3: int main() 4: {
5: /* это комментарий,
6: который продолжается до тех пор, пока не
7: встретится символ конца комментария в виде звездочки и слэша */
8: cout << "Hello world!\n";
9: // Этот комментарий оканчивается в конце строки
10: cout << "That comment ended!\n";
11:
12: // после двойного слеша может не быть никакого текста,
13: /* как, впрочем, и между этими символами */
14: return 0;
15: }
Резултат:
Hello world!
That comment ended!
Комментарии в строках 5—7 полностью игнорируются компилятором, как и комментарии в строках 9, 12 и 13. Комментарий в строке 9 завершается в конце этой строки, но для завершения комментариев, начавшихся в строках 5 и 13, требуется символ окончания комментария (*/).
Напоследок предупреждение: осторожнее с комментариями!
В комментариях, разъясняющих очевидные места, проку немного. Но они могут даже вводить в заблуждение, если при изменения текста программы вы забудете их скорректировать. Однако очевидность — понятие относительное. То, что очевидно для одного человека, может быть непонятно другому. Всегда старайтесь разумно комментировать свои действия и не забывайте обновлять комментарии при обновлении программы.
И последнее, комментарии должны разъяснять, не что это за операторы, а для чего они тут используются.
Функции
Вы уже познакомились с функцией main(), правда, это необычная, единственная в своем роде функция. Чтобы приносить пользу, функция должна быть вызвана во время сеанса работы программы. Функция main() вызывается не программой, а операционной системой.
Программа выполняется по строкам в порядке их расположения в исходном тексте до тех пор, пока не встретится вызов какой-нибудь функции. Затем управление передается строкам этой функции. После выполнения функции управление возвращается той строке программы, которая следует сразу за вызовом функции.
Есть прекрасная аналогия для работы программы с функцией. Например, если во время рисования у вас ломается карандаш, вы прекращаете рисовать и затачиваете его. После этого вы возвращаетесь к тому месту рисунка, где сломался карандаш. Когда программа нуждается в выполнении некоторой сервисной операции, вызывается функция, ответственная за выполнение этой операции, после чего программа продолжает свою работу с того места, где была вызвана функция. Эта идея демонстрируется в листинге 2.4.
Листинг 2.4. Пример вызова функции
1: #include <iostream.h>
3: // Функция Demonstration Function
4: // выводит на экран информативное сообщение
5: void DemonstrationFunction()
6: {
7: cout << "In DemonstrationFunction\n";
8: }
10: // Функция main выводит сообщение, затем
11: // вызывает функцию DemonstrationFunction и
12: // выводит на экран второе сообщение.
13: int main()
14: {
15: cout << "In main\n" ;
16: DemonstrationFunction();
17: cout << " Back in main\n";
18: return 0;
19: }
Результат:
In main
In DemonstrationFunction
Back in main
В строках 5—8 определяется функция DemonstrationFunction(). Она выводит на экран сообщение и возвращает управление программе.
Функция main() начинается в строке 13, и в строке 15 выводится на экран сообщение, уведомляющее о том, что сейчас управление программой находится в функции main(). После вывода этого сообщения в строке 16 вызывается функция DemonstrationFunction(). В результате этого вызова выполняются команды, содержащиеся в функции DemonstrationFunction(). В данном случае вся функция состоит из одной команды, содержащейся в строке 7, которая выводит другое сообщение. По завершении выполнения функции DemonstrationFunction() (строка 8) управление программой возвращается туда, откуда эта функция была вызвана. В данном случае выполнение программы продолжается со строки 17, в которой функция main() выводит на экран заключительное сообщение.
Использование функций
Функции возвращают либо некоторое реальное значение, либо значение типа void, т.е. ничего не возвращают. Функцию, которая складывает два целых числа и возвращает значение суммы, следует определить как возвращающую целочисленное значение. Функции, которая только выводит сообщение, возвращать нечего, поэтому для нее задается тип возврата void.
Функции состоят из заголовка и тела. Заголовок содержит установки типа возвращаемого значения, имени и параметров функции. Параметры позволяют передавать в функцию значения. Следовательно, если функция предназначена для сложения двух чисел, то эти числа необходимо передать в функцию как параметры. Вот как будет выглядеть заголовок такой функции:
int Sum(int а, int b)
Параметр — это объявление типа данных значения, передаваемого в функцию. Реальное значение, передаваемое при вызове функции, называется аргументом. Многие программисты используют эти два понятия как синонимы. Другие считают смешение этих терминов признаком непрофессионализма. Возможно, это и так, но в данной книге эти термины взаимозаменяемы.
Тело функции начинается открывающей фигурной скобкой и содержит ряд строк (хотя тело функции может быть даже нулевым), за которыми следует закрывающая фигурная скобка. Назначение функции определяется содержащимися в ней строками программного кода. Функция может возвращать значение в программу с помощью оператора возврата (return). Этот оператор также означает выход из функции. Если не поместить в функцию оператор возврата, то по завершении функции автоматически возвращается значение типа void. Значение, возвращаемое функцией, должно иметь тип, объявленный в заголовке функции.
Примечание: Более подробно функции рассматриваются на занятии 5; типы значений, возвращаемых функциями, — на занятии 3. Информация, представленная на этом занятии, является хотя и обзорной, но вполне достаточной для усвоения последующего материала, поскольку функции будут использоваться практически во всех программах, представленных в этой книге.
В листинге 2.5 демонстрируется функция, которая принимает два целочисленных параметра и возвращает целочисленное значение. Не беспокойтесь пока насчет синтаксиса или особенностей работы с целыми значениями (например, int x): эта тема подробно раскрывается на занятии 3.
Листинг 2.5. Пример использования простой функции (FUNC.CPP)
1: #include <iostream.h>
2: int Add (int x, int у)
3: {
4:
5: cout << "In Add(), received " << x << " and " << у << "\n";
6: return (x+y);
7: }
8:
9: int main()
10: {
11: cout << "I'm in main()!\n";
12: int а, b, с;
13: cout << "Enter two numbers: ";
14: cin >> а;
15: cin >> b;
16: cout << "\nCalling Add()\n";
17: c=Add(a,b);
18: cout << "\nBack in main().\n";
19: cout << "с was set to " << с;
20: cout << "\nExiting...\n\n";
21: return 0;
22: }
Результат:
I'm in main()!
Enter two numbers: 3 5
Calling Add()
In Add(), received 3 and 5
Back in main().
c was set to 8
Exiting...
АНАЛИЗ: Функция Add() определена в строке 2. Она принимает два целочисленных параметра и возвращает целочисленное значение. Сама же программа начинается в строке 9, выводя на экран первое сообщение. Затем пользователю предлагается ввести два числа (строки 13—15). Пользователь вводит числа, разделяя их пробелом, а затем нажимает, клавишу <Enter>. В строке 17 функция main() передает функции Add() в качестве аргументов два числа, введенные пользователем.
Управление программой переходит к функции Add(), которая начинается в строке 2. Параметры а и b выводятся на экран, а затем складываются. Результат функции возвращается в строке 6, и на этом функция завершает свою работу.
Резюме
Сложность изучения такого предмета, как программирование, состоит в следующем: большая часть изучаемого вами материала во многом зависит от того, что вам еще только предстоит изучить. На этом занятии вы познакомились с основными составляющими частями простой программы на языке C++. Кроме того, вы получили представление о цикле разработки и узнали несколько важных терминов.
Вопросы и ответы
Какую роль выполняет директива #include?
Это команда для препроцессора, который автоматически запускается при вызове компилятора. Данная директива служит для введения содержимого файла, имя которого стоит после директивы, в исходный текст программы.
В чем разница между символами комментариев // и /*?
Комментарии, выделенные двойным слешем (//), распространяются до конца строки. Комментарии, начинающиеся слешем со звездочкой (/*), продолжаются до тех пор, пока не встретится символ завершения комментария (*/). Помните, что даже конец функции не завершит действие комментария, начавшегося с пары символов (/*). Если вы забудете установить завершение комментария (*/), то получите сообщение об ошибке во время компиляции.
В чем разница между хорошими и плохими комментариями?
Хороший комментарий сообщит читателю, почему здесь используются именно эти операторы, или объяснит назначение данного блока программы. Плохой комментарий констатирует то, что делается в данной строке программы. Программа в идеале должна писаться так, чтобы имена переменных и функций говорили сами за себя, а логика выражений была проста и понятна без особых комментариев.
Коллоквиум
В этом разделе предлагаются вопросы для самоконтроля и укрепления полученных знаний и приводится несколько упражнений, которые помогут закрепить ваши практические навыки. Попытайтесь самостоятельно ответить на вопросы теста и выполнить задания, а потом сверьте полученные результаты с ответами в приложении Г. Не приступайте к изучению материала следующей главы, если для вас остались неясными хотя бы некоторые из предложенных ниже вопросов.
Контрольные вопросы
1. В чем разница между компилятором и препроцессором?
2. В чем состоит особенность функции main()?
3. Какие два типа комментариев вы знаете и чем они отличаются друг от друга?
4. Могут ли комментарии быть вложенными?
5. Могут ли комментарии занимать несколько строк?
Упражнения
1. Напишите программу, которая выводит на экран сообщение I love C++.
2. Напишите самую маленькую программу, которую можно скомпилировать, скомпоновать и выполнить.
3. Жучки: введите эту программу и скомпилируйте ее. Почему она дает сбой? Как ее можно исправить?
1: #include <iostream.h>
2: int main()
3: {
4: cout << Is there а bug here?";
5: return 0;
6: }
4. Исправьте ошибку в упражнении 3, после чего перекомпилируйте ее, скомпонуйте и запустите на выполнение.