Простое внесение
Начнем с простой программы, обращающейся к стандартным средствам языка С, а затем преобразуем применяя для ввода-вывода средства библиотеки iostream. (Это был наш первый пример программы на С++)
Вариант на стандартном С | Вариант на С++ | ||
#include <stdio.h> int i; char buff[80]; printf ("Введите число:"); scanf("%d", &i); printf ("Введите символьную строку:"); gets (buff); printf ("Вы ввели число: %d\n Вы ввели строку: %s\n", i, buff); | #include <iostream.h> int i; char buff[80]; cout << "Введите число и символьную строку:"; cin >> i >> buff; cout << "Вы ввели число:" << i << "\n" << "Вы ввели строку:" << buff << "\n"; |
Оставим пока в стороне вопросы ввода (к этому мы еще вернемся), и остановимся на выводе информации.
Сообщения, выводимые программой, будут иметь вид:
Вы ввели число: 12
Вы ввели строку: My string
При этом, применяя стандартной библиотечной функций printf(), мы использовали в качестве одного из параметров этой функции строку формата, которая содержит два спецификатора: %d, %s, которые предписывают оператору printf() осуществить вывод целого числа и строки. Но все вы прекрасно знаете, что такая конструкция весьма чувствительна к ошибкам. Стоит только неправильно указать спецификатор типа или пропустить какой-либо из аргументов, то на выходе получается бессмыслица, а на поиск ее причин и исправление ошибки уйдет время.
И посмотрите, как все те же операции могут быть реализованы с применением iostream.
Данная программа выводит абсолютно то же самое, но отличается во всем остальном. Вывод в ней осуществляется в результате выполнения выражения, а не вызова отдельной функции типа printf(). Приведенное выражение называется выражением внесения, так как текст в данном случае вносится в выходной поток.
Давайте подробнее рассмотрим, как работает операция внесения во второй версии программы. Первым шагом к пониманию операции внесения будет расстановка скобок в выражении так, чтобы можно было понять, каким образом оно интерпретируется компилятором:
(((((cout<<"Вы ввели число:")<<i)<<"\n Вы ввели строку:")<< buff)<<"\n");
Объект cout - это предопределенный объект класса iostream, который используется для вывода. Корме него существуют еще
cin - стандартный поток ввода
cerr - поток для вывода сообщений об ошибках.
Когда компилятор разбирает приведенное выше выражение, он начинает с самого высокого уровня вложенности скобочной структуры и на этом уровне находит
cout<<"Вы ввели число:"
В процессе анализа этого выражения компилятор пытается отыскать функцию - operator<<(), имеющую в качестве левого операнда объект класса ostream, а в качестве правого - целое. Описание переопределяемой функции operator << (ostream &, char*) содержится в заголовочном файле iostream.h. Здесь компилятор С++ преобразует исходное выражение в более пригодное для дальнейшей обработки. В результате получается следующее
operator<<(cout, "Вы ввели число:")
Когда функция operator << (ostream &, char*) будет выполнена, она выведет свой аргумент (строку) и примет значение объекта cout (ее первый аргумент). "Вы ввели число:" выведется на экран, и подвыражением, находящимся на самом глубоком уровне вложенности, станет
cout << i
Теперь компилятор ищет функцию operator <<(ostream &, int). Мы уже говорили, что iostream содержит функции операторы для всех встроенных типов. Процесс продолжается до тех пор, пока выражение внесения не будет сведено к набору вызовов функции operatop << ().
В итоге, выполнение этой сточки приведет к последовательному вызову нескольких функций-операторов
функции | левый операнд | правый операнд | возвращаемое значение |
operator (ostream &, char*) | cout | "Вы ввели число:" | cout |
operator (ostream &, int) | cout | i | cout |
operator (ostream &, char*) | cout | "\n Вы ввели строку:" | cout |
operator (ostream &, char*) | cout | buff | cout |
operator (ostream &, char*) | cout | "\n" | cout |