- •1. Среда программирования. Трансляция, компоновка и отладка программ
- •2. Виды и характеристики языков программирования
- •3. Виды программных ошибок.
- •4. Описание языка Си (используемые символы, константы, идентификаторы, ключевые слова, комментарии). Используемые символы
- •Константы
- •Ключевые слова
- •Использование комментариев в тексте программы
- •5. Идентификаторы и ключевые слова языка Си. Идентификаторы и ключевые слова
- •6. Структура программы на языке Си.
- •7. Категории типов данных (символьные, целые, с плавающей точкой).
- •Целый тип данных
- •Данные плавающего типа
- •8. Символьные и целые типы данных. Данные целого типа (integer)
- •Данные символьного типа (char)
- •9. Вещественные типы данных (с плавающей точкой). Данные вещественного типа (float, double)
- •10. Преобразование типов (явное и неявное).
- •11. Использование модификаторов при декларации типов данных.
- •12. Кодовая таблица ascii. Системы счисления. Классификация и преобразование символов. Классификация и преобразование символов
- •13. Константы. Целые константы. Константы с плавающей точкой. Символьные константы. Строки. Null.
- •1 Целые Константы
- •2 Константы с Плавающей Точкой
- •3 Символьные Константы
- •4 Строки
- •14. Условный оператор if.
- •15. Тернарная условная операция ?:.
- •16. Оператор выбора альтернатив switch.
- •17. Составление циклических алгоритмов. Операторы цикла с предусловием и с постусловием. Оператор while
- •Оператор do while
- •18. Оператор цикла с предусловием и коррекцией for. Оператор for
- •19. Операторы перехода (break, continue, return, goto). Оператор break
- •Оператор continue
- •Оператор return
- •Оператор goto
- •20. Унарные операции.
- •21. Аддитивные и мультипликативные операции.
- •22. Операции сдвига.
- •23. Поразрядные операции.
- •24. Операции отношения.
- •25. Логические операции.
- •26. Операция присваивания.
- •27. Сокращенная запись операции присваивания.
- •28. Стандартная библиотека языка Си. Математические функции.
- •29. Стандартная библиотека языка Си. Функции работы со строками.
- •Int strcmp(const char *s1, const char *s2);
- •Integer atoi(const char *nptr);
- •30. Стандартная библиотека языка Си. Ввод данных.
- •31. Стандартная библиотека языка Си. Вывод данных.
- •32. Управляющая строка функций ввода/вывода.
- •33. Препроцессор. Директивы #include, #define.
- •Директивы препроцессора и указания компилятору
- •34. Графический режим. Функции черчения и заполнения.
- •35. Графический режим. Функции вывода текста, функции управления цветом. (outtext, outtextxy, setbkcolor, setcolor, settextjustify, settextstyle, textheight, textwidth)
- •Цвет фона и вычерчивания
- •36. Одномерные массивы. Инициализация одномерных массивов. Ввод и инициализация массива символов.
- •37. Многомерные массивы. Инициализация многомерных массивов.
- •38. Структуры
- •Пример 5
- •39. Объединения.
- •Пример 2
- •40. Перечисления.
- •41. Работа с файлами. Типы открытия файлов (текстовый и бинарный). Дескриптор файла ("указатель на файл"). Режимы работы с файлами.
- •42. Работа с файлами. Открытие файла в различных режимах и закрытие файла.
- •Int feof(file *stream);
- •Int fclose(file *stream);
- •Коды, устанавливающие режимы доступа к открываемым файлам
- •Void rewind(file *stream);
- •Int fsetpos(file *stream, const fpos_t *pos);
- •45. Указатели. Указатели и адреса объектов. Указатели и массивы. Указатели.
- •Указатели и адреса объектов
- •Указатели и массивы
- •46. Операции с указателями: присваивание адреса, определение значения по адресу, присваивание указателей
- •1. Присваивание адреса.
- •3. Сравнение указателей.
- •48. Работа с динамической памятью. Динамические массивы.
- •49. Функции. Определение функции, объявление функции и вызов функции. Возвращаемое значение функции.
- •3. Вызов функции
- •50. Функции. Типы передачи параметров функции (по значению, по адресу).
- •Передача переменных
- •Передача векторных параметров
- •51. Функции. Переменные в качестве параметров функций.
- •52. Функции. Массивы в качестве параметров функций.
- •53. Указатели на функции.
- •1. Среда программирования. Трансляция, компоновка и отладка программ
- •2. Виды и характеристики языков программирования
51. Функции. Переменные в качестве параметров функций.
52. Функции. Массивы в качестве параметров функций.
53. Указатели на функции.
С функцией можно делать только две вещи: вызывать ее и брать ее адрес. Указатель, полученный взятием адреса функции, можно затем использовать для вызова этой функции. Например:
void error(char* p) { /* ... */ }
void (*efct)(char*); // указатель на функцию
void f()
{
efct = &error; // efct указывает на error
(*efct)("error"); // вызов error через efct
} Чтобы вызвать функцию через указатель, например, efct, надо сначала этот указатель разыменовать, *efct. Поскольку операция вызова функции () имеет более высокий приоритет, чем операция разыменования *, то нельзя писать просто *efct("error"). Это означает *efct("error"), а это ошибка в типе. То же относится и к синтаксису описаний. Заметьте, что у указателей на функции типы параметров описываются точно также, как и в самих функциях. В присваиваниях указателя должно соблюдаться точное соответствие полного типа функции. Например:
void (*pf)(char*); // указатель на void(char*)
void f1(char*); // void(char*)
int f2(char*); // int(char*)
void f3(int*); // void(int*)
void f()
{
pf = &f1; // ok
pf = &f2; // ошибка: не подходит возвращаемый тип
pf = &f3; // ошибка: не подходит тип параметра
(*pf)("asdf"); // ok
(*pf)(1); // ошибка: не подходит тип параметра
int i = (*pf)("qwer"); // ошибка: void присваивается int'у
}
Правила передачи параметров для непосредственных вызовов функции и для вызовов функции через указатель одни и те же. Часто, чтобы избежать использования какого-либо неочевидного синтаксиса, бывает удобно определить имя типа указатель-на-функцию. Например:
typedef int (*SIG_TYP)(); // из
typedef void (*SIG_ARG_TYP);
SIG_TYP signal(int,SIG_ARG_TYP); Бывает часто полезен вектор указателей на функцию. Например, система меню для моего редактора с мышью*4 реализована с помощью векторов указателей на функции для представления действий. Подробно эту систему здесь описать не получится, но вот общая идея:
typedef void (*PF)();
PF edit_ops[] = { // операции редактирования
cut, paste, snarf, search
};
PF file_ops[] = { // управление файлом
open, reshape, close, write
}; Затем определяем и инициализируем указатели, определяющие действия, выбранные в меню, которое связано с кнопками (button) мыши:
PF* button2 = edit_ops;
PF* button3 = file_ops; В полной реализации для определения каждого пункта меню требуется больше информации. Например, где-то должна храниться строка, задающая текст, который высвечивается. При использовании системы значение кнопок мыши часто меняется в зависимости от ситуации. Эти изменения осуществляются (частично) посредством смены значений указателей кнопок. Когда пользователь выбирает пункт меню, например пункт 3 для кнопки 2, выполняется связанное с ним действие:
(button2[3])(); Один из способов оценить огромную мощь указателей на функции - это попробовать написать такую систему не используя их. Меню можно менять в ходе использования программы, внося новые функции в таблицу действий. Во время выполнения можно также легко сконструировать новое меню. Указатели на функции можно использовать для задания полиморфных подпрограмм, то есть подпрограмм, которые могут применяться к объектам многих различных типов:
typedef int (*CFT)(char*,char*);
int sort(char* base, unsigned n, int sz, CFT cmp)
/*
Сортирует "n" элементов вектора "base"
в возрастающем порядке
с помощью функции сравнения, указываемой "cmp".
Размер элементов "sz".
Очень неэффективный алгоритм: пузырьковая сортировка
*/
{
for (int i=0; iname, Puser(q)->name);
}
int cmp2(char*p, char* q) // Сравнивает числа dept
{
return Puser(p)->dept-Puser(q)->dept;
}
Можно взять адрес inline-функции, как, впрочем, и адрес перегруженной функции
