Скачать презентацию Язык программирования С продолжение Лекция 06 11 12 Скачать презентацию Язык программирования С продолжение Лекция 06 11 12

Лекция-21.ppt

  • Количество слайдов: 36

Язык программирования С++ (продолжение) Лекция 06. 11. 12 г. 1 Язык программирования С++ (продолжение) Лекция 06. 11. 12 г. 1

Тесты по программированию (http: //www. quizful. net/test ) Лекция 06. 11. 12 г. 2 Тесты по программированию (http: //www. quizful. net/test ) Лекция 06. 11. 12 г. 2

Тесты по программированию (http: //www. quizful. net/test ) Лекция 06. 11. 12 г. 3 Тесты по программированию (http: //www. quizful. net/test ) Лекция 06. 11. 12 г. 3

Использование аргументов по умолчанию в функциях Формальному параметру функции может быть задан аргумент по Использование аргументов по умолчанию в функциях Формальному параметру функции может быть задан аргумент по умолчанию (default argument). Обычно это константа, которая часто встречается при вызове функции. Использование аргумента по умолчанию позволяет не задавать его значение при каждом вызове. int sqr_or_power(int n, int k = 2) { //k = 2 по умолчанию if (k == 2) return (n * n) ; else return pow(n, k) ; } Здесь предполагается, что чаще всего эта функция применяется для вычисления значения квадрата целого числа n. Вызовы этой функции могут выглядеть следующим образом: sqr_or_power(i + 5); //вычислит (i + 5) * (i + 5) sqr_or_power(i + 5, 3); //вычислит (i + 5) в кубе Лекция 13. 11. 12 г. 4

Использование аргументов по умолчанию в функциях Только несколько последних параметров функции могут иметь значения Использование аргументов по умолчанию в функциях Только несколько последних параметров функции могут иметь значения по умолчанию, т. е. аргументами по умолчанию могут быть аргументы, начиная с правого конца списка параметров функции и далее последовательно слева направо без перерывов. Значения по умолчанию можно указать и для всех аргументов функции. Использование аргументов по умолчанию, как и многих других возможностей «по умолчанию» , позволяет уменьшить труд программистов по созданию текста программы. void void foot foot (int (int i, int j = 7) ; //допустимо i, int j = 2, int k) ; //недопустимо i, int j = 3, int k = 7) ; //допустимо i = 1, int j = 2, int k = 3); //допустимо i = -3, int j); //недопустимо Лекция 13. 11. 12 г. 5

Перегрузка (совмещение имен) функций В языке С может быть только одна функция с одним Перегрузка (совмещение имен) функций В языке С может быть только одна функция с одним именем. Пример: семейство функций, которые выводят на экран некоторое значение (число или строку). int main () { void print_int (int v); print_int (10); void print_float (float v); print_float (5. 5); void print_sz (const char *v); print_sz ("Привет!n"); } В языке С++ можно «поручить» компилятору задачу по выбору нужного варианта функции. Для этого нужно определить набор функций, каждая из которых имеет имя print, но эти функции различаются количеством или типами аргументов. Предыдущий пример тогда будет выглядеть следующим образом: void print (int v); void print (float v); void print (const char *v); int main () { print (10); print (5. 5); print ("Привет!n"); } Лекция 13. 11. 12 г. 6

Перегрузка (совмещение имен) функций Таким образом, перегрузкой называется ситуация, когда в одном контексте (в Перегрузка (совмещение имен) функций Таким образом, перегрузкой называется ситуация, когда в одном контексте (в одной области имен) находятся несколько функций с одинаковыми именами, но различными сигнатурами. Перегрузка реализует один из видов функционального полиморфизма – статический полиморфизм, при котором реализация функции выбирается в зависимости от фактических типов параметров функции. Такой выбор происходит на этапе компиляции программы (реализуется так называемое «раннее связывание» ). Ещё бывает динамический полиморфизм, при котором реализация функции-члена класса выбирается в зависимости от фактического типа указателя на объект, через который она вызывается. Такой выбор происходит на этапе выполнения программы (т. н. «позднее связывание» ). Этот вид полиморфизма реализуется виртуальными функциями. Лекция 13. 11. 12 г. 7

Понятие о сигнатуре функции Сигнатура функции — часть общего объявления функции, позволяющая транслятору идентифицировать Понятие о сигнатуре функции Сигнатура функции — часть общего объявления функции, позволяющая транслятору идентифицировать функцию среди других. В различных языках программирования существуют разные представления о сигнатуре функции, что также тесно связано с возможностями перегрузки функции в этих языках. В языке С++ простая функция однозначно опознаётся компилятором по её имени и последовательности типов её аргументов, что составляет сигнатуру функции в этом языке. Если функция является методом некоторого класса, то в сигнатуре будет участвовать и имя класса. Например, сигнатурой функции: std: : size_t num. Digits(int number); будет: std: : size_t(int) Иными словами, это «функция, принимающая int и возвращающая std: : size_t» . Лекция 13. 11. 12 г. 8

Ограничения на перегрузку функций 1) Функции должны отличаться количеством или типом аргументов, т. е. Ограничения на перегрузку функций 1) Функции должны отличаться количеством или типом аргументов, т. е. должны иметь различные сигнатуры. 2) На перегрузку не влияет тип возвращаемого значения. 3) Использование параметров по умолчанию может войти в конфликт с перегрузкой. #include #include void f(int a) { cout<<"1"< #include void f(int a) { cout<<"1"<

Стандартная библиотека С++ Ни одна «серьезная» программа не может быть написана только с использованием Стандартная библиотека С++ Ни одна «серьезная» программа не может быть написана только с использованием «чистых» конструкций языка; программисты обязательно используют средства поддержки, которые, как правило, разрабатываются одновременно с языком, реализуются в виде библиотек поддержки и создают основу для успешной работы. Стандартная библиотека С++ является «надстройкой» над языком и существенно расширяет его базовые возможности, предоставляя разработчикам большое количество удобных и полезных конструкций, которые могут использоваться ими в качестве «строительных блоков» . Описание библиотеки и требования к ней (состав, интерфейсы, функциональность и пр. ) включены в международный стандарт языка С++: Programming languages – C++, INTERNATIONAL STANDARD ISO/IEC 14882, Second edition 2003 -10 -15 ISO/IEC 14882: 2011. Programming languages — C++, Third edition Лекция 13. 11. 12 г. 10

Язык Средства поддержки Лекция 13. 11. 12 г. 11 Язык Средства поддержки Лекция 13. 11. 12 г. 11

Стандартная библиотека С++ Основные источники: Н. Джосьютис C++. Стандартная библиотека. Для профессионалов. –СПб. : Стандартная библиотека С++ Основные источники: Н. Джосьютис C++. Стандартная библиотека. Для профессионалов. –СПб. : Питер, 2004. — 730 с. Электронная документация по библиотеке расположена по адресу: http: //msdn. microsoft. com/ru-ru/library/cscc 687 y(v=vs. 100). aspx Лекция 13. 11. 12 г. 12

51 файл 33 файла – С++ <algorithm> <bitset> <complex> <deque> <exception> <fstream> <functional> <iomanip> 51 файл 33 файла – С++ 18 файлов – С Лекция 13. 11. 12 г. String I/O STL 13

Библиотека ввода-вывода (iostream) В языке С++ нет специальных операторов для ввода или вывода данных. Библиотека ввода-вывода (iostream) В языке С++ нет специальных операторов для ввода или вывода данных. Вместо этого имеется набор классов, стандартно поставляемых вместе с компилятором, которые и реализуют основные операции ввода-вывода. Библиотека классов для ввода-вывода решает две задачи. Во-первых, она обеспечивает эффективный ввод-вывод данных всех встроенных типов, а также простое и гибкое определение операций ввода-вывода для новых типов, разрабатываемых программистом. Во-вторых, сама библиотека позволяет при необходимости развивать её и модифицировать. Механизм ввода-вывода в С++ называется потоком и реализуется классами istream (поток ввода) и ostream (поток вывода), определёнными в iostream. В этом файле определены также три глобальных объекта: cout, cerr (объекты класса ostream, выполняющие вывод на терминал) и cin (объект класса istream, выполняющий ввод с терминала). cout называется стандартным выводом, cin – стандартным вводом, cerr – стандартным потоком сообщений об ошибках. Вывод осуществляется с помощью операции <<, ввод с помощью операции >>, например: cout << "Пример вывода: " << 34; int x; cin >> x; Лекция 13. 11. 12 г. 14

Операции << и >> для потоков В классах библиотеки iostream операции >> и << Операции << и >> для потоков В классах библиотеки iostream операции >> и << определены для всех встроенных типов языка С++ и для строк (тип char*). Если мы хотим использовать такую же запись для ввода и вывода объектов других классов, то для них нужно выполнить перегрузку этих операций. Эта возможность будет рассмотрена в теме «Перегрузка операций для классов» . Лекция 13. 11. 12 г. 15

Форматирование ввода-вывода и манипуляторы Манипуляторы – это объекты-функторы, которые могут использоваться в качестве операндов Форматирование ввода-вывода и манипуляторы Манипуляторы – это объекты-функторы, которые могут использоваться в качестве операндов операторов ввода-вывода для управления потоком. Манипуляторы могут выводить в поток дополнительные данные, считывать их из потока, устанавливать флаги и делать многое другое. Перечень некоторых стандартных манипуляторов: endl - при выводе перейти на новую строку; ends - вывести нулевой байт (признак конца строки символов); flush - немедленно вывести и опустошить все промежуточные буферы; dec - выводить числа в десятичной системе (действует по умолчанию); oct - выводить числа в восьмеричной системе; hex - выводить числа в шестнадцатеричной системе; setw (int n) - установить ширину поля вывода в n символов; setfill(int n) - установить символ-заполнитель; этим символом выводимое значение будет дополняться до необходимой ширины; setprecision(int n) - установить количество цифр после запятой при выводе вещественных чисел; setbase(int n) - установить систему счисления для вывода чисел; n может принимать значения 0, 2, 8, 10, 16, причем 0 означает систему счисления по умолчанию, т. е. 10. Специализированные манипуляторы могут создаваться программистом самостоятельно. Лекция 13. 11. 12 г. 16

Форматирование ввода-вывода и манипуляторы Те же манипуляторы (за исключением endl и ends) могут использоваться Форматирование ввода-вывода и манипуляторы Те же манипуляторы (за исключением endl и ends) могут использоваться и при вводе. В этом случае они описывают представление вводимых чисел. Кроме того, имеется манипулятор, работающий только при вводе, это ws. Данный манипулятор переключает вводимый поток в такой режим, при котором все пробелы (включая табуляцию, переводы строки, переводы каретки и переводы страницы) будут вводиться. По умолчанию эти символы воспринимаются как разделители между атрибутами ввода. int x; // ввести шестнадцатеричное число cin >> hex >> x; Лекция 13. 11. 12 г. 17

Примеры //Ex 100. cpp #include <iostream> using namespace std; int main( ) { double Примеры //Ex 100. cpp #include using namespace std; int main( ) { double values[] = { 1. 23, 35. 36, 653. 7, 4358. 24 }; for( int i = 0; i < 4; i++ ) { cout. width(10); cout. fill( '*' ); cout << values[i] << 'n'; } } Вид командной строки для вызова компилятора: "%devcpp%g++" Ex 100. cpp -std=c++0 x -o Ex 100 Лекция 13. 11. 12 г. 18

Примеры //Ex 101. cpp #include <iostream> #include <iomanip> using namespace std; int main( ) Примеры //Ex 101. cpp #include #include using namespace std; int main( ) { double values[] = { 1. 23, 35. 36, 653. 7, 4358. 24 }; char *names[] = { "Zoot", "Jimmy", "Al", "Stan" }; for( int i = 0, n = sizeof names / sizeof names[0]; i < n; i++ ) cout << setiosflags( ios: : left ) << setw( 6 ) << names[i] << resetiosflags( ios: : left ) << setw( 10 ) << values[i] << endl; } Лекция 13. 11. 12 г. 19

Примеры //Ex 102. cpp #include <iostream> #include <iomanip> using namespace std; int main( ) Примеры //Ex 102. cpp #include #include using namespace std; int main( ) { double values[] = { 1. 23, 35. 36, 653. 7, 4358. 24 }; char *names[] = { "Zoot", "Jimmy", "Al", "Stan" }; cout << setiosflags( ios: : fixed ); //cout << setiosflags( ios: : scientific ); for( int i = 0, n = sizeof names / sizeof names[0]; i < n; i++ ) cout << setiosflags( ios: : left ) << setw( 6 ) << names[i] << resetiosflags( ios: : left ) << setw( 10 ) << setprecision( 1 ) << values[i] << endl; } Лекция 13. 11. 12 г. 20

Строковые потоки Специальным случаем потоков являются строковые потоки, определенные в заголовочных файлах sstream и Строковые потоки Специальным случаем потоков являются строковые потоки, определенные в заголовочных файлах sstream и strstream. Все операции для этих потоков происходят в памяти. Фактически такие потоки формируют форматированную строку символов, заканчивающуюся нулевым байтом. Строковые потоки применяются для облегчения форматирования данных в памяти. Лекция 13. 11. 12 г. 21

Пример //Ex 110. cpp #include <iostream> #include <sstream> #include <bitset> using namespace std; int Пример //Ex 110. cpp #include #include #include using namespace std; int main() { ostringstream os; // Десятичное и шестнадцатеричное значение os << "dec: " << 15 << hex << " hex: " << 15 << endl; cout << os. str() << endl; // Присоединение вещественного числа и битового поля bitset<15> b(1023); os << "float: " << 4. 67 << " bitset: " << b << endl; // Перезапись восьмеричным числом os. seekp(0); os << "oct: " << oct << 15; cout << os. str() << endl; } Сначала в os выводятся два числа – десятичное и шестнадцатеричное. Затем к ним присоединяется вещественное число и битовое поле (в двоичном виде). Функция seekp(0) перемещает позицию записи в начало потока данных, поэтому при следующем вызове оператора << данные записываются в начало строки с перезаписью существующего строкового потока данных. При этом символы, которые не были перезаписаны, остаются действительными. Лекция 13. 11. 12 г. 22

Пример //Ex 111. cpp #include <iostream> #include <strstream> using namespace std; int main() { Пример //Ex 111. cpp #include #include using namespace std; int main() { double x = 13. 57; ostrstream buffer; // Динамический поток char* // Заполнение потока char* buffer << "float x: " << x << ends; cout << buffer. str() << endl; // Снятие фиксации с потока char* buffer. freeze(false); // Установка позиции записи в начало buffer. seekp (0, ios: : beg); // Повторное заполнение потока char* buffer << "once more float x: " << x << ends; cout << buffer. str() << endl; // Возвращение памяти в буфер buffer. freeze(false); } Лекция 13. 11. 12 г. 23

Ввод-вывод файлов может выполняться как с помощью низкоуровневых, безо всякого контроля типов, стандартных функций Ввод-вывод файлов может выполняться как с помощью низкоуровневых, безо всякого контроля типов, стандартных функций библиотеки С, так и с помощью потоков ввода-вывода. Файл рассматривается как последовательность байтов. Чтение или запись выполняются последовательно. При операциях чтения-записи говорят, что существует текущая позиция, начиная с которой будет производиться следующая операция. Большинство файлов обладают возможностью прямого доступа. Это означает, что можно производить операции ввода-вывода не последовательно, а в произвольном порядке. В библиотеке fstream для ввода-вывода файлов определены классы ofstream (вывод) и ifstream (ввод). Сами операции ввода-вывода выполняются так же, как и для других потоков: >> "ввести" и << "вывести". Различия заключаются в том, как создаются объекты и как они привязываются к нужным файлам. Лекция 13. 11. 12 г. 24

Примеры //Ex 103. cpp #include <fstream> using namespace std; int iarray[2] = { 99, Примеры //Ex 103. cpp #include using namespace std; int iarray[2] = { 99, 10 }; int main( ) { ofstream os( "test. dat" ); // текстовый вывод ofstream ofs ( "test 1. dat", ios_base: : binary ); // двоичный вывод os. write( (char*)iarray, sizeof(iarray) ); ofs. write( (char*)iarray, sizeof(iarray) ); } 00 00 00 0 A 0 D 00 00 00 63 10 99 00 00 00 0 A 00 00 00 63 10 Лекция 13. 11. 12 г. 99 25

//Ex 105. cpp #include <fstream> #include <iostream> using namespace std; /* Для всех файлов, //Ex 105. cpp #include #include using namespace std; /* Для всех файлов, имена которых переданы в аргументах командной строки, - открыть, вывести содержимое и закрыть файл */ int main (int argc, char* argv[]) { ifstream file; // Перебор аргументов командной строки for (int i=1; i

Лекция 13. 11. 12 г. 27 Лекция 13. 11. 12 г. 27

Пространства имён Термин «пространство имён» (namespace) – один из основных в языках программирования. Он Пространства имён Термин «пространство имён» (namespace) – один из основных в языках программирования. Он связан с возможностью различения сущностей программы с одинаковыми именами. int x; // первая x void foo (char x) { // вторая x x = 12; // здесь x - это вторая x } void bar () { x = 12; // здесь x - это первая x } int main () { double x; // третья x x = 12; // здесь x -- это третья x } В этом фрагменте программы 4 пространства имён и 3 различных переменных, имеющих одинаковые имена «х» . Лекция 13. 11. 12 г. 28

Пространства имён Каждый блок также имеет своё пространство имён. Например: int main(){ int x Пространства имён Каждый блок также имеет своё пространство имён. Например: int main(){ int x = 1, y = 321; { int x; x = 2; { int x; x = 3; y = 123; } cout << x; // 2 } cout << x; // 1 cout << y; // 123 } Здесь в одной функции объявлено три разных переменных «х» . Когда внутри блока определяется очередной «x» , он скрывает (маскирует) все предыдущие переменные с таким же именем. Но как только блок заканчивается, его локальный «х» исчезает, и вновь становится доступным «х» из родительского (объемлющего) блока. Лекция 13. 11. 12 г. 29

Пространства имён структур Каждая структура также имеет своё пространство имён. Для доступа к таким Пространства имён структур Каждая структура также имеет своё пространство имён. Для доступа к таким именам используется операция разрешения контекста (разрешения области видимости) – двойное двоеточие. #include #include struct Foo { typedef unsigned int uint; enum color {white, black}; uint data [16]; }; int main(void) { Foo: : uint x; x = 17; Foo: : color y = Foo: : black; cout << x << " " << y << endl; // 17 1 system("PAUSE"); return 0; } Лекция 13. 11. 12 г. 30

Пространства имён структур могут быть вложенными: #include <stdlib. h> #include <iostream. h> struct A Пространства имён структур могут быть вложенными: #include #include struct A { struct B { struct C { int x, y; }; }; }; int main(void) { A: : B: : C a; a. x = 17; a. y = 23; cout << a. x << " " << a. y << endl; // 17 23 system("PAUSE"); return 0; } Лекция 13. 11. 12 г. 31

Определяемые пользователем пространства имён В предыдущих примерах пространства имён были «бесплатным приложением» к чему-то Определяемые пользователем пространства имён В предыдущих примерах пространства имён были «бесплатным приложением» к чему-то другому — к блоку, к функции, к структуре. . . Однако в С++ есть конструкция, которая позволяет создавать пространство имён «в чистом виде» : namespace N { typedef unsigned int uint; } int main(void) { N: : uint data [16]; … } Лекция 13. 11. 12 г. 32

Определяемые пользователем пространства имён Пространство имён можно дополнять новыми именами любое количество раз, в Определяемые пользователем пространства имён Пространство имён можно дополнять новыми именами любое количество раз, в разных частях программы, в т. ч. и в разных файлах: namespace NS { struct A { int x, y; }; } namespace NS { typedef long int lint; } int main(void) { NS: : A a; a. x = 17; a. y = 23; NS: : lint z = 3456; . . . return 0; } Лекция 13. 11. 12 г. 33

Определяемые пользователем пространства имён Пространства имён могут быть вложенными: namespace NS 1 { namespace Определяемые пользователем пространства имён Пространства имён могут быть вложенными: namespace NS 1 { namespace NS 2 { namespace NS 3 { struct A { int x, y; }; } } } int main(void) { NS 1: : NS 2: : NS 3: : A a; . . . return 0; } Лекция 13. 11. 12 г. 34

Ключевые слова using namespace и using С помощью ключевого слова using namespace можно «разрешить» Ключевые слова using namespace и using С помощью ключевого слова using namespace можно «разрешить» обращаться ко всем именам из указанного пространства имён «напрямую» , без операции разрешения контекста: namespace NS { struct A { int x, y; }; } namespace NS { typedef long int lint; } int main(void) { using namespace NS; A a; a. x = 17; a. y = 23; lint z = 3456; . . . return 0; } Лекция 13. 11. 12 г. 35

Ключевые слова using namespace и using Ключевое слово using «даёт разрешение» обращаться к конкретному Ключевые слова using namespace и using Ключевое слово using «даёт разрешение» обращаться к конкретному имени из указанного пространства имён «напрямую» , без операции разрешения контекста: namespace NS { struct A { int x, y; }; } namespace NS { typedef long int lint; } int main(void) { using NS: : lint; NS: : A a; a. x = 17; a. y = 23; lint z = 3456; . . . return 0; } Лекция 13. 11. 12 г. 36