Интерфейс с программами и подпрограммами, написанными на разных языках программирования. Указатели на функции

Страницы работы

Уважаемые коллеги! Предлагаем вам разработку программного обеспечения под ключ.

Опытные программисты сделают для вас мобильное приложение, нейронную сеть, систему искусственного интеллекта, SaaS-сервис, производственную систему, внедрят или разработают ERP/CRM, запустят стартап.

Сферы - промышленность, ритейл, производственные компании, стартапы, финансы и другие направления.

Языки программирования: Java, PHP, Ruby, C++, .NET, Python, Go, Kotlin, Swift, React Native, Flutter и многие другие.

Всегда на связи. Соблюдаем сроки. Предложим адекватную конкурентную цену.

Заходите к нам на сайт и пишите, с удовольствием вам во всем поможем.

Содержание работы

                            Интерфейс

   с программами и подпрограммами, написанными на разных языках

                      программирования.

                     Указатели на функции.

Рассматриваются вопросы взаимодействия между программами и подпрограммами, написанными на разных языках программирования.

1)  Указатели на функции.

Каждая функция характеризуется типом возвращаемого значения, именем и сигнатурой (количеством, порядком следования и типом операндов). Таким образом, сигнатура – это список параметров функции.

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

 <тип возвращаемого значения функции> (*<имя _ указателя>)

                       (<спецификация параметров>).

Например, создадим пустое меню для вызова некоторых функций:

сhar FileName[30]; //обрабатываемая строка с инициализацией

void act1 (char *name);

void act2 (char *name);

void act3 (char *name);

typedef void (*MENU) (char *) // тип MENU указателей на функцию с

       // возвращаемым значением VOID и с одним операндом типа VOID

MENU MenuAct[3]={act1,act2,act3} //инициализация таблицы адресов

Void main()

{ int num;

  cout << “\n Введите номер пункта меню”;

  cin>>num;

  (*MenuAct[num-1])(FileName);

}

Как видим, в данной программе создан набор функций одного типа и сигнатуры. Используя данный массив указателей на эти функции, можем  их выполнить.

Аналогично предыдущему примеру можно решить алгебраическое уравнение методом деления пополам на отрезке от float A до float B с точностью float E.

#include <stdlib.h>

#include <stdio.h>

float f (float x)

  {return x*x*x*x*10-X*5+3;} //исследуемая функция

typedef float (*PointFunc) (float); //предопределение функции

float des(PointFunc f,float A,float B,float E)

{ float x,y,c,Fx,Fy,Fc;

  x=A; y=B; Fx=(*f)(x); Fy=(*f)(y);

 if (Fx*Fy>0.0)

  { printf (“неверный интервал решения\n”)

    exit(1);

  }    // выход в случае ошибки

 do

  { c=(y-x)/2;

    Fc=(*f)(c);

    if (Fc*Fx>0){x=c; Fx=Fc;}

     else

        {y=c; Fy=Fc;}

  } while (Fc!=0||y-x>E);

 return c;

}

void main()

{ float result;

  result=res(f,0.0,2.0,1e-5);

  printf (“result= %f ”,result);

}

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

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

  #include <stdio.h>

  #include <string.h>

  #defineMAXLINES 5000     /* max количество сортируемых линий */

char *lineptr[MAXLINES]; /*указатели на линии текста*/

int readlines (char *lineptr[], int nlines);

  void writelines (char *lineptr[], int nlines);

  void qsort(void *lineptr[], int left, int right,

                    int (*comp) (void *, void *));

  int numcmp (char *, char *);

  /* сортировка вводимых строк */

main (int argc, char *argv[])

    { intnlines;       /*число вводимых строк */

intnumeric = 0;      /* 1если числовая сортировкаt */

if (argc>1 && strcmp(argv[1], "-n") == 0)

                numeric = 1;

      if ((nlines = readlines (lineptr, MAXLINES)) >= 0)

        { qsort( (void **) lineptr, 0, nlines-1,

                       int (*)(void*, void*))(numeric?numcmp:strcmp));

             writelines (lineptr, nlines);

          return 0;

        } else

           {   printf ("input too big to sort\n");

               return 1;

           }

      }

QSORT написана так что может выполняться с любым типом данных, а не только с цифровыми данными. Как следует из прототипа QSORT требует для работы массив указателей, двух целых чисел и функции с двумя аргументами-указателями. Генерированный тип – VOID*, и затем преобразуется к нужному типу операцией преобразования.

/*qsort: sort v[left]...v(right] Into increasing order*/

void qsort(void *v[], int left, int right,

                    int (*comp) (void *, void *))

 { int i, last;

   void swap (void >v[], int, int);

if (left >= right) /*ничего не делать, если в массиве */

return;          /* меньше двух элементов */

swap(v, left, (left + right)/2);

          last = left;

          for (i = left+1; i <= right; i++)

                if ((*comp)(v[i]. v[leftl) < 0)

                     swap(v, ++last, i);

          swap(v, left, last);

          qsort(v, left, last-1, comp);

          qsort(v, last+1, right, comp);

 }

Декларация должна выполняться с некоторой  осторожностью.

  int (*comp) (void *, void *)

которая означает, что COMP это указатель на функцию с двумя аргументами типа  VOID* и возвращает INT. Выражение

  if ((*comp)(v[i], v[left]) < 0

включает декларацию указателя на функцию COMP, которая и будет вызвана

(*comp) (v[i], v[left])

Скобки необходимы, чтобы правильно определить входящие элементы.

   int *comp(void *, void *)    /* WRONG */

  #include <stdlib.h>

  /*  numcmp: выполняет цифровое сравнение s1 и s2 */

int numcmp (char *s1, char *s2)

   {  double v1, v2;

       v1 = atof (s1);

       v2 = atof (s2);

        if (v1 < v2)

           return -1;

        else if (v1 > v2)

           return 1;

        else

           return 0;

Похожие материалы

Информация о работе

Уважаемые коллеги! Предлагаем вам разработку программного обеспечения под ключ.

Опытные программисты сделают для вас мобильное приложение, нейронную сеть, систему искусственного интеллекта, SaaS-сервис, производственную систему, внедрят или разработают ERP/CRM, запустят стартап.

Сферы - промышленность, ритейл, производственные компании, стартапы, финансы и другие направления.

Языки программирования: Java, PHP, Ruby, C++, .NET, Python, Go, Kotlin, Swift, React Native, Flutter и многие другие.

Всегда на связи. Соблюдаем сроки. Предложим адекватную конкурентную цену.

Заходите к нам на сайт и пишите, с удовольствием вам во всем поможем.