![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Файл mod.cpp
#include " mod.h" #include < stdio.h> void prc(void) { extern a; printf(" %d\n", 2*a); } Внешняя переменная а представляет собой «мостик», по которому данные (значение глобальной переменной a) из модуля prog.cpp передаются в модуль mod.cpp для дальнейшей обработки.
Глава 16. ОТ C к C++ 16.1 Основные отличия языка C++ 16.1 Основные отличия языка C++ Рассмотренные в гл. 1–15 элементы языка входят в подмножество языка C и могут быть откомпилированы при помощи компилятора языка C или C++. Язык C++ имеет множество дополнительных элементов по сравнению с языком C, которые могут быть откомпилированы только компилятором C++[9]. Традиционно программы, написанные на C, имеют расширение *.c, на C++ – *.cpp, и для их компиляции выбирается соответствующий компилятор. Если разработка программы ведется в специальной инструментальной среде, например, в VC++, возможна настройка компилятора для трансляции с языка C или C++. Основное и принципиальное отличие C++ от C составляют классы, эта составляющая языка рассмотрена в гл. 17. Также в C++ появляются новые элементы языка, такие как объекты-потоки для ввода/вывода данных cin и cout, новые операторы (:: – оператор разрешения области видимости), средства для управления памятью (операторы new и delete), шаблоны, обработка исключений. 16.2. Потоковый ввод/вывод в C++ Ввод/вывод в C++ осуществляется с помощью потоков библиотеки C++, доступных при подключении заголовочного файла iostream.h (в VC++.NET – объекта-заголовка iostream). Поток представляет собой объект какого-либо потокового класса. Потоковые классы сконструированы на основе базового класса ios: ios – базовый потоковый класс; istream – класс входных потоков; ostraem – класс выходных потоков; iostream – класс двунаправленных потоков ввода/вывода. В потоковые классы включены операторы добавления данных в поток < < и извлечения данных из потока > >. На основе класса istream в библиотеке C++ объявлен объект-поток cin, представляющий собой стандартный буферизованный входной поток, связанный обычно с клавиатурой консоли. Извлечение данных из потока имеет следующую форму записи: int a; float b; cin > > a > > b; где a и b – переменные заданного типа, в которые помещаются данные из потока cin. В роли разделителей значений в потоке используются пробельные символы (пробел, знак табуляции, перевод строки), поэтому для ввода данных с помощью cin при выполнении программы следует ввести с клавиатуры значения следующими способами: 34 5.78 Enter или 34 Enter 5.78 Enter Ввод данных в поток завершается нажатием клавиши Enter. Если количество заполняемых переменных меньше, чем количество значений в потоке, из потока извлекается столько значений, сколько переменных надо заполнить, а остальные значения сохраняются в потоке и будут прочитаны при следующем извлечении данных из потока. На основе класса ostream объявлен объект-поток cout, представляющий собой стандартный буферизованный выходной поток, связанный обычно с дисплеем консоли. Форма записи добавления данных в поток следующая: cout < < a < < b; при этом значения переменных a и b выводятся на экран без разделителя и в формате, заданном по умолчанию. Перемещение курсора на следующую строку экрана после вывода данных не происходит. Для перевода курсора на новую строку используется манипулятор endl: cout < < a < < " " < < b < < endl; В этом примере значения переменных a и b на экране разделены пробелом, после вывода данных происходит переход на новую строку, а сами значения выводятся на экран в виде, соответствующем их типу: 34 5.78. Для потока cin определен специальный метод для ввода символов – getline(Str, Count), позволяющий в строковую переменную Str ввести из потока заданное количество символов (Count− 1): char str1[128]; cout < < " STR1--> "; cin.getline(str1, 9); cout < < str1 < < endl; Если при выполнении этого фрагмента программы ввести с клавиатуры последовательность символов abcdefghj, в переменную str1 будут помещены 8 символов и символ '\0', а на экране появится строка abcdefgh. В потоках cin и cout можно форматировать данные, для этого используются специальные манипуляторы, доступные через заголовочный файл iomanip.h. Пример Форматирование вывода в потоке cout: #include < iostream.h> #include < iomanip.h> int main(void) { //Выравнивание по левому краю – left, по правому краю – right cout.setf(ios_base:: left); //Вывод с плавающей точкой – scientific, с фиксированной – fixed cout.setf(ios_base:: scientific); //Точность вывода числа на экране cout < < setprecision(3); double x=2.5, y=125.76435; //Ширина поля вывода числа – 15 знаков cout < < setw(15) < < x < < setw(15) < < y < < endl; return 0; } Ответ на экране
16.3. Управлениепамятью в C++ Для создания динамических переменных (гл. 14) в языке C++ используются специальные операторы new и delete. Существуют две формы операторов: для одиночной переменной и массива значений. Оператор new выделяет область памяти для одиночной переменной, размер которой соответствует ее типу, и возвращает указатель того же типа, так что дополнительных преобразований типа указателя не требуется: float * ptr; ptr=new float; В результате выполнения этого фрагмента программы в динамической памяти будет выделена область размером 4 байта для хранения одного значения типа float, и адрес этой области записан в переменную ptr. Для размещения в памяти нескольких значений одного типа (массива) применяется оператор new[]: float * ptrm; ptrm=new float[4]; при этом в квадратных скобках указывается количество элементов, для которых выделяется память. В результате выполнения этого фрагмента программы в динамической памяти будет выделена область размером 16 байт для хранения четырех чисел типа float, и адрес этой области записан в переменную ptrm. Для освобождения динамической памяти, выделенной при помощи new, используется оператор delete. Для одиночной переменной освобождение памяти имеет следующий вид: delete ptr; при этом освобождается область в динамической памяти размером 4 байта. Для освобождения памяти из-под массива, размещенного с помощью оператора new[], следует использовать следующую форму оператора delete: delete[] ptrm; Следует заметить, что недопустимо смешивать формы операторов new и delete: если память выделялась для одиночной переменной (new), то и освобождение должно производиться оператором delete, если в памяти размещался массив (new[]) – для освобождения памяти должен использоваться оператор delete[]. Пример Использование операторов new и delete для размещения данных в динамической памяти: char* st; //Выделение памяти для строки 100 байт st=new char[100]; //Объявление указателя и выделение памяти //для переменной типа int int* ptr1=new int; //Объявление указателя и выделение памяти //для массива элементов типа double double* ptr2=new double[3]; //Ввод данных в переменные cout < < " Введите строку символов (< 100) и целое число-> "; cin > > st > > *ptr1; cout < < " Введите три вещественных числа-> "; for(int i=0; i< 3; i++) cin > > ptr2[i]; cout < < " Введено: " < < endl; cout < < " Строка " < < st < < endl; cout < < " Целое " < < *ptr1 < < endl; cout < < " Массив вещественных чисел" < < endl; for(i=0; i< 3; i++) cout < < i < < " " < < *(ptr2+i) < < endl; //Освобождение памяти для данной переменной delete[] st; delete ptr1; delete[] ptr2; Если при выполнении программы ввести данные следующим образом: zxcvbn 456 Enter 2.5 3.6 4.8 Enter, то на экран будут выведены значения: Введено: Строка zxcvbn Целое 456 Массив вещественных чисел 0 2.5 1 3.6 2 4.8 16.4. Перегрузка функций в C++ В языке C++ в одной программе могут использоваться несколько функций с одним и тем же именем, и каждая из этих функций выполняет свой собственный набор действий. Это называется перегрузкой функций. Перегрузка функций – это свойство языка C++, позволяющее в программе использовать несколько функций с одинаковыми именами, выполняющих различные действия и имеющих различные списки параметров. Пример перегруженных функций: void Message(int); //Вывод кода сообщения об ошибке void Message(char*); //Вывод текста сообщения об //ошибке void Message(int Code) { cout < < " Код ошибки: " < < Code < < endl; } void Message(char* Msg) { cout < < " Ошибка: " < < Msg < < endl; } Вызов перегруженных функций: int main(void) { Message(100); Message(" Деление на нуль! "); return 0; } Компилятор при обработке вызова каждой функции сравнивает списки фактических аргументов при вызове функции и наборы формальных параметров в прототипе функции и по их совпадению определяет, какая из перегруженных функций соответствует вызову. В нашем примере вызов функции Message(100) содержит один целочисленный параметр, что соответствует функции, имеющей прототип void Message(int), а вызов Message(" Деление на нуль! ") совпадает по списку параметров с прототипом функции void Message(char*). Результат выполнения программы: Деление на нуль! Следует заметить, что язык C перегрузку функций не поддерживает. Кроме перегрузки функций в C++ применяется перегрузка операторов. 16.5. Пространства имен в C++ Глобальные переменные видны в любых точках программы, начиная с объявления переменной, локальные – только в пределах блока. Существуют и статические переменные, объявленные внутри блока, их область видимости также ограничивается этим блоком (не путайте с временем жизни!). Язык C++ позволяет ограничить действие имен некоторой областью, специально для этого объявленной. Такая область называется пространством имен и создается с помощью ключевого слова namespace. В пространство имен могут быть включены переменные, функции. Создается пространство имен на внешнем уровне: namespace имя { объявления членов пространства } Например, namespace smp { int count; void calc(); } Функции, объявленные в пространстве имен, имеют прямой доступ к другим членам пространства. Для определения функции, принадлежащей пространству имен, используется оператор разрешения области видимости:: (два двоеточия): void smp:: calc() { count++; } Доступ к членам пространства имен извне возможен двумя способами. 1. При помощи явного указания пространства имен и оператора разрешения области видимости: smp:: calc(); cout < < smp:: count < < endl; 2. При помощи предложения using namespace, включающего данное пространство имен в область видимости текущего блока, что позволяет обращаться к членам пространства без указания имени пространства: using namespace smp; calc(); cout < < count < < endl; Если предложение using объявлено на внешнем уровне, видимость членов пространства имен становится глобальной. При появлении языка C++ элементы, объявленные в библиотеке C++, относились к глобальному пространству имен, не имеющему имени. Действующий стандарт языка C++ все эти элементы относит к пространству имен std. Требования стандарта соблюдены в компиляторе, входящем в состав Microsoft Visual C++.NET, поэтому при разработке программы в этой среде для обращения к потокам cin, cout следует использовать один из приведенных выше способов: int a; std:: cout < < " Введите число"; std:: cin > > a; std:: cout < < " Вы ввели" < < a< < std:: endl; или using namespace std; … int a; cout < < " Введите число"; cin > > a; cout < < " Вы ввели" < < a< < endl;
Глава 17. ОСНОВЫ 17.1. Объектно-ориентированный подход
|