- •Конспект лекций по дисциплине "Программирование"(іі часть)
- •123 "Компьютерная инженерия"
- •1 Функции 6
- •1 Функции
- •1.1 Определение, описание, вызов функции
- •Void prn1(int X)
- •Void prn2()
- •Void main()
- •1.2 Передача параметров в функции по значению и по указателю
- •Void func(int intg,float fltp)
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •1.3 Функции и массивы
- •Int func1(int arr[]) {...}
- •Void main()
- •Void main()
- •Void main()
- •1.4 Функции с умалчиваемыми значениями параметров
- •Void main()
- •Void main()
- •1.5 Функции с переменным числом параметров
- •Void main()
- •Void main()
- •1.6 Передача параметров в функцию main()
- •Int main(int argc,char**argv,char**envp)
- •Int main(int argc,char **argv)
- •1.7 Рекурсивные и подставляемые функции
- •Void main()
- •Void main()
- •1.8 Функции, возвращающие указатель
- •Void main()
- •1.9 Функции и структуры
- •Void f1(stud a)
- •Void f3(stud *p)
- •Void main()
- •1.10 Перегрузка функций
- •Void main()
- •Void main()
- •Int mul(double X,double y)
- •Int sum(int X) {return 2*X;}
- •Void main()
- •1.11 Шаблоны функций
- •Int main()
- •Void func(a);
- •Int main()
- •1.12 Указатели на функции
- •Void main()
- •Int f2(int X){return X*X;};
- •Void main()
- •Void main()
- •2 Работа с файлами
- •2.1 Потоковый ввод-вывод
- •2.2 Открытие и закрытие потока
- •Int fclose(file *имя);
- •Int main()
- •Void perror(const char *str);
- •2.3 Посимвольный ввод-вывод
- •Int fputc(int ch, file *fp);
- •Int fgetc(file *fp);
- •2.4 Построчный ввод-вывод
- •Int fputs(char*string, file *fp);
- •2.5 Форматированный ввод-вывод
- •Int fprintf(file *fp, char *format [,аргумент]…);
- •Int fscanf(file *fp, char *format [,указатель]…);
- •2.6 Форматированные вывод в строку и ввод из строки
- •Int a2; long b2;
- •2.7 Блоковый ввод-вывод
- •Int fwrite(void *ptr, int size, int n, file *fp);
- •Int fread(void *ptr,int size,int n,file *fp);
- •2.8 Произвольный доступ к файлу
- •Int fseek(file *fp, long offset, int from_where);
- •Int main()
- •3 Многофайловая компиляция
- •Void main()
- •Void main()
- •4 Объекты и их атрибуты
- •Void main()
- •5 Ссылки
- •Int &хref; // ошибка!!
- •Int f2_ptr(int *a, int *b) {return *a-*b;}
- •Int f4_ref(const int&a, int &b)
- •Void main()
- •Литература
1.12 Указатели на функции
Имя функции, по определению, есть указатель, значением которого является адрес размещения функции в памяти. Если значение этого адреса присвоить другому указателю, то данный указатель можно использовать для вызова функции.
Указатель на функцию определяется специальным образом:
тип_функции (*имя_указателя)(спецификация_параметров);
где тип_функции – тип возвращаемого функцией значения;
спецификация_параметров – типы формальных параметров;
*имя_указателя – имя указателя на функцию в круглых скобках.
Примеры определения указателей на функцию:
int (*ptrfunc)(int); // указатель на функцию
char (*pf1)(char*);
char* (*pf3)(char*);
Если этот пример записать без скобок, то он будет воспринят компилятором как прототип функции, возвращающей указатель.
int *ptrfunc(int); //прототип
В определении указателя на функцию тип возвращаемого значения и сигнатура функции должны совпадать с соответствующими типами и сигнатурами тех функций, адреса которых предполагается присвоить вводимому указателю.
Пример.
float mul(float x,float y) {return x*y;}
float sum(float x,float y) {return x+y;}
Void main()
{float (*ptrmul)(float,float); // указатель на функцию
float (*ptrsum}(float,float); // указатель на функцию
ptrmul=mul; // указателю присвоили имя функции mul
ptrsum=sum; //указателю присвоили имя функции sum
float f1=3.0,f2=9.0,f3;
f3=(*ptrmul)(f1,f2)+(*ptrsum)(f1,f2);
printf("f3=%.1f", f3); // f3=39.0
float(*ptr)(float,float); //указатель на функцию
ptr=mul; //указателю присвоили имя функции mul
printf("mul=%.1f", (*ptr)(f1,f2)); // mul=27.0
ptr=sum; //указателю присвоили имя функции sum
printf("sum=%.1f",(*ptr)(f1,f2)); }// sum=12.0
Указатели на функцию могут образовывать массив, при этом тип и сигнатура во всех функциях должны быть одинаковые. Синтаксис: тип_функции(*имя_указателя[n])(спецификация_параметров);
где n – размер массива указателей на функции (константное выражение).
Пример. Определен массив из трех указателей на функции, имеющие тип int с параметром типа int
#include <stdio.h>
int f1(int x){return x+x;};
Int f2(int X){return X*X;};
int f3(int x){return ~x;}; //побитовое отрицание
Void main()
{int(*p[3])(int);
p[0]=f1; p[1]=f2; p[2]=f3;
int a=(*p[0])(5);
int b=(*p[1])(a);
int c=(*p[2])(a);
printf("a=%d b=%d c=%u\n",a,b,c);
}
В результате работы программы на экран выведется:
a=10 b=100 c=65525
Для задания типа указателя на функцию можно применять спецификатор typedef. Синтаксис такой:
//Определение тип указателя на функцию
typedef тип_функции(*имя_типа_указателя)(спец_ия_парам);
//Определение указателя на функцию, массива указателей на функцию
имя_типа_указателя имя_указателя_ф-ции; имя_типа_указателя имя_указателя_ф-ции[n];
Например:
typedef int (*ABC)(int); // тип указателя на функцию ABC
АВС р1; // указатель на функцию р1 типа ABC
АВС р2[4];// массив из 4 указателей на функцию р2 типа ABC
Пример. Определили массив указателей на функции
#include <stdio.h>
void typ0(){printf("Привет,");}
void typ1(){printf(" дорогой");}
void typ2(){printf(" друг!");}
typedef void (*TYPE)();
TYPE mpf[]={typ0,typ1,typ2};
//void (*mpf[])()={typ0,typ1,typ2};
void main()
{for(int i=0;i<3;i++) mpf[i]();}
Указатели на функции могут использоваться в качестве параметра функции. В этом случае в функцию можно передать указатели на различные функции.
Пример. Функция суммирует сначала квадраты элементов массива, а затем ‑ их кубы.
#include <stdio.h>
float sqr(float e){return e*e;} //Определение функции
float cube(float y){return y*y*y;} //Определение функции
typedef float(*PF)(float);
float summa(PF f,float a[],int N)//Определение функции
{float sum=0.0;
for(int i=0;i<N;i++) sum+=(*f)(a[i]);
return sum;}
