Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование / WORD / Лекции по ЯП (часть 3).doc
Скачиваний:
138
Добавлен:
15.04.2015
Размер:
1.34 Mб
Скачать

Манипулирование блоками памяти

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

Инициализация памяти с помощью функции memset()

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

void *memset(void *dest, int с, size_t count);

Аргумент dest указывает на блок памяти,

с - это значение, которое следует поместить в байты блока,

count — количество этих байтов, начиная с dest.

Заметьте, что переменная c имеет тип int, а используется в качестве char, т.е. используется только ее младший байт со значениями из диапазона от 0 до 255.

Внимание. Не пытайтесь с помощью функции memset() инициализировать массивы типа int, float или double, если это число не равно 0.

Копирование блоков памяти функцией memcpy()

Функция memcpy() копирует байты данных из одного блока памяти в другой. Такие блоки часто называются буферами. Функция не различает тип копируемых данных, она просто аккуратно переносит информацию байт за байтом. Ее прототип имеет следующий вид:

void *memcpy(void *dest, void *src, size_t count);

Аргументы dest и src указывают соответственно на блоки памяти, куда и откуда копируются данные. Аргумент count задает количество копируемых байт. Функция возвращает значение dest. Если два блока памяти накладываются один на другой, функция может сработать некорректно: часть данных в блоке src окажется затертой еще до их копирования. Для работы с перекрывающимися блоками памяти используйте функцию memmove ().

Перемещение блоков памяти с помощью функции memmove()

Функция memmove() по сравнению с функцией memcpy()обладает большей гибкостью, поскольку корректно справляется с ситуацией взаимного наложения блоков. Прототип функции memmove() имеет следующий вид:

void *memmove(void *dest, void *src, size_t count);

Указатели src и dest указывают на исходный и конечный блоки памяти соответственно. Параметр count задает количество копируемых байт. Функция возвращает dest. Если блоки накладываются один на другой, то функция гарантированно выполняет копирование информации из перекрываемой области прежде, чем затереть ее новыми данными.

Типы, определяемые пользователем

Кроме известных нам типов данных язык Си позволяет создавать еще 3 типов данных:

  • перечислимый тип (enum);

  • структуры (structure);

  • объединения (union).

Перечислимый тип

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

enum имя_типа {список_названий} список_переменных;

В отличие от Паскаля a:(b, c, d, е);

| | | |

0 1 2 3

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

enum имя_типа{b, c, d=5, e} a;

| | | |

0 1 5 6

Каждый следующий символ увеличивается на единицу по сравнению с предыдущим, если нет другого присваивания.

С переменными перечислимого типа можно производить следующие операции:

  • присвоить переменную типа enum другой переменной того же типа;

  • провести сравнение с целью выяснения равенства или неравенства;

  • арифметические операции с константами типа enum (i = e - с).

Нельзя использовать арифметические операции и операции + + и – – для переменных типа enum.

Основная причина использования перечислимого типа – это улучшение читаемости программ.