- •Введение
- •Блок-схема алгоритма
- •Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Основные понятия языка С(С++)
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Структура программы на языке С(С++)
- •Операции и выражения
- •sizeof
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора
- •Директива #include
- •Директива #define
- •Операторы языка С(С++)
- •Понятие пустого и составного операторов
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Примеры программ
- •Массивы
- •Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели
- •Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Передача массива в функцию
- •inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Вершина стека
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Стек
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Файлы
- •Примеры программ
- •Литература
int i=0, znak; |
|
while(*(ss+i)==' ') i++; |
|
if (!*(ss+i)) return 0.; |
// в строке одни пробелы |
znak=(*(ss+i)=='-')? -1: 1; |
|
if (*(ss+i)=='+' || *(ss+i)=='-') |
i++; // пропуск позиции знака |
for(n=0.0; (*(ss+i)>'0' && *(ss+i)<='9') || *(ss+i)=='.'; i++) |
|
{ if (ii) ii*=10; |
// число цифр после десятичной точки |
if (*(ss+i)!='.') |
n=10.0*n+(*(ss+i)-'0'); // выбор цифр числа из строки |
else ii=1; |
// выбрана десятичная точка |
} |
|
if(!ii) ii=1; |
// если введено целое число |
return znak*n/ii; |
// возврат signed double |
}
// функция перевода цифровой символьной строки в signed int int atoi(char ss[]) // в функцию передается указатель
{ int n,i=0,znak; while(*(ss+i)==' ') i++; if (!*(ss+i)) return 0;
znak=(*(ss+i)=='-')? -1: 1;
if (*(ss+i)=='+' || *(ss+i)=='-') i++; for(n=0; *(ss+i)>'0' && *(ss+i)<='9'; i++) n=10*n+(*(ss+i)-'0');
return znak*n;
}
// функция перевода signed int в символьную строку
void itoa(int n,char *ss) |
|
{ int i=0, znak; |
|
if ((znak=n)<0) n=-n; |
// |
do |
// |
{ ss[i++]=n%10+'0'; |
// |
} while((n/=10)>0); |
// |
if (znak<0) ss[i++]='-'; |
|
ss[i]='\0'; |
|
for(n=0;n<i/2;n++) |
|
{ ss[n]+=ss[i-1-n]; |
|
ss[i-1-n]=ss[n]-ss[i-1-n]; ss[n]-=ss[i-1-n];
}
}
Указатели на функции
В языке С (С++) функция не может быть значением переменной, в тоже
время, аналогично переменным функция физически расположена в памяти и соответственно имеет адрес. Таким образом, ее адрес, присвоенный указателю, является точкой входа в функцию. Указатель на функцию может быть использован для вызова функции вместо ее имени, а также позволяет передавать функцию как обычный параметр в другую функцию. Следовательно с указателем на функцию можно обращаться, как с переменной (передавать его другим функциям, помещать в массивы и т.д).
Указатель на функцию – это такой тип переменной, которой можно присваивать адрес точки входа в функцию, то есть адрес первой исполняемой команды. Эта переменная в дальнейшем может использоваться для вызова функции вместо ее имени. Определение указателя на функцию имеет следующий общий вид:
тип_результата (*имя_указателя_на функцию)(список_типов_параметров);
В объявлении
int (*fun)(int, int *);
переменная fun является указателем на функцию с двумя параметрами: типа int и указателем на int. Сама функция должна возвращать значение типа int. Круглые скобки, содержащие имя указателя fun и признак указателя *, обязательны, иначе запись
int *fun (int, int *);
будет интерпретироваться как объявление функции fun возвращающей указатель на int. Это следует из того, что приоритет префиксного оператора * ниже, чем приоритет ().
Вызов функции возможен только после инициализации значения указателя fun и имеет вид:
(*fun)(i,&j);
В этом выражении для получения адреса функции, на которую ссылается указатель fun используется операция разадресации * . Вызов функции через указатель возможен так же в обычным способом:
fun( i,&j);
Ниже приведен пример использования указателя на функцию инициализированного адресом системной функции strcmp.
#include <stdio.h>
#include <string.h>
#define n 80
void check(char *, char , int ( cmp)(const char *,const char *))); void main(void)
{ char s1[n],s2[n];
int (*p)(const char *,const char *); p=strcmp; // p – адрес strcmp() gets(s1); gets(s2); check(s1,s2,p);
}
void check(char *a, char b, int ( cmp)(const char *,const char *)))
{printf("\n строки ");
if (!(*cmp)(a,b)) printf("равны");
else printf("не равны");
}
При вызове check ей передается два указателя на символьные строки и один на функцию. Аналогично можно обращаться к check, используя и указатели на другие функции, если возвращаемый тип и передаваемые параметры, совпадают с рассмотренными выше. Выражение if(!(*cmp)(s1,s2)) можно заменить на if(!cmp(s1,s2)). Можно вызвать функцию check также следующим образом: check(s1,s2,strcmp). При этом не требуется использовать дополнительно указатель p.
Ниже приводятся примеры некоторых более сложных деклараций:
int (*ukz)[10]; - объявление указателя ukz на массив из 10 элементов int; char (*(*fun))[]() - функция, возвращающая указатель на массив из
функций, возвращающих значение типа char;
char (*(*m_ukz[5])())[10] - m_ukz[5] массив из указателей на функции,
возвращающие указатели на массив из [10] элементов char.
Примеры программ
Пример . Использование указателя на функцию в качестве параметра функции вычисляющей производную от функции cos(x).
double proiz(double x, double dx, double (*f)(double x) );
double fun(double z); |
|
|
int main() |
|
|
{ double x; |
// |
точка вычисления производной |
double dx; |
// |
приращение |
double z; |
// |
значение производной |
scanf("%f,%f",&x,&dx); // ввод значений x и dx |
||
z=proiz(x,dx,fun); |
|
// вызов функции |
printf("%f",z); |
// печать значения производной |
|
return 0; |
|
|
} |
|
|
double proiz(double x,double dx, double (*f)(double z) ) { // функция вычисляющая производную
double xk,xk1,pr; xk=fun(x); xk1=fun(x+dx); pr=(xk1/xk-1e0)*xk/dx; return pr;
}
double fun( double z)
{ // функция от которой вычисляется производная return (cos(z));