Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Инофрматика.docx
Скачиваний:
10
Добавлен:
18.07.2019
Размер:
82.03 Кб
Скачать

Информатика (строго С++) 8 семинаров Литература Т.А. Павловская, Ю.А. Щупак «С/С++ Структурное программирование Практикум» Издание «Питер» обязательно иметь, хотя бы электронный вариант. Т.А. Павловская «языки высокого уровня С/С++»

1 семинар – линейные вычислительные процессы 2 – разветвленные -=- 3 – одномерный массив 4 – двумерный массив 6 – строки 7 – структуры

С++ - язык высокого уровня, наиболее распространенный среди профессионалов.

Взять у Дудкина Геннадия Алексеевича дистрибутив Среды С++

Каждый месяц аттестация, в конце семестра зачет, в январе – экзамен.

С++ - язык высокого уровня для профессиональной работы программистов. 1) как готовить программу. 2) как программировать на языке.

Схема процесса подготовки программы к исполнению: 1)Исходная программа; 2)Обработка директив; 3)Расширенная исходная программа; 4)Компилятор (проверка синтаксиса программы); 5а) Есть ошибка => Редактирование исходной программы, возврат на 1; 5б) Нет ошибки => Объектная программа; 6) Компоновка; 7) Исполняемая программа. 8а) Есть ошибка => возврат на 1 8б) Нет ошибки => Результат.

Среда программирования С++

Среда образует необходимые для создания программ средства, к которым относятся: 1) Редактор; 2) Препроцессор; 3) Компилятор; 4) Компоновщик; 5) Отладчик.

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

Функции отладчика: 1) Установка точек останова для прерывания выполнения программы. 2) Трассировка с самого начала или с любого места программы. 3) Пошаговое исполнение программы.

Консольное приложение – программа, которая выполняется из командной строки, не имеет графического интерфейса и имеет концепцию «Рабочей области».

Элйементы языка С++

Основой языка С++ является латинский алфавит и цифры. Строчные и прописные буквы – разные буквы. С++ чувствителен к регистру. Язык С++ имеет свой словарь, который представляет собой совокупность зарезервированных или ключевых слов. Все ключевые слова содержат только строчные буквы.

Кроме алфавита в С++ используются следующие символы: 1) Запятая, точка, точка с запятой; 2) Все скобки (круглые, квадратные, фигурные); 3) Знаки (вопросительный, восклицательный, 1,2 черты); 4) Двойные и одинарные кавычки.

Алгоритм заключается в фигурные скобки после выражения «main(){}». Функция main является обязательной и используется как начальная метка выполнения программы. Может быть записана по-разному, это зависит от используемого типа функций.

Тип INT объявляет функцию main как функцию, которая возвращает целое значение, в этом случае последним оператором функции будет оператор return 0; Тип void сообщает компилятору о том, что функция main не возвращает никакого значения.

Комментарии. Виды комментариев (короткие и длинные): Короткие // текст Длинные /* текст */

Простые типы данных.

Данные хранятся в памяти компьютера. Каждая область памяти однозначна, имеет определенный адрес, на который ссылаются, когда следует сохранить или прочесть данные. Тип данных – множество допустимых значений данных вместе с набором операций, которые применимы к этим данным. Встроенные типы данных (известные компилятору) подразделяются на базовые (простые) и производные типы данных. Помимо встроенных типов данных, программист может определять свои собственные пользовательские типы данных. Данные в программе могут быть представлены константами и переменными, которые имеют идентификатор, тип и значения.

Константа – именованная область в памяти компьютера. Значение константы во время выполнения программы не меняется. Переменная – область в памяти компьютера, в отличие от константы, значение переменной изменяется при работе программы в зависимости от применяемых к ней операций. Каждая переменная имеет имя, тип, размер и значение. В С++ имеются простые базовые типы данных.

Целые (int , char, short, bool) Простой тип данных С плавающей точкой (float, double, longdouble)

Имя типа

Размер в байтах

Допустимые значения

Char

1

-128 to 127

Int

Зависит от реализации

Зависит от реализации

Shortint

2

-32768 to 32767

Longint

4

-2197147483548 (over 9000)

unsignedchar

1

0 to 255

С плавающей точкой

Имя типа

Размер в байтах

Допустимые значения

float

4

double

8

Longdouble

10

Тип bool служит для представления логических данных, которые могут принимать 2 значения (true, false).

Константы простых типов

Формат объявления констант: const идентификатор = значение пример : const float f=1.25

Переменные простых типов

Формат объявления переменных: Тип идентификатор Тип идентификатор = значение

Локальные и глобальные переменные. Локальные переменные – переменные, которые используются в операторах того блока программы, где находится их объявление. За пределами блока они невидимы. Глобальные переменные – переменные, которые доступны из любой части программы. Их область действия – вся программа. Глобальная переменная объявляется 1 раз и по возможности глобальными переменными рекомендуется не пользоваться.

1 // my_first.cpp 2 // программа, печатающая текст 3 #include <iostream> // позволяет программе выводить значения на экран 4 5 //функция main начинает использование программы 6 int main() 7{ 8 std:: cout <<”welcome to C++!\n”; // выводит сообщение 9 10 return 0; // показывает успешное завершение функции 11 12 } // конец функции main

// - примечание, содержит текст, который не обрабатывается компилятором, может быть записан как на отдельной строке, так и справа от какой-то строки #include – директива препроцессора (плагины, походу) Пустые строки используются как правило для выделения ее логических частей. main – название функции, с которой программа начинает свое выполнение, круглые скобки рядом описывают параметры, которые передаются функции. int – целочисленный тип данных, размер которого зависит от интегрируемой среды (short/long) { наинает тело функции, } кончает тело функции. С++ использует потоки для передачи данных в 3 потока (Сout – выводной, Сin – вводный, Сerr – ошибочный) в данном случае с помощью операнда << (направление передачи) правая часть данных передается в левый поток, при этом символ «/» (escape) в сочетании с «n» означает перевод на новую строку. Пример ввода данных в переменную: cin>>a std::cout – означает, что используется имя потока cout, принадлежащее к пространству имен std. using namespace std; - мы заранее включаем пространство имен std и можно не приписывать его каждый раз. using std:cout; using std:cin; Ввод и вывод данных

Представляет собой дополнение к языку С++, которое находится в стандартной библиотеке IOstream (input, output stream) данная библиотека позволяет программировать ввод данных при помощи объекта cin класса instream и вывод данных при помощи объекта cout класса ostream. Используются также операторы поразрядного сдвига >> - для ввода << - для вывода данных. Объект cin поддерживает связь с клавиатурой

Для форматирования вывода используются манипуляторы - функции, которые можно включать в цепочку операций помещения и извлечения данных. Они подразделяются на простые и параметризованные.

Простые: Endl (end line) связан с заголовочным файлом ввода-вывода

Параметризованные:

  1. Setw (int)

  2. Setprecision (int)

  3. Пример: Setw (3) => 3 знакоместа Setprecision (3) => 3 знака после запятой

Кроме того для форматирования вывода используются управляющие последовательности.

Управляющая последовательность |n используется для перехода на новую строку.

Управляющая последовательность |t позволяет форматировать расположение данных как в одной строке, так и в последовательно расположенных строках.

Для использования объектов и операторов ввода/вывода необходимо добавлять в начало файла следующие 2 строки:

# include <IOstream> using namespace std;

Первая строка служит для подключения стандартной библиотеки IOstream Вторая строка необходима для того, чтобы сообщить компилятору об использовании стандартных потоков ввода/вывода. Если не использовать данное пространство имен, то тогда надо будет записывать префикс std:: перед каждым использованием объектов cin и cout.

Структура программы

# include <IOstream> using namespace std; Int main() //(можно void вместо int) Int I, double x; cout << «ввести x» ; cin>>x; cout << «ввести I» ; cin>>I; return 0;

Операции над операндами простых типов

Операция – действие, выполняемое над операндом. Каждая операция обозначается определенным знаком.

Операнд – часть команды, определяющая аргумент, над которым выполняется операция. Операндами являются данные и результаты операции.

Выражения – конструкции языка для вычисления значения в соответствии со значением операндов. В зависимости от количества операндов различают:

  1. Унарные (один операнд) пример: изменение знака числа

  2. Бинарные (два числа) пример: умножение чисел

Арифметические операции

Наименоване

Символ

Синтаксис

Сложение

+

J=i+2

Вычитание

-

J = i-2

Деление

/

J=i/2

Деление по модулю (остаток от деления)

%

J=i%2

Инкремент (увеличение на 1)

++

++i и i++ (префиксный и постфиксный варианты соответственно)

Декремент (уменьшение на 1)

--

--i и i--

Int I=2; cout << ++I << endl; //3 cout << I++ << endl; //3 cout << I << endl; //4

Инкремент увеличивает значение операнда на единицу.

Декремент уменьшает значение операнда на единицу.

Способы записи этих операторов:

  1. Префиксный – до операнда – сначала над операндом производится действие, затем он используется.

  2. Постфиксный – операнд сначала используется, затем над ним производится действие.

Арифметические операции с присваиванием

Операция

Знак

Пример

Присваивание

=

J=y

Замещение

+= ; -=; /=; *=; %=

Y+=5 (Y=Y+5)

Логические операции

Производятся только над выражениями, обладающими двумя значениями (истина или ложь). К логическим операциям относятся:

  1. Отрицание

  2. Конъюнкция

  3. Дизъюнкция

Операция

Знак

Пример

Отрицание

!

Конъюнкция

&&

Дизъюнкция

||

Логические операции реализуются совместно с операциями отношения >,<,=>,=<,!=.

Битовые операции – осуществляются над переменными, рассматриваемыми, как битовые цепочки и применяются для целого типа данных (char, int, long).

&

Битовое умножение

1&1=1, 1&0=0

|

Битовое сложение

0|1=1, 0|0=0

^

Битовое исключающее сложение

1^1=0,

~

Операция битового отрицания

~1=0, ~0=1

Приведение типов данных.

При выполнении арифметических операций результат зависит от типов операндов. Если операнды целого типа => операнды целого типа

Пример: Int a,b Int c C=a/b

Часто бывает, что операнды разных типов. В этом случае работает правило, согласно которому типы операндов приводятся к более общему типу. Однако, часто бывает необходимо преобразовать тип данных.

Int a double b C=a/b с - double

Int a=3 b=2 double C=a/b с - double

Сначала получится 1, затем это значение приведется к типу double. Для того, чтобы деление произошло над данными типа double необходимо хотя бы один из операндов привести к типу double. Для этого необходимо воспользоваться оператором явного преобразования типа.

Int a=3 b=2 r= static_cast (double)(a)/b; //Тип данных, к которому хотим привести

Линейный вычислительный процесс

Y=a+b

  1. Начало

  2. А,B

  3. Y-a+b

  4. Y

Для выполнения математических функций, необходимо подключить smath.

#include <iostream> #include <cmath> #include <conio.h> //для задержек, getch() – команда задержки using namespace std; Int main () {double Z1,Z2,a; cout << «ввести a» << endl; cin >> a; Z1= (1-2*pow(sin(a)2))/(2+sin(2*a)); Z2= (1+(tan(a))/(1-tan(a)); cout << «Z1=» << Z1 << endl; cout << «Z2=» << Z2 << endl; Return 0;}

СанктПБГУВК

Кафедра вычислительных систем и информатики

Лабораторная работа №1.1 Линейные вычисления Расчёт по формуле Вариант №3

ПРАВ: Работу выполнил студент группы из 11 ФИО … Работу принял ВСИ Неклюдова С. А.

Центр СПБ 2011

  1. Условие задачи (из книги 1к1му)

  2. Формализация

  3. Таблица имен (описание идентификаторов (табл)

    Имя в задаче

    Имя в программе

    Тип данного

    Содержание, смысл

    a

    a

    float

    Сторона треуг

  4. Блок-схема алгоритма (все блоки нумеруются

  5. Текст программы

  6. Трассировка

Т.к. результат вычислений совпал с результатом трассировки совпал, алгоритм работает верно.

Операторы

Оператор представляет собой установленное синтаксисом языка базовое действие в программе. В С++ любое выражение, которое заканчивается символом точки с запятой является оператором

Оператор-выражение

К операторам-выражениям относятся:

  1. Оператор присваивания (идентификатор = выражение)

  2. Оператор вызова функций (идентификатор(аргумент1,…,аргумент n)

  3. Пустой оператор, который состоит только из точки с запятой и используется в операторах цикла

Составной оператор

- Состоит из одного или большего числа операторов любого действия, заключенных в фигурные скобки, при этом после фигурной скобки точка с запятой не ставится. Пример {x+y;z/=x;}

Условный оператор

- Имеет следующий формат: if (логическое выражение) оператор Если выражение – истина, то выполняется оператор, иначе программа ничего не делает.

If (a==x) Temp = a;

If (!c) {temp=a; a=y; y=temp;}

Условный оператор If else

If (выражение) оператор 1; else оператор 2;

If (a==x) temp=a else temp=-a

Оператор цикла while

Формат оператора while: while (логическое выражение) оператор

Если логическое выражение – истина, то тогда выполняется оператор и управление переходит обратно в начало цикла. Оператор будет выполняться до тех пор, пока выражение не станет ложным.

Пример: static const int N=10 int x=1, sum=0 while (x<N+1) {sum+=x;++x;} cout<<sum<<endl;

В цикле накапливается сумма целых чисел. Цикл повторяется 10 раз. Значение первого числа x=1 задается до начала цикла. Переменная sum инициализируется значением 0. При каждом проходе, цикл while увеличивает значение sum на текущее значение x, затем увеличивает переменную x на единицу. После того, как значение x станет равным 11, выражение x<n+1 станет ложным и цикл закончится. Управление перейдет к оператору вывода полученной суммы.

Оператор цикла For

Формат: for(выражение1; выражение2; выражение3) оператор

Сначала вычисляется выражение 1. Обычно выражение 1 инициализирует переменную, которая используется в цикле. Затем вычисляется выражение 2 и если оно истина, то выполняется оператор, обрабатывается выражение 3 и управление переходит к началу цикла, то есть к выражению 2. Все повторяется до тех пор, пока выражение 2 не станет ложным.

Пример: static const int N=10; for(int x=1,sum=0;x<N+1;++x) sum+=x; cout<<sum<<endl;

Оператор цикла do while

Формат: do оператор while (логическое выражение)

Сначала выполняется оператор, только затем вычисляется выражение. Пока выражение – истина, управление передается обратно к началу оператора цикла и процесс повторяется. Когда выражение становится ложным, управление переходит к следующему оператору программы. В отличии от оператора while и for, оператор do while выполняется хотя бы 1 раз, так как проверка условия цикла происходит в конце оператора, в связи с этим оператор do while называют циклом с постусловием.

Пример: static cons tint N=10; int x=1,sum=0; do {sum+=x; ++x;} while (x<N+); cout<<sum<<endl;

Оператор передачи управления continue

Направляет поток управления внутри цикла. Он заставляет прекратиться текущую итерацию цикла и немедленно начинает следующую. Оператор continue может использоваться только внутри тела операторов while, for и do while.

#include <IOstream> using namespace std; int main () {int x, sum=0; bool flag=true; while (flag) {cout<<”Enter x”; cin>>x; if(x>0) {sum+=x; continue;} flag=false; } cout<< sun<<endl; return 0; }

В цикле while вводится значение переменной x. Сумма введенных значений накапливается до тех пор, пока вводятся положительные числа. Оператор continue обеспечивает передачу управления к оператору вывода подсказки. Оператор flag=false выполняется когда введено отрицательное значение или 0. Выражение flag в операторе while становится ложным и цикл while завершается, а управление получает оператор вывода результатов.

Вычислить и вывести на экран в виде таблицы значение функции F на интервале Xнач – Xкон, с шагом dx, при этом дается какой-то оператор f = {ax^2+bx+c a<0 c<>0 {-a/x-c a>0 и c=0 {a/(x+c)

Ay И(By или Cy)<>0

В противном случае функция f принимает целое значение.

  1. Построить таблицу

  2. Разветвленное условие

  3. F – действительное F – целое

Static_cast<int>

#include<IOstream> #include<IOmanip> using namespace std; Int main() { double xn,xk,dx,a,b,c,F; cout<<setw(6)<<”enter xn”<<endl; cout<<setw(6)<<”enter xk”<<endl; cout<<setw(6)<<”enter dx”<<endl; cout<<setw(6)<<”enter a”<<endl; cout<<setw(6)<<”enter b”<<endl; cout<<setw(6)<<”enter c”<<endl; cin>>xn; cin>>xk; cin>>dx; cin>>a; cin>>b; cin>>c; cout<<”_______\n”; cout<<”|”<<setw(6)<<”x”<<setw(6)<<”|”<<setw(6)<<”F”<<Setw(6)<<”|”<<endl; cout<<”_______\n”; for (double x=xn; x<xk; x+=dx) {if((a<0)&&(c!=0)) F=a*x*x+b*x+c; if ((a>0)&&(c==0) F=(-a)/(x+c); else F=a/(x+c); if((static_cast<int>(a))&(static_cast<int>(b))|} (static_cast<int>(c)))!=0) cout<<”|”<<setw(6)<<”x”<<setw(6)<<”|”<<setw(6)<<”F”<<Setw(6)<<”|”<<endl; cout<<”|”<<setw(6)<<x<<setw(6)<<”|”<<setw(6)<<static_cast<int>(F)<<Setw(6)<<”|”<<endl; cout<<”_______\n”; } return 0; } Оператор передачи управления Break;

Вызывает выход из циклов: for,do while,while,switch.

Управление передается операторам, находящимся за циклом. Оператор Break позволяет завершить выполнение цикла досрочно.

Пример: #include <iostream> using namespace std; Int main() { int x,sum=0; while (true) { cout<<”enter x “; cin>>x; if (x<=0) break; sum+=x; } cout<<sum<<endl; return 0; }

Если х<=0, то цикл немедленно завершается, благодаря оператору Break. Если х>0 , то накапливается сумма. Выход из цикла возможен только при вводе нуля или отрицательного числа.

Оператор-переключатель switch

Формат оператора: switch (выражение) {case – константа 1: оператор 1 case – константа 2: оператор 2 case – константа 3: оператор 3 case – константа n: оператор n default: оператор

Операторы представляют собой обычные составные операторы, которые содержат метку case, а один из них – необязательную метку default. Метка case представляет собой константное целочисленное выражение. Все метки должны быть уникальные. Значением выражения должен быть символ или целое число. Значение выражения сравнивается с константами во всех вариантах case, после чего управление передается оператору, который соответствует значению выражения. Выражение определяет, который из вариантов case становится выполняемым. Обычно действие, которое выполняется после метки case, заканчивается оператором break и управление передается следующему за switch оператору программы.

Если оператор break отсутствует, управление передается оператору, следующему за case, что делает возможным выполнять одинаковые действия при разных значениях констант. Если не выбирается ни одна из меток case , тогда управление получает case с меткой default, а после его выполнения оператор switch завершается.

Пример: int x; char choise; // (символьная переменная choise) cout<<”enter integer”; cin>>x; cout<<”enter 1..3 “; cin>>choise; switch(choise) {case ’1’: cout<<x<<endl;break; case’2’:cout<<x*x<<endl;break; case’3’:cout<<x*x*x<<endl;break; default: cout<<”error input\n”}

Оператор-переключатель анализирует введенное значение символьной переменной choise. Оператор break, присутствующий в каждом case обеспечивает выход из switch после выполнения необходимых действий, при этом метка default не нуждается в операторе break. Если введен символ 1, то выводится значение переменной х, 2 – х^2, 3 – x^3. Если введен символ отличный от 1,2,3, то выводится сообщение об ошибке ввода.

Оператор возврата return

Форматы: return; return(выражение);

В первом случае оператор прекращает выполнение текущей функции и возвращает управление вызвавшей функции. Во втором случае управление вызвавшей функции передается с передачей значения выражения

Тернарный оператор

Формат: ?:

Выражение1?Выражение2:Выражение3

Оператор называется тернарным, т.к. имеет 3 операнда и представляет собой компактную форму условного оператора if else. Сначала вычисляется выражение 1. Если оно – истина, вычисляется выражение 2 и полученное значение становится результатом оператора. Если выражение 1 – ложно, то вычисляется выражение 3 и оно становится результатом оператора.

Пример: max=(a>b)?a:b;

Оператор sizeof

Формат: sizeof(выражение);

Является статическим и вычисляет длину операнда в байтах. Результат оператора рассматривается, как константа целого типа, никогда не равная нулю.

Данный оператор позволяет программе автоматически определять размеры встроенных типов данных.

Вычисление суммы ряда

Cn=2^n/n! Cn-1=2^(n-1)/(n-1)!

Основные проблемы: 1)2^n 2)n!

Использование рекуррентной формулы при вычислении суммы ряда позволяет:

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

Массивы

Массив – производный тип данных и представляет собой последовательность однотипных данных, имеющих единый идентификатор и хранящихся в смежных ячейках памяти. Количество элементов в массиве называют размером массива.

Для вычисления количества байтов оперативной памяти, которую занимает массив, используется следующая формула: Число_байтов=sizeof(тип данных)*n

Массивы могут быть одномерными и многомерными.

Доступ к элементам массива организуется с помощью индексов. Количество индексов называют размерностью массива. Для массивов определена 1 операция – индексация, при помощи которой происходит обращение к элементам массива. Оператор индексации обозначается квадратными скобками. В зависимости от размера массива, указывается 1 или несколько индексов.

Значение индексов в С++ начинается с 0 до размера указанного массива.

Array[2]- обращение к 3 элементу массива.

Одномерные массивы

Каждому элементу одномерного массива соответствует один индекс. Это целое, неотрицательное число, которое определяет позицию элемента в последовательности.

Объявление одномерного массива имеет вид: Тип данных Идентификатор [Размерность массива]

Обращение к элементу массива производится с помощью оператора индексации

Пример Ввода-вывода одномерного массива

#include <IOstream> using namespace std; const int N=10; int main() //объявление массива из 10 элементов {int array [N]; //цикл ввода элементов массива for(int j=0;j<N;j++) {cout<<”enter array[“<<j<<”]”; cin>>array[j];} //Вывод массива cout<<”\n\n array\n”; for (int j=0, j<N;j++) cout<< array[j];<<’\t’; cout<<endl; return 0;

Пример демонстрирует ввод-вывод 10 элементов целочисленного массива. Размер массива задан глобальной константой целого типа. В начале программы объявляется массив. Индекс элементов массива изменяется от 0 до 9. Для ввода элементов массива используется цикл с параметром (арифметический цикл for). В качестве параметра цикла используется переменная j, которая объявляется и инициализируется нулевым значением как первый элемент массива (индекс 0). Цикл начинается с проверки условия j<N и заканчивается , когда j=N. Последний оператор цикла увеличивает значение индекса на 1.

Второй цикл for используется для вывода элементов массива. Для отделения элементов массива друг от друга при выводе используется управляющая последовательность \t (“Ти”).

Примеры инициализации одномерного массива.

Int m[3]={1,100,200}; unsigned short Y[5]={3,4}; double y[]={1.2,3.5,6.7};

Количество значений в списке может быть меньше объявленного. В этом случае все недостающие элементы инициализируются нулевым значением. Количество элементов массива может вообще не указываться (3 пример). Размер массива вычисляется компилятором автоматически. Пустые квадратные скобки недопустимы при обычном объявлении массива, без его инициализации.

Пример поиска минимальных элементов в одномерном массиве.

Определение минимального элемента в массиве.

#include <IOstream> using namespace std; int main() // Объявление инициализации в массиве { int array[]={5,-10,123,3}; //size int size=sizeof(array[0]); int jMin=0; //Предполагаем, что минимальный элемент массива имеет индекс 0. Запускаем цикл просмотра элементов массива. for(int j=1;j<size;j++) if (array[j]<array[jMin]) jMin=j; //Вывод элементов массива. cout<<”array\n”; for(int j=0;j<size;j++) cout<<array[j]<<’\t’; //Вывод минимального значения элемента массива cout<<array[jMin]<<endl; return 0; }

В программе происходит поиск не самого значения минимума, а его индекса. Предполагаем, что наименьшее значение имеет самый первый элемент массива, поэтому индекс jMin получает значение 0. Цикл проверки управляет изменением значения текущего элемента с индексом j. Если текущий элемент меньше, то с помощью выражения jMin=j корректируется индекс минимального элемента массива.

Пример вычисления среднеарифметического значения элементов массива.

#include <IOstream> using namespace std; int main() {cout int size=6; double array[size]; //Ввод элементов массива for(int j=0; j<size;j++) cin>>array[j]; //вычисляем сумму элементов массива double total=0.0; for(int j=0; j<size; j++) total+=array[j]; //вычисление и вывод среднеарифметического double array=total/size; cout<<”average=”<<average<<endl; return 0; }

Количество элементов массива задается константой size. Первый цикл for предназначен для ввода элементов массива. Второй – для вычисления суммы элементов массива. До начала цикла переменная total обнуляется. Среднеарифметическое

Сортировка элементов массива.

Под пузырьковой сортировкой понимают целый класс алгоритмов сортировки. Пузырьковая сортировка в своем простейшем варианте выполняется медленно. Чаще используются пузырьковые сортировки с оптимизацией. Однако, все алгоритмы пузырьковой сортировки имеют общую особенность: обмен элементов массива производится между 2 соседними элементами.

142 23 97 19 2 4 23 142 97 19 2 4 23 97 142 19 2 4 23 97 19 142 2 4 23 97 19 2 142 4 23 97 19 2 4 142 (142 “всплыл”)

W=array[m]; array[m]=array[m+1]; array[m+1]=w;

1 – 15.09 – 3 балла – с 26 – 3 вариант 2 – 22.09 – 3 балла 2.5 – ряды – 29.09 – 3 балла 06.10 – 3 балла 13.10 – 3 балла 20.10 – 4 балла 27.10 – 4 балла 7.3 – 7 семинар 03.11 – 4 балла 7.4 – 10.11 – 4 балла 7.5 – 17.11 – 4 балла С 151 – 24.11 – 4 балла С 165 – 01.12 – 4 балла 15.12 – балла 8.4 – 22.12 – 4 балла Итого возможно получить 60 баллов – зачет автоматом. Меньше 40 – отчисление 40-60 – на усмотрение лектора $ - 540 руб/час.

Метод пузырька, сортировка.

#include <IOstream> using namespace std; Int main(){ Int nums[10]; Int a,b,t; Int size; size=10; cout<<”Enter massive”<<endl; for (t=0;t<size;t++) cin>>nums[t]; for (a=1;a<size;a++) for(b=size-1;b>=a;b--) {if(nums[b-1]>nums[b]) {t=nums[b-1]; nums[b-1]=nums[b]; nums[b]=t; } } cout<<”sorted massive”;endl; for(t=0;t<size;t++) cout<<nums[t]<<” ”; return 0; }

В одномерном массиве, состоящем из n вещественных элементов, вычислить:

  1. Номер минимального элемента в массиве

  2. Сумму элементов массива, расположенных между первым и вторым отрицательными элементами массива

  3. Преобразовать массив таким образом, чтобы сначала располагались все элементы, модуль которых не превышает 1, а потом – все остальные.

#include <IOstream> #include <IOmanip> using namespace std; Int main() { const int n=9; Int I,k,p,b,i2=0; double m[n],a[n],sum=0,min; for (i=0;i<n;i++_ {cout<<”Enter massive”<<endl; cin>>m[t]; } min=m[0]; k=0; for(i=0;i<n;i++){ if(m[i]<min){ min=m[i]; k=I; } } cout<<endl; cout<<”min=”<<min<<” k=”<<k<<endl;

For (i=0;i<n;i++) {if (m[i]<0){ p=I; break; } } for(i=n-1;i>=0;i--){ if (m[i]<0{ b=I; break; } } cout<<”p=”<<p<<” b=”<<b<<endl; for (i=p+1);i<=b-1;i++) sum+=m[i]; cout<<”sum=”<<sum<<endl; cout<<endl;

For (i=0;i<n;i++){ if (fabs(m[i])<=1){ a[i2]=m[i]; i2++; } } for(i=0;i<n;i++){ if(fabs(m[i]>1){ a[i2]=m[i]; i2++; } } cout<<”massiv”<<endl; for(i=0;i<n;i++){ cout<<a[i]<<endl; return 0; }

В одномерном массиве, состоящем из n вещественных элементов вычислить:

  1. Количество элементов в массиве равных нулю.

  2. Сумму элементов массива, расположенных после минимального элемента.

  3. Упорядочить элементы по возрастанию модулей элементов массива.

#include <IOstream> using namespace std; Int main() { int array[100] int I,j,n,h,sum=0,masnull=0,max; cout<<”enter quantity of elements”; cin>>n; cout<<endl; cout<<”enter massive”; for (i=0;i<n;i++) { cin>>array[i]; cout<<endl; for(i=0;i<n;i++) {cout<<array[i]<<” “;} cout<<endl; for (i=0;i<n;i++) {if (array[i]==0) masnull+=1; }max=array[1]; for(i=0;i<n;i++) {if(array[i]>max) max=array[i]; for(i=0;i<n;i++) {if (array[i]==max) {for(i=i+1;i<n;i++) sum+=array[i];} } for (i=0; i<n;i++) {for(j=0;j<n-1;j++)

To be continued…

Многомерные массивы

Формат объявления двумерного массива Тип идентификатор [n] [m] n – указывает количество строк в матрице m – указывает количества столбцов в матрице

Количество элементов многомерного массива определяется произведением максимальных значений индексов. int array [3][4] => 12 элементов в массиве

Размер массива можно вычислить, как частное от деления количества байтов, занимаемого массивом на количество байтов, которое занимает его первый элемент. числе_элементов=sizeof(идентификатор[])

Обращение к элементу двумерного массива производится точно также, как к элементу одномерного массива, с помощью операции индексации. Массивы, имеющие больше 3 индексов используются крайне редко.

Пример ввода матрицы:

#include <IOstream> using namespace std; Int main() { //объявление максимального значения индексов матрицы const int row=5; const int column=10; //объявление матрицы вещественных чисел из 5 строк и 10 столбцов double matrix[row][column]; //ввод элементов матрицы for(int i=0;i<row;i++) for(int j=0;j<column;j++) cin<<matrix[i][j]; return 0; }

Матрица – двумерный массив, поэтому для ввода каждого элемента необходимо использовать 2 цикла, которые вкладываются друг в друга. Когда циклы вкладываются друг в друга первым выполняется самый внутренний цикл. Он будет инициироваться столько раз, сколько выполняется внешний цикл.

В примере по вводу матрицы внешний цикл с переменной i управляет изменением индекса строки. Внутренний цикл с переменной j изменяет индекс столбца. Каждый цикл имеет собственную инициализацию, проверку и обновление. Внешний цикл повторяет внутренний цикл 5 раз и не производит никакой обработки. Во внутреннем цикле происходит ввод значения элементов матрицы с индексами i и j. Можно вводить 5 строк с вещественными числами по 10 элементов в каждой строке.

Найти сумму четных элементов, расположенных под главной диагональю квадратной целочисленной матрицы…

Прога:

#include <IOstream> #include <IOmanip> #include <cstdlib> using namespace std; Cons tint rang=5; Int main() { int I,j,n=0,summa=0; int mas[rang][rang]; for (i=0;i<rang,i++) {for(j=0;j<rang,j++) {mas[i][j]=rand()%20; cout<<setw(6)<<mas[i][j]; } cout<<endl; } for (i=0;i<rang,i++) for(j=0;j<rang,j++) If((i>j)&&(i<rang-j-1)&&(mas[i][j]%2==0)) summa+=mas[i][j]; cout<<”ln”; cout<<”summa ”<<summa endl; return0; }

Указатели

Все рассмотренные предыдущие примеры в качестве данных использовали обычные переменные. Для таких переменных память выделяется автоматически при запуске программы и также автоматически удаляется при завершении программы. Доступ к значению обычной переменной происходит по ее идентификатору. С++ позволяет обратиться к значению переменной иначе, при помощи адреса, по которому записано значение. Адрес помещается в особую переменную – «указатель». Указатели относятся к производным типам данных, как и массивы. Применение указателей позволяет создавать динамические структуры данных, размер которых определяется не при создании программы, а при ее исполнении. Указатель – это переменная, значением которой является адрес другой переменной. Указатель, как любая переменная должен быть объявлен в программе до его первого использования.

Форматы объявления указателя:

  1. Тип* идентификатор;

  2. Тип *идентификатор;

  3. Тип *идентификатор1 *идентификатор2

Символ * свидетельствует о том, что переменная с указанным идентификатором является указателем. В одной строке может быть объявлен один или несколько указателей одного типа. Тип указателя должен совпадать с типом переменной, адрес которой он хранит. Указатель инициализируется либо при его объявлении, либо с помощью операции присваивания. Нельзя использовать в программе указатель, значение которого не определено. Можно исопльзовать в качестве начального значения Null или адрес. Для инициализации указателя нулевым значением можно записать:

Тип* идентификатор=0;

Тип *идентификатор=0;

Char *pt,p – один адрес, одна переменная, объявлены одновременно.

Название

Знак

Пояснение

Взятие адресов

&

Получить адрес переменной

Разыменование

*

Позволяет получить значение переменной по ее адресу

Присваивание

=

Присвоить указателю адрес переменной или нуль

Всякие

Всякие

Те же арифметические и прочие операции, что и у переменных

Выделение памяти

new

Получить указатель на начало выделенного блока памяти

Освобождение памяти

Delete

Освободить выделенный блок памяти и сделать указатель недоступным

Арифметические операции, связанные с увеличением указателя на целое значение модифицируют значение указателя на число соответствующее произведению целого числа на количество занимаемых типом указателя байт.

Инкримент модифицирует указатель не на единицу, а на число байтов, которое занимает тип указателя.

Пример взятия адреса

#include <IOstream> using namespace std; Int main() { int x=5; int *px=&x; Взятие адреса cout<<”значение адреса”<<x<<endl cotu<<”значение адреса<<&x<<endl cout<<”Вывод px”<<px<<endl; return 0; }

В листинге программы объявляет и инициализируется целая переменная x, кроме того объявляется указатель на данные целого типа px, при этом указатель инициализируется значением адреса переменной x. Для инициализации адреса использована операция взятия адреса.

Пример разыменования указателя

#include <IOstream> using namespace std; Int main() { double v1=0.05,v2=2.5; double *pv; pv=&v1; cout<<”pv=”<<pv<<endl; cout<<”v1=”<<v1<<endl; cout<<”*pv=”<<*pv; pv=&v2; cout<<”*pv=”<<pv<<endl; cout<<”v2=”<<v2<<endl; cout<<”*pv=”<<*pv; return 0; }

В программе объявляются 2 переменные с плавающей точкой v1,v2, а также указатель на тип с плавающей точкой pv. Сначала указатель получает значение адреса переменной v1, а затем организует последовательный вывод указателя pv значения переменной v1 по ее имени и значения переменной v1 через разыменование указателя *pv.

Доступ к переменным массива можно получить через указатель. Пусть известен целочисленный массив int array[10] имя массива «array» является его константным адресом, поэтому выражение вида (array + i) Представляет адрес i-го элемента в массиве array. Для того, чтобы получить значение элемента массива, необходимо выполнить операцию разыменования адреса. *(array + i). Для получения адреса i-го элемента в массиве, можно использовать операцию взятия адреса &(array[i]). Тип указателя на массив должен совпадать с типом массива.

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

#include <IOstream> using namespace std; Int main() { int array[]={10,20,30,40,50} int size=sizeof(array)/sizeof(array[0]); // вывод одномерного массива с использванием константного адреса for (int i=0,i<size,i++) cout<<*(array+i)<<’\t’ cout<<endl;// int *p=array; int count=0; do {cout<<*p++<<’\t’; count++; } while (count<size); cout<<endl; return 0; }

Цикл с for выводит элементы массива array, используя его константный адрес, который является указателем. Для перемещения к следующему элементу, указатель array увеличивается на значение индекса i, а затем операция разыменования *, возвращает значение элемента массива с адресом array + i .

Во второй части программы тот же массив выводится с использованием указателя p, который при объявлении инициализируется адресом array. Цикл с постусловием do while, управляет счетчиком массива count. В цикле, для получения значения элемента массива используется указатель p. Сначала берется значение, хранимое по адресу p, это значение возвращает операция взятия содержимого по адресу (*p). После вывода значения элемента, указатель инкрементируется (p++), делая доступным следующий элемент массива для новой итерации цикла.

Вывод двумерного массива с использованием указателя.

#include <IOstream> using namespace std; Int main() { const int R=2 C=3 Double matrix[R][C] = {15,25,23,3.17,1.5,-2.8} double p=&matrix[0][0]; for(int i=0,i<R;i++) { for(int j=0,j<C;j++) cout<<*(p+i*C+j)<<’t’; cout<<endl; } return 0; }

В листинге программы объявляется указатель на тип с плавающей точкой, который одновременно с объявлением инициализируется адресом первого элемента матрицы. Адрес выводимого элемента матрицы вычисляется при помощи выражения (p+i*C+j) часть этого выражения (p+i*C) позволяет определить адрес первого элемента в строке i, а все выражение целиком – адрес текущего элемента j в i-й строке. Для многомерного массива нельзя инициализировать указатель именем массива. Для этого необходимо выполнять операцию взятия адреса.

Операторы распределения памяти (new,delete)

Для управления свободной памятью, которая предоставляется программе операционной системой, существуют унарные операторы new и delete. Эти операторы позволяют динамически распределять память для любых типов данных и используются для выделения и освобождения памяти в ходе выполнения программы. Создаются данные с помощью оператора new, а удаляют их с использованием оператора delete.

Оператор new выделяет блок памяти и возвращает указатель на первую ячейку этого блока. Если оператор new не в состоянии найти необходимое пространство в свободной памяти, он вернет указатель 0.

Форматы использования оператора new

Указатель=new тип; Указатель=new тип (параметр);

Тип указателя и тип, указанный за словом new, должны совпадать.

Чтобы освободить блок памяти, выделенный оператором new, необходимо воспользоваться операцией динамического освобождения памяти. Оператор delete освобождает память, выделенную заранее оператором new. Недопустимо применение оператора delete для указателя, который не участвовал в выполнении оператора new.

Формат использования оператора delete

Delete указатель;

Освобождение памяти не означает удаление связанного с этим блоком памяти указателя. Просто указатель теряет силу, а память становится свободной.

Пример использования оператора delete: #include <IOstream> using namespace std; Int main(); { int* pi, unsigned short* pi; pi=new int; pu= new unsigned short (200) double* pd=new double; float* pf=new float (-3.15); cout<<”Point”; cout<<pi<<pu; cout<<pd<<pf; cout<<”value с инициализацией” cout<<”\n*pu\t”<<*pu; cout<<”\n*pf\t”<<*pf; cout<<”Value без инициализации”; cout<<*pi cout<<*pd<<endl; *pi=-*pu;*pd=-*pf; cout<<”Value после инициализации”; cout<<*pi<<endl; cout<<*pd<<endl; return0; }

Пример использования оператора delete: #include <IOstream> using namespace std; Int main(); { int x=25; cout<<”Значение x\t”<<x; // объявление указателя с инициализацией int* py=new int (x); cout<<”Значение *py перед delete”<<*py; //освобождение памяти delete py; //состояние памяти после освобождения py cout<<”значение *py после delete”<<py<<endl; return 0; }

Указатели и динамические массивы

Операторы new и delete позволяют выделять и освобождать память при работе с динамическими массивами, размер которых становится известным в процессе выполнения программы. При работе с динамическими массивами используются следующие форматы операторов new и delete:

Указатель=new

Тип массива[размер];

Delete[]указатель;

В операторе delete размер не указывается, но наличие квадратных скобок является обязательным. Их использование сообщает, что одновременно освобождается память, используемая для всех элементов массива.

Строки

Чаще всего одномерные массивы используются для создания символьных строк. В С++ строка определяется как символьный массив, который завершается нулевым символом ‘\0’. При определении длины символьного массива необходимо учитывать признак ее завершения и задавать длину массива на 1 больше, длины самой большой строки. Например объявляя строку str из 10 символов, необходимо зарезервировать место для нулевого символа, то есть char str[11]. С++ позволяет определять строковые литералы. Строковый литерал – список символов, заключенный в двойные кавычки. Пример: “Привет” фактически П Р И В Е Т ‘\0’ “ “ Строка, приведенная последней называется нулевой. Она состоит из одного нулевого символа, используемого для представления нулевых строк.

Считывание строк с клавиатуры

Проще всего считывать строку с клавиатуры, создав массив, который примет эту строку с помощью инструкции cin. Пример: #include <IOstream> using namespace std; Int main(); { char str[80]; cout<<”Введите строку”; cin>>str; cout<<”вывод строки”; cout<<str; return0; }

Недостаток этой программы в том, что она отображает только первое слово. str=>”это пример” – выведена будет только подчеркнутая часть. Дело в том, что оператор прекращает считывание строки как только встречает символ пробела, табуляции или новой строки. Для решения этой проблемы можно воспользоваться библиотечной функцией gets().

Формат функции:

Gets(имя массива)

Если в программе необходимо считывать строку с клавиатуры, необходимо использовать функцию gets(), а в качестве аргумента – имя массива, не указывая индекса. Пример: #include <IOstream> #include <cstdio> using namespace std; Int main(); { char str[80]; cout<<”Введите строку”; gets(str) cout<<”Ваша строка”; cout<<str; return0; }

Некоторые библиотечные функции обработки строк

Strcpy() strcpy(to,from)

Функция strcpy копирует содержимое строки from в строку to. Надо помнить, что массив, используемый для хранения строки to должен быть достаточно большим, чтобы в нем можно было поместить строку из массива from. В противном случае массив to переполнится, что может привести к разрушению программы.

#include <IOstream> #include <cstring> using namespace std; Int main(); { char str[80]; strcpy(str,”Hello”); cout<<str; return0; }

Strcat (S1,S2)

Функция strcat присоединяет строку S2 к концу строки S1. При этом строка S2 не изменяется. Обе строки должны завершаться нулевым символом. Результирующая строка также будет завершаться нулевым символом.

#include <IOstream> #include <cstring> using namespace std; Int main(); { char s1[20],s2[10]; strcpy(s1,”Hello”); strcpy(s2,”everyone”) strcat(s1,s2); cout<<str; return0; }

Функция strcmp (s1,s2) сравнивает строку s1 со строкой s2 и возвращает значение 0, если строки равны. Если строка s1 лексиграфически, то есть в соответствии с алфавитным порядком больше строки s2, то возвращается положительное число. Если строка s1 лексиграфически меньше строки s2, возвращается отрицательное число.

Функция strlen(S) возвращает длину строки, указанной аргументом S.

#include <IOstream> #include <cstring> using namespace std; Int main(); { char str[80]; cout<<”enter string”; gets(str); cout<<”String’s length”<<strlen(str); return0; }

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

#include <IOstream> #include <cstring> using namespace std; Int main(); { char str[80]; Int i; Cout<<”enter string”; gets(str); for (i=strlen(str)-1;i>=0;I--) cout<<str[i]; return 0; }

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

Существует 2 вида строк:

  1. Строки, завершающиеся нулевым байтом.

  2. Строки типа string, реализующие объектно-ориентированный подход к программированию.

Пример удаления вхождений символа из строки.

#include <IOstream> using namespace std; Int main(); { char S[]=”aaabbb”; char c=’a’; cout<<”string”<<S<<endl; int i=0; int j=I; while (S[i]) {fi (S[i]!=c ) S[j+1]=S[i]; i++; } S[j]=’\0’; cout<<s<<endl; return 0; }

Программа изменяет состояние исходной строки таким образом, что в ней не остается ни одного вхождения заданного символа. Модификация исходной строки происходит в цикле, который управляет изменением индекса i для обращения к элементу строки. Инициализация индекса нулевым значением происходит до начала итераций. Оператор j=i определяет значение индекса j, который используется для новой нумерации элементов в строке. Если проверяемый элемент строки s[i] не совпадает с удаляемым символом ‘c’, происходит запись этого символа по индексу j. После записи элемента на новое место, индекс j увеличивается на 1 для подготовки к записи следующего элемента модифицированной строки. Как только в цикле while (цикл с предусловием) проверка элементов строки обнаружит нулевой байт, цикл закончится. Для окончательного формирования нового состояния строки по индексу j, записывается символ завершения строки.

Модифицированная программа удаления цифр из строки.

#include <IOstream> using namespace std; Int main(); { char S[]=”aaabbb777”; int I; for (j=0,i=0;S[i];i++) if (!(S[i]>=’0’&&S[i]<=’9’)) S[j++]=S[i] S[j]=’\0’; cout<<S<<endl; return 0; }

Удаляет все символы цифр из исходной строки. Вместо оператора цикла while, здесь используется цикл for, арифметический цикл с параметрами. Выражение в условном операторе if будет истинным тогда, когда анализируемый символ S[i] не будет входить в диапазон от символа 0 до символа 9.

Пример реверса строки.

#include <IOstream> using namespace std; Int main(); { char []=”aaabbb” cout<<”string:\t\t”<<S<<endl; int len=sizeof(S)-1; \\ размер строки без нулевого байта int i=0; j=len-1; \\ I – индекс для перемещения от начала строки \\ j – индекс для перемещения от конца строки char tmp; \\ tmp – переменная для перестановки элементов do { tmp=S[i]; S[i++]=S[j]; S[j--]=tmp; } while (i<j); \\ цикл с постусловием, предназначен для реверса строки cout<<”result:\t\t”<<S<<endl; } return 0; }

После объявления и вывода исходной строки, вычисляется размер строки в байтах, без учета нулевого байта. В следствии того, что элемент типа char занимает в оперативной памяти 1 байт, количество символов в строке совпадает с ее размером. Индекс элемента с нулевым байтом будет равен вычисленному размеру len, т.к. индексация в массиве начинается с нуля. Для реверса строки необходимо попарно менять местами символы, имеющие одинаковое смещение от начала и от конца строки. Для организации перестановки, используются 2 индекса i и j и переменная tmp. До начала цикла обработки строки, индекс i инициализируется нулевым значением, что соответствует индексу первого элемента, а индекс j инициализируется len-1, который определяет индекс символа перед нулевым байтом. В программе используются оператор цикла с постусловием do while, который управляет изменением индекса i, для обращения к начальным элементам строки и изменением индекса j, для обращения к элементам от конца строки. Итерации в цикле происходят до тех пор, пока значение i меньше значения j.

Обмен с потоком для увеличения скорости передачи данных производится через специальную область оперативной памяти, которая называется буфер. Фактическая передача данных выполняется при выводе после заполнения буфера, а при вводе, если буфер исчерпан.

По направлению обмена потоки можно разделить:

  • Входные

  • Выходные

  • Двунаправленные

По виду устройств, с которыми работает поток:

  • Стандартные

  • Файловые

  • Строковые

Стандартные потоки служат для передачи данных от клавиатуры на экран дисплея.

Файловые потоки для обмена информации с файлами внешних носителей.

Строковые потоки – для работы с массивами символов в оперативной памяти.

Для поддержки потоков библиотека C++ содержит иерархию классов, построенную на базе двух базовых классов “ios” и “streambuf”. “ios” содержит общие для вывода и ввода поля инвертора. “streambuf” обеспечивает буферизацию потоков и взаимодействие с физическими устройствами. От этих двух классов наследуется класс “istream” и “ostream”. “istream” – класс для входных потоков. “ostream” – для выходных. В свою очередь, эти два класса являются базовыми для класса “iostream”, который реализует двунаправленные потоки. “ifsream” – класс входных файловых потоков. “ofstream” – класс выходных файловых потоков. “fstream” – класс двунаправленных файловых потоков.

Методы обмена с потоками

Вместе с операциями извлечения и включения (>>, <<) определяют методы для неформативного чтения и записи в поток.

Функции чтения в классе “istream”

get ()

get (с)

get (buf, num, lim=’\n’);

getline (buf, num, lim=’\n’);

sekq (pos);

Функция “get ()” возвращает код извлеченного и из потока символа. “get (c)” возвращает ссылку на поток, из которого выполняется чтение и запись извлеченных символов в “c”. “ get (buf, num, lim=’\n’)” считывает num-1 символ, пока не встречает символ lim и копирует эти символы в символьную строку “buf”. Вместо символа “lim” в строку записывается признак конца строки. “getline (buf, num, lim=’\n’)” аналогична предыдущей функции, но копирует в “buf” и символ “lim”. “sekq (pos)” устанавливает текущую позицию чтения в значение “pos”.

Запись файлов

ofstream out (“tx”);

if (!out) {

cout<<”Не можем открыть файл “test” для записи”<<endl;

return 1;

}

ifstream in (“textЭб ios::in/ios::nocreate);

if (!in) {

cout<<”Не можем открыть файл “text” для чтения”<<endl;

return 1;

}

Файловые потоки

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

  • Создание потока

  • Открытие потока и связывание его с файлом

  • Обмен, ввод/вывод

  • Закрытие файла

Задача: написать программу, которая считывает текст из файла, выводит его на экран, заменив цифры от 0 до 9 на слова, начиная каждое предложение с новой строки.

#include <iostream>

#include <fstream>

using namespace std;

int main ()

{ ifstream fin (“file_in.text”);

ofstream fout (“file_out.text”);

char temp;

while (!fin.eof()) {

fin.get (temp);

switch (temp) {

case‘0’: fout<<”Ноль”; break;

case‘1’: fout<<”Один”; break;

case‘2’: fout<<”Два”; break;

case‘9’: fout<<”Девять”; break;

case’.’: fout<<endl; break;

case’\n’: fout<<endl; break;

default: fout<<” “;

break;

}

}

return 0;

}

Структуры

Структура объединяет логически связанные данные разных типов и представляет собой набор переменных, которые объединены общим именем. Объявление структуры начинается с ключевого слова “struct”:

struct идентификатор (список параметров);

Структуры могут быть вложены друг в друга. Это значит, что элементы сами могут быть структурами. Объявление структуры не резервирует никакого пространства в памяти. Оно лишь создает новый тип данных.

Операции доступа к элементам структуры

Для доступа к элементам структуры по имени переменной используется операция “.”. Для доступа к элементам структуры через указатель на переменную служит операция “->”. При записи в программе обе операции помещаются между именем переменного типа структуры и идентификатором элемента структурного типа.

Пример программы с простой структурой

#include <iostream>

using namespace std;

int main ()

{

// объявление типа структуры

Struct address

{

Char city[20];

Char street[10];

Int house;

};

// объявление переменной

Address a;

// ввод значений элементов

Cin >> a.city; cin >> a.street;

Cin >> a.house;

// объявление указателя с инициализацией

adress *p = new adress;

//ввод значений элементов

cin >> p -> city; cin >> p -> street;

cin >> p -> house;

//присваивание структур

adress copy, copy = a; copy = *p;

return 0;

}

В программе определяется тип структуры adress. В 1ой части программы объявляется переменная а , для которой вводятся значения элементов. Чтобы элементы получили свои значения, используется операция (.). Во второй части программы объявляется указатель p на тип структуру. Одновременно с объявлением выделяется память при помощи оператора new, а адрес выделенного блока памяти записывается в переменную p и для доступа к элементам теперь используется операция стрелка (->). Значения элементов, принадлежащих одной структурной переменной, могут быть присвоены другой структуре. Для этого нет необходимости копировать каждый элемент, достаточно воспользоваться оператором присваивания. В примере структура копий сначала получает значения, хранящиеся в структурной переменной а, после чего приравнивается к структуре, адрес которой записан в р. В последнем случае используется операция разыменования. Операции отношения ( ==, !=) над структурами недопустимы. Для сравнения структурных переменных используется перегрузка операторов.