
- •Определение алгоритма
- •Классификация языков
- •Модификаторы доступа
- •Объявление переменных
- •Локальные переменные
- •Формальные параметры
- •Глобальные переменные
- •Спецификаторы хранения
- •Оператор присваивания
- •Инициализация переменных
- •Константы
- •Операторы
- •Оператор ?
- •Операторы указания & и *
- •Оператор sizeof
- •Оператор «запятая»
- •Выражения
- •Преобразования типов в выражениях
- •Принудительные преобразования типов
- •Оператор break
- •Оператор continue
- •Метки и goto
- •Одномерный массив
- •Создание указателя на массив
- •Двумерные массивы
- •Массивы строк
- •Многомерные массивы
- •Индексация с помощью указателей
- •Размещение массивов
- •Функции
- •Оператор return
- •Правила видимости для функций
- •Аргументы функции. Передача по значению и передача по указателю
- •Передача массивов в функции
- •Аргументы функции main()
- •Возврат указателей
- •Указатели на функции
- •Структуры
- •Доступ к членам структуры
- •Присваивание структур
- •Массивы структур
- •Указатели на структуры
- •Битовые поля
- •Объединения
- •Перечисления
- •Использование typedef
- •Ввод, вывод, потоки и файлы
- •Форматированный консольный ввод-вывод
- •Модификаторы формата
- •Файловая система ansi c
- •Запись и чтение символа
- •Использование feof()
- •Работа со строками: fgets() и fputs()
- •Указатели
- •Односвязные списки
- •Обход односвязного списка
- •63.Бинарное дерево поиска. Вставка и поиск элемента по ключу в бинарном дереве поиска. Поиск элемента (find)
- •Добавление элемента (insert)
- •64.Бинарное дерево поиска. Удаление элемента из бинарного дерева поиска. Удаление узла (remove)
- •65.Обход бинарного дерева
- •66.Балансировка бинарного дерева поиска
-
Возврат указателей
Функции могут возвращать указатели также как и любые другие типы. Важно помнить, что указатели – это не беззнаковые целые. Это адрес памяти некоторого типа данных, у них другая арифметика.
Пример – функция, возвращающая указатель на символ в месте, где найдено первое вхождение символа в строке:
char *match(char c, char *s)
{ register int count;
count = 0;
while(c!=s[count] && s[count]) count++;
if(s[count]) return (&s[count]);
else return NULL;
}
Функция match() пытается вернуть указатель на позицию в строке, где первый раз найден символ. Если не найдено соответствие, возвращается указатель, содержащий NULL.
-
Рекурсия
В С функции могут вызывать сами себя. Простой пример.
int factr(int n)
{ int answer;
if(n == 1) return 1;
answer = factr(n-1)*n;
return (answer);
}
-
Указатели на функции
Хотя функция – это не переменная, она имеет физическое положение в памяти, которое может быть присвоено указателю. Адрес, присвоенный указателю, является входной точкой в функцию. Указатель может использоваться вместо имени функции. Он также позволяет передавать функции как обычные аргументы в другие функции.
Адрес функции получается при использовании имени функции без скобок и аргументов. Пример:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415
double del2(double a, double b, double eps, double (*f)(double));
int main(void)
{
double (*p)(double);
p = sin;
double a = -PI/2, b = PI/2, eps = 0.0001;
printf("Root = %lf\n", del2(a,b,eps,p));
printf("Root = %lf\n", del2(a,b,eps,sin));
return 0;
}
double del2(double a, double b, double eps, double (*f)(double))
{
if(b<a) {
puts("Left bigger than right");
exit(0);
}
if(eps <= 0) {
puts("Eps <= 0");
exit(0);
}
if(f(a) == 0) return a;
if(f(b) == 0) return b;
while(b-a >= eps) {
double x=(a+b)/2;
if(f(a)*f(x) < 0.) a=x;
else if(f(x) == 0.) return x;
else b=x;
}
return (a+b)/2;
}
Когда вызывается del2(), ей передаются числа с плавающей точкой двойной точности и один указатель на функцию. Скобки вокруг *f необходимы для правильной интерпретации компилятором данного выражения.
При объявлении указателя на функцию можно использовать прототип, оставив имена параметров пустыми.
Рассмотрим работу функции sin() в функции del2(). Оператор
if(f(a) == 0) return a;
осуществляет вызов функции, в данном случае sin(), с помощью f, который указывает на данную функцию. Вызов происходит с аргументом a.
Бывают моменты, когда выгодно передавать функции в процедуры или хранить массивы функций. Пример:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
void enter(void), del(void); void review(void), quit(void);
int menu(void);
void (*options[])(void) = {
enter,
del,
review,
quit
};
int main(void)
{
int i;
i = menu();
(*options[i])();
getchar();
return 0;
}
int menu(void)
{
char ch;
do {
printf("1. Enter\n");
printf("2. Delete\n");
printf("3. Review\n");
printf("4. Quit\n");
printf("Select a number:");
ch = getche();
printf("\n");
}while(!strchr("1234", ch));
return ch-49;
}
void enter(void)
{ printf("In enter.");}
void del(void)
{ printf("In del.");}
void review(void)
{ printf("In review.");}
void quit(void)
{ printf("In quit.");
exit(0);
}