Передача имен функций в качестве параметров



При решение некоторых задач появляется необходимость передачи в функцию в качестве параметра имени другой функции. Например, требуется вычислить значение следующего выражения:

 

Для получения результата надо трижды вычислять сумму, для этого целесообразно использовать функцию. Однако следует заметить, что функция должна вычислять не просто сумму элементов массива, а сумму значений некоторой функции от элементов массива. Поэтому наряду с массивом в функцию надо передавать имя функции, вычисляющей очередное слагаемое.

Функция может быть вызвана с помощью указателя на нее. Для этого надо объявить указатель соответствующего типа и присвоить ему адрес необходимой функции с помощью операции взятия адреса. Например,

//объявляем pf как указатель на функцию типа float любоеИмя(float)

 typedef float (*pf)(float);

 //определяем функцию fun такого типа

 float fun(float) {/* тело функции *./}

………………

pf=&fun; //получаем адрес функции fun

c=pf(a);//вызываем функцию fun по указателю pf на неё

 

Удобно использовать переименование типов (typedef) при описании указателей на функцию. Указатели на функцию передаются в подпрограмму так же, как и параметры других типов. Тип указателя и тип функции, передаваемой посредством этого указателя, должны совпадать полностью.

Пример программы, вычисляющей значение приведенного выражения.

// передача в подпрограмму в качестве параметра имени функции

 

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include <math.h>

typedef float (*pf)(float);

float f1(float x);

float f2(float x);

float f3(float x);

float sum(int n,float *a,pf f);

int _tmain(int argc, _TCHAR* argv[])

{ const int nn=30;

float a[nn],z;

int n;

printf("wwedite kol-wo elementow \n");

scanf("%d",&n);

printf("\nwwedite elementi\n");

for (int i=0;i<n;i++)

scanf("%f",&a[i]);

z=(sum(n,a,f1)+sum(n,a,f2))/sum(n,a,f3);

printf("\n summa=%6.2f",z);

getch();

return 0;

}

 

float f1(float x)

{return (sin(x+1.0));

}

float f2(float x)

{return (exp(x/2.0));

}

float f3(float x)

{return (log(x+2.0));

}

float sum(int n,float *a,pf f)

{float s;

 s=0;

 for (int i=0;i<n;i++)

 s+=f(a[i]);

 return s;

}

Примеры программ с подпрограммами

Приведем примеры организации программ с подпрограммами.

Пример 1. Определить в матрице все элементы, которые являются числами Фибоначчи, и переписать их в одномерный массив. Полученный массив упорядочить по возрастанию. Числа Фибоначчи образуются по следующему правилу: f0=1, f1=1, fi =fi-2 +fi-1 (i≥2).

Программирование проведем с использованием подпрограмм. Составим функцию, которая определяет, является ли число, переданное в качестве аргумента, числом Фибоначчи. Кроме того, составим функцию упорядочения элементов одномерного массива по возрастанию. Для проверки правильности выполнения отдельных этапов алгоритма выведем получаемый массив чисел Фибоначчи до его упорядочения и после упорядочения. В этом случае целесообразным является составить функцию вывода элементов одномерного массива, так как это действие приходится осуществлять дважды. Для придания программе большей универсальности будем использовать динамические массивы.

Проверку заданного числа на число Фибоначчи будем проводить путем последовательного сравнения этого числа со всеми числами Фибоначчи, начиная с 1. Процесс сравнения заканчивается в том случае, если заданное число оказалось числом Фибоначчи или если очередное число Фибоначчи превысило заданное число.

Для упорядочения чисел используется алгоритм “пузырьковой сортировки”.

// нахождение в матрице чисел Фибоначчи и сортировка их по

// возрастанию.

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include "stdlib.h"

#include "math.h"

bool fib(int a);

void out(int *b,int k);

void upor(int *b,int k);

int _tmain(int argc, _TCHAR* argv[])

{

 int **a, //Массив исходной матрицы

*b; //Массив чисел Фибоначчи

int m,n,i,j,k;

printf("wwedite kol-wo strok i stolbzow\n");

scanf("%d%d",&m,&n);

a=(int **)malloc(m*sizeof(int *));

for(i=0;i<m;i++)

a[i]=(int *)malloc(n*sizeof(int));

printf("\nwwedite matrizu\n");

for (i=0;i<m;i++)

for (j=0; j<n;j++)

scanf("%d",&a[i][j]);

  

printf("\nisxodnaja matriza\n");

for (i=0; i<m;i++)

{

for (j=0; j<n;j++)

printf("%3d ",a[i][j]);

printf(" \n");

}  

k=0;

b=(int *)malloc(k*sizeof(int));

for (i=0;i<m;i++)

for (j=0; j<n; j++)

       {  

    if (fib(a[i][j]))

        { k++;

     b=(int *)realloc(b,k*sizeof(int));

     b[k-1]=a[i][j];

       }

}

if (k==0) printf("\n W matrize net chisel fibonachhi\n");

else

{

printf("\n Massiw chisel fibonachhi\n");

out(b,k);

upor(b,k);

printf("\nUporjadochennij massiw chisel fibonacci\n");

out(b,k);

}

getch();

return 0;

}

 

 

//Функция упорядочения элементов

//одномерного массива по возрастанию

void upor(int *b,int k)

{ int i,c,n;

bool pr;

n=0;

do

{

  n++;

  pr=true;

  for (i=0; i<k-n; i++)

if (b[i]>b[i+1])

{ c=b[i];

     b[i]=b[i+1];

     b[i+1]=c;

     pr=false;

}

}while (!pr);

}

 //Функция, определяющая, является ли

//заданное число числом Фибоначчи

bool fib(int a)

{int f0,f1,f2;

bool res;

res=false;

f1=1;f2=1;

do

{

if (a==f2) res=true;

else {f0=f1;

  f1=f2;

f2=f0+f1;}

}while (!res&&a>=f2);

return res; //конец функции Fib

}

void out(int *b,int k)

{for (int i=0;i<k;i++)

printf("%3d ",b[i]);

}

 

Пример 2. Определить в каждой строке матрицы A(m,n), m<=10, n<=12, первое по порядку простое число и занести его в одномерный массив. Если в строке нет простых чисел, то для этой строки в массив занести 0.

Поскольку максимальные размеры матрицы заданы в условии, то в программе целесообразно использовать статические массивы. Определение вида числа (простое или нет) произведем в подпрограмме-функции, которая возвращает значение “истина”, если число простое, и “ложь” в противном случае.

Для определения вида числа следует определить остатки от деления этого числа на все целые числа, начиная с двух и заканчивая числом, которое является квадратным корнем из этого числа. Если при делении на все эти числа все остатки будут отличны от нуля, то число является простым. Если же при делении на очередное число остаток окажется равным нулю, то это число не является простым и дальнейшие проверки можно не производить. Эти действия и выполняются в функции с помощью цикла с заранее неизвестным числом повторений.

Поиск первого простого числа в каждой строке матрицы реализован в основной программе также с помощью цикла с заранее неизвестным числом повторений. Цикл выполняется , пока не найдено в этой строке простое число и пока не исчерпаны элементы строки. Если простое число найдено или все элементы строки уже проанализированы, то цикл следует завершить.

// поиск в каждой строке матрицы первого простого числа

 

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include "math.h"

 

bool pros(int a);

 

int _tmain(int argc, _TCHAR* argv[])

{ const int mm=10, nn=12;

int a[mm][nn],b[mm],i,j,m,n;

bool pr;

printf("wwedite kol-wo strok i stolbzow\n");

scanf("%d%d",&m,&n);

printf("\nwwedite matrizu\n");

for (i=0;i<m;i++)

for (j=0; j<n;j++)

scanf("%d",&a[i][j]);

for (i=0; i<m; i++)

{

j=0;

pr=false;

while(j<n && !pr)

 {

  pr=pros(a[i][j]);

  if (!pr) j++;

 }

 if (pr) b[i]=a[i][j];

else b[i]=0;

}

//Вывод матрицы по строкам и правее

//каждой строки - первого простого числа

printf("\nisxodnaja matriza i prostie chisla\n");

for (i=0; i<m;i++)

{

for (j=0; j<n;j++)

printf("%3d ",a[i][j]);

printf(" %3d\n",b[i]);

getch();

return 0;

}

 //Функция определения простого числа

bool pros(int a)

{ bool res;

if (a==1) res=false;

else

{int i=2;

res=true;

while (res && i<=sqrt((float)a))

if (a%i==0) res=false;

else i++;

}

return res; //конец функции Pros

}

 

 

Пример 3. Составить функцию, которая в каждой строке матрицы заменяет каждый положительный элемент минимальным отрицательным элементом из стоящих между предыдущим и текущим положительными элементами. Если положительный элемент стоит на первом месте в строке, то его не изменять. Если отрицательных элементов нет между положительными, то замену не производить.

Использовать составленную функцию для матрицы W(m,n),m<=12,n<=15.

В основной программе произведем ввод исходных данных (количества строк и столбцов матрицы и самой матрицы), с помощью процедуры преобразуем матрицу и осуществим вывод исходной и преобразованной матриц. Поскольку вывод необходимо выполнить два раза, то целесообразно организовать для этого функцию.

Преобразование матрицы осуществляется в процедуре. Суть выполняемых действий сводится к тому, что каждый элемент строки матрицы необходимо анализировать на положительность. При появлении положительного элемента надо найти минимальный элемент, стоящий между предыдущим положительным и текущим положительным. Если найденный минимальный элемент окажется отрицательным, то его следует поместить на место текущего положительного элемента. После нахождения положительного элемента необходимо запомнить индекс столбца, в котором он расположен.

 

// программа замены в строках матрицы положительных чисел минимальным

// отрицательным из расположенных между положительными

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include "math.h"

const int nn=15;

void wiwod(const float a[][nn],int m,int n);

void samen(float a[][nn],int m,int n);

int _tmain(int argc, _TCHAR* argv[])

{

 const int mm=12;

 float w[mm][nn]; //Массив исходной матрицы

 int m,n,i,j;

printf("wwedite kol-wo strok i stolbzow\n");

scanf("%d%d",&m,&n);

printf("\nwwedite matrizu\n");

for (i=0;i<m;i++)

for (j=0; j<n;j++)

scanf("%f",&w[i][j]);

printf("\nisxodnaja matriza \n");

wiwod(w,m,n);

samen(w,m,n);

printf("\npreobrasowannaja matriza \n");

wiwod(w,m,n);

getch();

return 0;

}

 

void wiwod(const float a[][nn],int m,int n)

{ for (int i=0; i<m;i++)

{

for (int j=0; j<n;j++)

  printf("%6.1f ",a[i][j]);

printf("\n");

}

 

void samen(float a[][nn],int m,int n)

{int i,j,jpol,l;

 float min;

 for (i=0; i<m; i++)

 {

jpol=-1;

for (j=0; j<n; j++)

{

if (a[i][j]>0)

 {

    min=a[i][jpol+1];

    for (l=jpol+1; l<j; l++)

      if (a[i][l]<min) min=a[i][l];

    if (min<0) a[i][j]=min;

    jpol=j;

 }

}

 }

}


 

Модули пользователей


Дата добавления: 2018-10-27; просмотров: 392; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!