Использование указателей для работы с функциями 


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



ЗНАЕТЕ ЛИ ВЫ?

Использование указателей для работы с функциями



(2 часа)

Цель работы: выработать практические навыки в написании программ с функциями и в использование указателей для работы с функциями.

 

Теоретические сведения

С позволяет использовать указатели на базовые типы, на массивы и структуры как параметры передаваемые в функцию и возвращаемые из функции, а также указатели на функции. Общий синтаксис для объявления указателя на структуру как параметры функции:

[const ]<тип>*<имя указателя>

При объявлении функции имя указателя как формального параметра может не указываться аналогично другим видам формальных параметров.

Ключевое слово const предохраняет данные от изменения данных в структуре функции, тогда как отсутствие ключевого слова const позволяет функции изменять значения данных, т.к. при использовании указателей в теле функции известны физические адреса переменных.

Пример использования указателей на различные типы данных как параметры функции.

int funct (float*, int*); // передача указателей на тип float и на тип int

Struct Мyst

{

//члены;

};

void loadMy(Myst*pmy); // передача указателя рmу натип структур типа Муst.

В примере объявлена структура типа Myst и объявлена функция loadMy(). Функция имеет формальный параметр-указатель pmy на тип Мyst.

Вызов функции funct() и fn():

Float*pf; int*pl;

Int a = funct(pf, pl); fn(pf);

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

void (* pfunc) (int, int);

Объявлен указатель pfunc на функцию, которая требует два параметра типа int и не возвращает значения (void). Типы и количество параметров, а также тип возвращаемого значения должны создать. Для использования указателя объявим функцию

void f1 (int, int);

Присвоим указателю адрес функции

pfunc= f1;

и осуществим её вызов

(*pfunc)(2,4);

 

Указатели как параметры функции

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

Для передачи аргументов в функцию используют:

1 Указатели на простые типы данных, как параметры функции.

2 Указатели на массивы (передавать по значению нельзя).

3 Указатели на перечислимые типы как параметры функции.

4 Указатели на структуры и объединения как параметры функции.

5 Указатели на функции (передавать по значению нельзя).

С позволяет объявлять и использовать указатели на функции. В таком указателе хранится адрес функции, т.е. адрес первого выполнимого оператора. Указатель на функцию можно использовать для её вызова. Общий синтаксис для объявления указателя на функцию:

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

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

Инициализация указателя на функцию:

<имя_указателя> = <имя_функции>;

Общий синтаксис для вызова функции с использованием указателя:

(*<имя_указателя>)(<список_фактических_параметров>);

Пример

int linescarch (int)*pstring //объявление функции linesearch (int*)

Voild main()

{int a; * pstr = “Hello World!”; // объявление переменной и указателя pstr на тип int

int (*search)(int*); // объявление указателя на функцию

search= linesearch; //присваиваем адрес функции linesearch() указателю search

//другие операторы

a = (* search)(pstr); // вызов функции linesearch () с помощью указателя.

}

Пример

/* ЗАНЯТИЕ N 16

Разработал Петров Ю.В.

Объявить заданные функции и указатель на функцию этого типа,

выполнить определение функций. Объявить массивы и указатели

на них, выполнить инициализацию в соответствии с заданными

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

массивов выделить память в куче. Вывести значения элементов

массивов на экран. Осуществить вызов функций с применением

указателя. Вывести результаты работы функций на экран. */

#include <stdio.h>

#include <math.h>

#include <conio.h>

#include <iostream.h>

const int kx = 6, ky = 6, kw = 8, a1 = 3, a2 = 9,

b1 = 6, b2 = 5, c1 = 6, c2 = 10;

 

//Вычисляет сумму отрицательных элементов массива

float summa (int, float*);

//Вычисляет произведение положительных элементов массива

float prois (int, float*);

float (*ps)(int, float*); //Объявление указателя на функцию

 

void main ()

{

int i;

float y[ky+2]; //+2 элемента массива для хранения

// результатов работы функций

float *px=new float [kx+2];//Выделение памяти для массива в "куче"

float *xptr;

clrscr();

printf("Массив x[]\n");

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

{ *px = a1*i*i - a2*(5-i); //Инициализация динамического массива

printf("x[%d] = %6.2f %p \n",i, *px, px);

px++;

}

xptr = y;

gotoxy(25,1); printf("Массив y[]\n");

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

{ *xptr = b1*sin(2*i) + b2*exp(i-5); //Инициализация массива y[]

gotoxy(30,i+2);

printf("y[%d] = %6.2f\n",i,*xptr);

xptr++;

}

px-=kx; //Установка указателя на нулевой элемент массива

printf("Указатель на дин. массив содержит адрес рx = %p\n ", px);

ps=summa; //Связывание указателя с функцией summa()

printf("Указатель на функцию содержит адрес рs = %p\n ", ps);

printf("Сумма: x[%d] = %6.2f ", kx, (*ps)(kx, px));

printf("Сумма: y[%d] = %6.2f\n ", ky, (*ps)(ky, y));

ps=prois; //Связывание указателя с функцией prois()

printf("Указатель на функцию содержит адрес рs = %p\n ", ps);

printf("Произведение: x[%d] = %8.2f ", kx+1, (*ps)(kx, px));

printf("Произведение: y[%d] = %8.2f\n ", ky+1, (*ps)(ky, y));

delete [] px; //Освобождение памяти, выделенной в "куче"для массива

getch();

}

 

float summa (int kol, float* Arr) //Определение функции

{ float s=0;

for (int i=0; i<kol; i++) if (Arr[i]<0) s+=Arr[i];

return s;

}

 

float prois (int kol, float* Arr) //Определение функции

{ float s=1;

for (int i=0; i<kol; i++) if (Arr[i]>0) s*=Arr[i];

return s;

}

/*

Массив x[] Массив y[]

x[0] = -45.00 0AD0 y[0] = 0.03

x[1] = -33.00 0AD4 y[1] = 5.55

x[2] = -15.00 0AD8 y[2] = -4.29

x[3] = 9.00 0ADC y[3] = -1.00

x[4] = 39.00 0AE0 y[4] = 7.78

x[5] = 75.00 0AE4 y[5] = 1.74

Указатель на дин. массив содержит адрес рx = 0AD0

Указатель на функцию содержит адрес рs = 049C

Сумма: x[6] = -93.00 Сумма: y[6] = -5.29

Указатель на функцию содержит адрес рs = 04F3

Произведение: x[7] = 26325.00 Произведение: y[7] = 2.52 */

Ход работы

1 Изучить теоретические сведения.

2 В соответствии с индивидуальным заданием по лабораторной работе №7. разработать алгоритм.

3 Объявить указатели на функции. Использовать указатели для вызова соответствующих функций. Использовать оператор switch для выбора варианта функций.

4 Разработать и набрать программу на компьютере, устранить ошибки.

5 Получить результат.

6 Оформить отчет.

7 Подготовиться к защите лабораторной работы, изучив контрольные вопросы.

 

Индивидуальное задание к лабораторной работе №16

Составить программу использующую вызовы функций с помощью указателей. Индивидуальные задания приведены в таблице 16.1.

Таблица 16.1 - индивидуальные задания

Вариант первая функция вторая функция третья функция четвертая функция
  int (*func1) (int *) int (*func2) (int *,float *) int (*func3) (void *) char *func4 (char *,…)
  float (*func1) (int *, float *, double *) float (*func2) (void *,…) float (*func3) (int, …) double (*func4 (double, double))[3]
  void (*func1) (void *, int *) void (*func2) (int, int *) void (*func3) (void) int (*func4 (void))(int)
  double (*func1) (float *, int) double (*func2) (double, long int) double (*func3) (unsigned int *) int (*func4(int)) (int)[3][5]
  long double (*func1) (int *, float *) long double (*func2) (void *, …) long double (*func3) (int, …) char * (*func4 (int *, …))(void *)
  char (*func1) (unsigned int *) char (*func2) (int *, float *, double *) char (*func3) (void *,…) int *func4(char *, int *,…)
  long int (*func1) (int, int *) long int (*func2)(double, long int) long int (*func3)(void) float (*func4 (double)(void)) [10]
  unsigned int (*func1) (int *) unsigned int (*func2) (int, …) unsigned int (*func3) (int *,float *) long int (*func4(int)) (void)
  float (*func1) (int *, float *, double *) float (*func2) (unsigned int *) float (*func3) (void) void *func4 (int *, int, …)
  unsigned long int (*func1) (int, …) unsigned long int (*func2) (int *) unsigned long int (*func3) (double, long int) float (*func4(long int, int))[5]
  signed int (*func1) (int *, float *, double *) signed int (*func2) (int) signed int (*func3) (void *, …) double (*func4 (char)(int *))[4]
  double (*func1) (float *, int) double (*func2) (double, long int) double (*func3) (unsigned int *) double (*func4 (double, double))[3]
  long double (*func1) (int *, float *) long double (*func2) (void *, …) long double (*func3) (int, …) int (*func4 (void))(int)
  char (*func1) (unsigned int *) char (*func2) (int *, float *, double *) char (*func3) (void *,…) int (*func4(int)) (int)[3][5]
  long int (*func1) (int, int *) long int (*func2)(double, long int) long int (*func3)(void) char * (*func4 (int *, …))(void *)
  unsigned int (*func1) (int *) unsigned int (*func2) (int, …) unsigned int (*func3) (int *,float *) int *func4(char *, int *,…)
  int (*func1) (int *) int (*func2) (int *,float *) int (*func3) (void *) float (*func4 (double)(void)) [10]
  float (*func1) (int *, float *, double *) float (*func2) (void *,…) float (*func3) (int, …) long int (*func4(int)) (void)
  void (*func1) (void *, int *) void (*func2) (int, int *) void (*func3) (void) int *func4(char *, int *,…)
  double (*func1) (float *, int) double (*func2) (double, long int) double (*func3) (unsigned int *) float (*func4 (double)(void)) [10]
  long double (*func1) (int *, float *) long double (*func2) (void *, …) long double (*func3) (int, …) long int (*func4(int)) (void)
  char (*func1) (unsigned int *) char (*func2) (int *, float *, double *) char (*func3) (void *,…) void *func4 (int *, int, …)
  unsigned long int (*func1) (int, …) unsigned long int (*func2) (int *) unsigned long int (*func3) (double, long int) float (*func4(long int, int))[5]
  signed int (*func1) (int *, float *, double *) signed int (*func2) (int) signed int (*func3) (void *, …) double (*func4 (char)(int *))[4]
  double (*func1) (float *, int) double (*func2) (double, long int) double (*func3) (unsigned int *) char *func4 (char *,…)
  long double (*func1) (int *, float *) long double (*func2) (void *, …) long double (*func3) (int, …) double (*func4 (double, double))[3]
  char (*func1) (unsigned int *) char (*func2) (int *, float *, double *) char (*func3) (void *,…) int (*func4 (void))(int)
  double (*func1) (int *, float *, double *) double (*func2) (double, long int) double (*func3) (unsigned int *) int (*func4(int)) (int)[3][5]
  void (*func1) (void *, int *) void (*func2) (int, int *) void (*func3) (void) char * (*func4 (int *, …))(void *)
  double (*func1) (float *, int) double (*func2) (double, long int) double (*func3) (unsigned int *) int *func4(char *, int *,…)

 

 

Требования к содержанию отчёта приведены в лабораторной работе №1.

 

Контрольные вопросы для подготовки и самостоятельной работы

 

1 Можно ли использовать указатели для передачи данных в функции?

2 Какие типы данных можно передать в функцию с использованием указателей?

3 Можно ли менять значения данных в функции при использовании указателей при наличии модификатора const.

4 Можно ли возвращать указатели из функций?

5 Как объявить указатель на функцию?

6 Можно ли использовать указатели для работы с функциями различного типа?

7 Какой тип имеет имя функции?

8 Как связать указатель с конкретной функцией?

9 Как использовать указатели для вызова функции?

10 Как ограничивается доступ к членам класса?

11 Как связать и использовать указатель на функцию?

12 Как вызвать функцию с использованием указателя?

Лабораторная работа №17

Использование функций высокого и низкого уровня для работы с
потоками (файлами)

(2 часа)

Цель работы: научиться использовать функции высокого и низкого уровня при работе с файлами.

 

Теоретические сведения

 



Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 464; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.216.32.116 (0.042 с.)