
- •Функции.
- •Вызов функции с переменным числом параметров
- •Функция main и её параметры.
- •Директивы препроцессора (прекомпилера).
- •Объявление указателей.
- •Модификатор const.
- •Операции.
- •Указатели на различные типы.
- •Указатель на void.
- •Применение указателей для передачи данных между функциями.
- •Массивы.
- •Индексация массивов.
- •Хранение массива в памяти. Адреса элементов. Хранение массива в памяти.
- •Массивы и константные указатели.
- •Статическое и динамическое выделение памяти.
- •Функции calloc, malloc, free
- •Функция realloc
- •Передача массивов в качестве аргументов функции.
- •Указатели на функции.
- •Библиотеки функций.
- •Функции форматированного ввода-вывода.
- •Функция printf().
- •%[Флаги] [Ширина] [.Точность] [{h | l | I | i32 | i64}]тип
- •Для чего нужен форматированный вывод.
- •Функция scanf().
- •Функции sprintf() и sscanf().
- •Функции fprintf() и fscanf().
- •Функции неформатированного ввода-вывода.
- •Работа со строковыми данными (стрингами). Представление строковых данных в языке c.
- •Функции работы со строками.
- •Потоковый ввод-вывод
- •Функции форматированного ввода-вывода.
- •Функция printf().
- •%[Флаги] [Ширина] [.Точность] [{h | l | I | i32 | i64}]тип
- •Для чего нужен форматированный вывод.
- •Функция scanf().
- •Функции sprintf() и sscanf().
- •Функции fprintf() и fscanf().
- •Функции неформатированного ввода-вывода.
- •Функции работы с файлами.
- •Потоковый ввод-вывод
- •Работа с потоками
- •Курсор.
- •Ввод-вывод отдельных символов и строк.
- •Форматированный ввод-вывод информации в файл.
- •Блочный потоковый ввод-вывод
- •Смена текущей позиции в файле. Проверка конца файла.
- •Функции доступа к файлам нижнего уровня.
- •Методы сортировки данных.
- •Введение
- •Сравнение методов сортировки
- •Программная реализация алгоритмов сортировки
- •Метод пузырька.
- •Метод обмена.
- •Метод вставки.
- •Метод Шелла.
- •Метод кучи (бинарной кучи).
- •Очередь
- •Линейный список
- •Физическое (машинное) представление линейных списков
- •Программные реализации структур данных. Стек. Реализация в виде массива.
- •Стек. Связанное представление.
- •Очереди. Реализация в виде массива.
- •Дерево. Связанное представление.
- •Рекурсивный вызов функций.
- •Структуры. Объединения. Перечисления.
- •Перечисление (enum).
- •Производные типы данных.
- •Структура (struct).
- •Побитовое описание полей структуры.
- •Объявление переменных, реализующих структуру.
- •Доступ к элементам структуры.
- •Объединение (union).
- •Вложенное описание структур и объединений.
- •Описание структур и объединений в виде пользовательского типа.
- •Передача структур и объединений в виде параметров функции.
- •Инициализация структур и объединений.
- •Выгода от использования структур
Функции fprintf() и fscanf().
Функции fprintf() и fscanf() полностью аналогичны функциям printf() и scanf(), но используются для форматированного ввода-вывода при работе с файлами. Дополнительный параметр stream идентифицирует сессию работы с файлом (об этом ниже):
int fprintf (FILE* stream, const char* FormatString, [arg1, arg2,]…);
int fscanf(FILE* stream, const char* FormatString, [void* arg1, void* arg2,]…);
Функции неформатированного ввода-вывода.
char *gets( char *buffer );
Ввод строки с клавиатуры. Вводимая строка должна заканчиаться символом перевода строки (нажатием клавиши Enter), который функция gets() заменяет на терминирующий ноль.
int getch( void );
Ввод 1 символа с клавиатуры. Функция ожидает нажатие любой клавиши и возвращает ASCII-код введённого символа. Если была нажата спецклавиша (функциональная клавиша, стрелка и т.п.), то getch вернёт 0, это означает, что нужно ещё раз вызвать эту функцию для получения кода, описывающего нажатую клавишу.
int getchar( void );
Эквивалент getch()
int puts( const char *string );
Вывод строки на экран.
int putch( int c );
Вывод символа на экран.
int putchar( int c );
Эквивалент putch().
char *fgets( char *string, int n, FILE *stream );
Аналогично gets(), но работает с файлами.
int getc( FILE *stream );
Аналогично getch(), но работает с файлами.
int fgetc( FILE *stream );
Эквивалент getc();
int fputs( const char *string, FILE *stream );
Аналогично puts(), но работает с файлами.
int putc( int c, FILE *stream );
Аналогично putch(), но работает с файлами.
int fputc( int c, FILE *stream );
Эквивалент putc();
Все вышеперечисленные функции объявлены в stdio.h, за исключением getch() и putch(), описанных в conio.h.
Представление строковых данных в C. Функции работы со строками.
Работа со строковыми данными (стрингами). Представление строковых данных в языке c.
В отличие от других языков (Pascal, Basic), в C специального типа данных для работы со строками нет. Все строковые данные представляются в виде массива символов, оканчивающегося символом с кодом 0 (терминирующим нулём). Например, строка “C Language” хранится в памяти в виде:
'С' |
' ' |
'L' |
'a' |
'n' |
'g' |
'u' |
'a' |
'g' |
'e' |
0 |
При этом ответственность за выделение памяти и её освобождение (в случае динамического выделения) для работы со строками полностью ложится на пользователя.
Исключение составляет случай выделения памяти под строковый литерал (константу) – в этом случае память под него выделяется статически, автоматически во время компиляции. Сам же литерал трактуется языком как константный массив элементов типа char. С ним можно оперировать как с обычным константным массивом.
Например:
void main()
{
char* p;
char c;
p="ABCD"; // Теперь указатель p указывает
// на начало массива символов
с="EFGH"[1]; // Такое тоже возможно –
// это же константный массив.
}
В результате этой программы указатель p станет указывать на область из 5 байт, где хранится строковый литерал, а в переменную c запишется 1й символ (индексация идёт с нуля) , т.е. 'F'.
Тем не менее, работать напрямую с областью памяти, выделенной по строковые литералы, считается очень плохим стилем, т.к. компилятор автоматически освобождает выделенную под литерал память и возможна ситуация, в которой программа будет обращаться к уже освобождённой памяти.
Поэтому все рабочие строковые данные необходимо хранить в специально выделенной для этого памяти, например в статических массивах. При этом размер массива обычно берут с запасом, чтобы в него могла убраться самая длинная строка. Если же заранее размер строк неизвестен, то память можно выделить динамически.
Пример:
main()
{
char ac[255]; // Массив для промежуточных строковых данных
char ac2[]="TempString"; // Проинициализированный массив
// символов.
…
ac[3]='A';
ac[2]='B';
ac[1]=ac2[1];
…
}