Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Voprosy_k_ekzamenu_po_informatike

.pdf
Скачиваний:
41
Добавлен:
09.06.2015
Размер:
2.24 Mб
Скачать

20. УКАЗАТЕЛИ, РАБОТА С УКАЗАТЕЛЯМИ В С/С++.

Указатели – это переменные, значением которых является адрес. В С++ различают три вида указателей: указатели на объект, на функцию и на void.

Указатель на объект содержит адрес области памяти, в которой хранятся данные определенного типа. Пример объявления:

char *a;

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

const int *b;

// указатель на константу типа int

double **c;

// указатель на указатель на вещественное значение

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

Указатель типа void применяется в тех случаях, когда конкретный тип объекта, адрес которого нужно хранить, не определен. Указателю на void можно присвоить значение указателя любого типа, а также сравнить его с любым указателем, но перед выполнением каких-либо действий с областью памяти, на которую он ссылается, требуется преобразовать его к конкретному типу явным образом.

Выделение участка динамической памяти и присваивание ее адреса указателю происходит следующим образом:

int *a = new int;

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

delete a;

Операция разадресации предназначена для доступа к значению, адрес которой хранится в указателе. Эту операцию можно использовать как для получения значения, так и для его изменения. Пример:

int *a; *a = 100;

41

21. СТРОКОВЫЙ ТИП В С/С++, СТАНДАРТНЫЕ ФУНКЦИИ ДЛЯ РАБОТЫ СО СТРОКАМИ.

Строка – это последовательность символов определенной длины. Существуют два типа данных, которые используются для представления строк.

Первый способ основывается на том, что строка представляет собой массив базового типа char, конец которого отмечается нулевым символом '\0'.

Второй способ основывается на том, что строка представляет собой объект класса string.

Объявление и инициализация.

char a[10] = “строка”; char b[] = “строка”; string s = “строка”;

Ввод-вывод осуществляется с помощью объекта cout и операции <<. Ввод строк можно осуществлять также с помощью cin >>, но при этом символы строки будут считываться до тех пор, пока не встретится символ пробела, табуляции или перевода строки, после чего ввод прекратится. Для того, чтобы ввести строку целиком можно использовать функцию getline.

Функции для работы с массивом char. Для использования следующих функций нужно подключить заголовочный файл <cstring>.

42

string. Класс string позволяет работать со значениями типа string почти так же, как со значениями простого типа данных. Для него работают операторы присваивания и конкатенации +. Класс string поддерживает доступ к символам, как к элементам массива. Для использования функций класса string нужно подключить заголовочный файл <string>.

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

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

Изменение строки.

43

44

22. РАБОТА СО СТРУКТУРАМИ В С/С++.

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

struct name { int a; char b; double c;

};

После определения структуры ее тип может использоваться для объявления переменных, массивов, указателей. Типом является имя структуры name:

name x; name y[10]; name *z;

Поля структуры. Доступ к полям структуры выполняется с помощью операций выбора: при обращении к полю через имя переменной, используется операция ‘.’, при обращении к полю через указатель, используется операция ->. Пример:

x.a = 3; y[0].b = ‘h’; z->c = 24.23;

Члены-функции и закрытые члены. С помощью ключевого слово private можно сделать некоторые члены структуры закрытыми. Доступ к ним можно получить только из данной структуры. Пример:

struct point { int x, y;

double length_find(); private:

double length_print();

};

//открытая член-функция

//закрытая член-функция

Также структуры могут содержать члены-функции, такие как double length_print() и double length_find().

45

23. ОБЪЕДИНЕНИЯ В С/С++, ОТЛИЧИЕ ОТ СТРУКТУР.

Объединение (union) — это пользовательский тип данных или класса, который в любой конкретный момент содержит только один объект из списка своих членов (при этом такой объект может представлять собой тип массива или класса). Объединение в C++ представляет собой ограниченную форму типа класса. В нем могут содержатся спецификаторы доступа (public, protected, private), данные-члены и функции-члены, включая конструкторы и деструкторы. В него не могут входить виртуальные функции и статические элементы данных. Он не может ни использоваться в качестве базового класса, ни иметь базовые классы. По умолчанию элементы объединения имеют доступ public. Пример:

union Some { int i; double a;

};

Отличия от структур:

В структуре элементы располагаются в памяти последовательно друг за другом, а объединение позволяет хранить различные типы данных в одном и том пространстве памяти (но не одновременно).

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

46

// считывание одного символа
Неформатированный ввод/вывод. В двоичных файлах данные сохраняются во внутреннем (машинном) представлении, поэтому они обычно занимают меньше места, и работа с ним происходит быстрее, так как преобразование типов не производится. Однако просмотр и редактирование двоичных файлов возможно только программным путем. Примеры ввода/вывода:
getline(in, x);
// считывание строки до знака переноса
24. ФАЙЛЫ ПРЯМОГО И ПОСЛЕДОВАТЕЛЬНОГО ДОСТУПА К ДАННЫМ, ФОРМАТИРОВАННЫЙ И НЕФОРМАТИРОВАННЫЙ ВВОД/ВЫВОД.
По способу доступа файлы можно разделить на последовательные, чтение и запись в которых производится с начала файла байт за байтом, и файлы с произвольном (прямом) доступом, допускающие чтение и запись в указанную позицию. По внутреннему представлению данных файлы бывают текстовые (форматированные) и двоичные (неформатированные).
Форматированный ввод/вывод. В текстовых файлах все данные сохраняются в виде символов, даже числа. При считывании данных из потока (или записи данных в поток) происходят необходимые преобразования типов. Например, при чтении данных строки могут преобразовываться к арифметическим типам, а при записи, наоборот, арифметические типы преобразуются в строковый тип, на что потребуются дополнительные временные затраты. Однако, текстовые файлы просты для чтения пользователем, а для их создания и редактирования можно пользоваться текстовым редактором, например, «Блокнот». Примеры ввода/вывода:
in >> x; // считывание строки до знака пробела, табуляции или переноса
out << x;

in.get(ch);

out.put(ch);

in.read((char*) &i, sizeof(double)); // считывание i байт значений типа

double

out.write((char*) &i, sizeof(int));

Произвольный доступ. Выше описана работа с файлами в режиме последовательного доступа. Для обеспечения произвольного доступа используется внутренний указатель файла, который определяет текущий индекс обрабатываемого байта файла, и две пары функций. seekg(), seekp() – используется потоками ввода и устанавливает указатель в нужную позицию. tellg(), tellp() – используется потоками вывода и сообщает текущую позицию указателя. Примеры произвольного доступа:

47

in.seekg(3, ios::end); // устанавливает указатель на позицию 3 относительно конца файла

streampos n = in.tellg(); // переменной n присваивается текущая позиция чтения

streampos n = in.tellg(); // в переменную n запишется текущая позиция чтения

streampos n = out.tellp(); // в переменную n запишется текущая позиция записи

48

25. РАБОТА С ФАЙЛАМИ В С/С++, ПРИМЕРЫ.

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

Классы. В C++ реализованы три класса для работы с файлами: ifstream — класс входных файловых потоков, ofstream – класс выходных файловых потоков; fstream - класс двунаправленных файловых потоков. Эти классы объявлены в заголовочном файле <fstream>.

Работа с текстовыми файлами. Примеры создания потока и присваивание его файлу:

ifstream in; in.open(“infile.txt”);

или

ifstream in(“infile.txt”);

Примеры считывания с файла:

in >> x; // считывание строки до знака пробела, табуляции или переноса

while (in >> x) {

 

sum += in;

}

// считывание нескольких строк до конца файла

 

Для завершения работы с потоком его необходимо закрыть с помощью

функции close().

Работа с двоичными файлами. Для открытия двоичных файлов необходимо открыть входной поток, используя спецификатор режима ios::binary. Пример:

ifstream in(“infile.dat”, ios::binary);

На нижнем уровне двоичного ввода/вывода находятся функции get()/put().

Функция get() считывает один символ из соответствующего потока и помещает его значение в переменную типа char, при этом возвращает ссылку на поток, связанный с предварительно открытым файлом. При считывании символа конца файла данная функция возвратит вызывающему потоку значение false. Пример:

in.get(ch);

Функция put() записывает символ в поток и возвращает ссылку на этот поток. Пример:

in.put(ch);

49

Функции get и put используются для считывания данных побайтно, что позволяет нам обрабатывать текстовые данные, представленные в ASCII кодировке. Однако в двоичных файлах могут храниться последовательности целых и вещественных типов, где каждое значение занимает от 2 до 10 байт. В этом случае использование этих функций невозможно. В таком случае нужно использовать функции read() и write(), предназначенные для считывания и записи блоков двоичных данных.

Пример функции read():

double j;

in.read((char*) &j, sizeof(double));

Функция считывает из вызывающего потока sizeof(double) байт и передает их в буфер j. Если конец файла достигнут до того, как было считано нужное количество байт, то выполнение функции read() прекращается, а в буфере оказывается столько байт, сколько их было в файле.

Пример функции write():

int i = 20;

out.write((char*) &i, sizeof(int));

Функция записывает в соответствующий поток из буфера i столько байт, сколько задано параметром sizeof(int).

50