
- •Федеральное агентство по образованию
- •Краткая история языка с
- •Особенности и основные понятия языка Си
- •Структура программы
- •Типы данных
- •Классификация типов данных
- •Вещественные
- •Логический
- •Диапазоны представления данных
- •Объявление переменных
- •Константы в языке Си
- •Операции языка Си. Приоритет операций
- •Операция присваивания
- •Арифметические операции
- •Операции отношения
- •Логические операции
- •Поразрядные операции
- •Операцияsizeof
- •Операция выбора по условию
- •Операция запятая
- •Приведение типов Неявное преобразование типов
- •Явное преобразование типов
- •Основные средства ввода-вывода на Си Понятие потока
- •Стандартные потоки
- •Функции потокового ввода-вывода
- •Функции ввода
- •Ввод символов
- •Ввод строк
- •Форматированный ввод
- •Операторы языка Си
- •Оператор if
- •Оператор switch
- •Оператор while
- •Оператор do while
- •Оператор for
- •Оператор break
- •Оператор continue
- •Функции вывода на экран
- •Вывод символов
- •Функция вывода строк puts()
- •Форматированный вывод
- •Указатели в языке Си
- •Адресная арифметика
- •Массивы
- •Функции в языке с
- •Прототипы функций
- •Указатели типа void
- •Функции, возвращающие указатели
- •Встраиваемые функции
- •Рекурсивные функции
- •Функции с переменным числом аргументов
- •Аргументы функции main()
- •Область действия и область видимости
- •Локальные переменные
- •Локальные переменные в функции Main()
- •Глобальные переменные
- •Классы памяти
- •Указатели на указатели
- •Указатели и многомерные массивы
- •Массивы указателей
- •Указатели на функции
- •Операции над строками символов Определение длины строки
- •Копирование строк
- •Поиск в строках
- •Преобразования символов в строках
- •Другие функции для работы со строками
- •Преобразования строк в числа
- •Преобразования чисел в строки
- •Функции анализа символов
- •Распределение памяти
- •Манипулирование блоками памяти
- •Типы, определяемые пользователем
- •Перечислимый тип
- •Структуры
- •Сложные структуры
- •Битовые поля в структурах
- •Объединения
- •Работа с файлами Связь между потоками и файлами
- •Типы дисковых файлов
- •Открытие файла
- •Запись и чтение данных
- •Форматированный ввод-вывод Форматированный вывод
- •Int fprintf (file *fp, char *fmt, ...);
- •Форматированный ввод
- •Символьный ввод
- •Символьный вывод
- •Блочный ввод-вывод
- •Закрытие файла
- •Директивы препроцессора
- •Директива #include
- •Директива #define
- •Директивы условной компиляции
- •Директива #undef
- •Предопределенные макросы
- •69 Лекции по курсу «Языки программирования» Часть III
Манипулирование блоками памяти
До сих пор мы занимались исключительно вопросами выделения и освобождения блоков памяти. Однако в библиотеке Си имеются и функции для других манипуляций с блоками, например, помещения во все байты блока определенных значений, копирования и перемещения информации из одного места в другое.
Инициализация памяти с помощью функции 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.
Основная причина использования перечислимого типа – это улучшение читаемости программ.