Использование указателей при передаче параметров




Л а б о р а т о р н а я р а б о т а N 6

Функции

 

 

Вы уже знакомы с некоторыми библиотечными функциями, такими как printf(), scanf(), getchar(), putchar(), gets(), sin(), cos(),.... Теперь нужно знать, как создавать свои собственные функции.

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

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

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

Описание любой функции имеет вид:

 

Заголовок функции

{ Описания локальных переменных

Операторы

}

 

Заголовок функции имеет формат:

 

Тип_функции имя_функции (список_параметров)

 

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

 

Примеры заголовков функций:

 

main()

float max (float x, float y)

int prov (char mas[], int s)

void line (ink k, int n, char simv, int ps)

 

Тип функции, указанный перед именем функции, - это тип возвращаемого функцией значения. По умолчанию предполагается тип int. Если функция никакое значение не возвращает, то указывается тип void.

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

 

void line (k,n,simv,ps)

int k,n;

char simv;

int ps;

 

Но такая форма записи уже устарела (и имеет недостатки).

Значение функции передается в вызывающую программу с помощью оператора возврата return.

 

Пример описания функции:

 

/* функция определения наибольшего из двух чисел */

float max (float x, float y)

{ if (x>y) return x;

else return y;

}

 

/* 2-й вариант */

float max (float x, float y)

{ float z; /* z=max(x,y) */

z = (x>y)? x: y;

return z;

}

 

Вы можете вызвать свою функцию в любом выражении, указав ее имя и аргументы (фактические параметры):

 

 

Имя_функции (аргумент_1, аргумент_2,...)

Аргументом может быть идентификатор, константа и выражение. Типы аргумента и соответствующего параметра в заголовке функции должны совпадать. Например, оператор

f = max(a,b) - max(c,d);

содержит два вызова приведенной выше функции max. При первом обращении функции max передаются значения переменных a и b, она возвращает наибольшее из этих чисел, которое подставляется вместо указателя функции max(a,b). При втором вызове функции max формальным параметрам x и y присваиваются соответственно значения фактических параметров c и d. Оператор return возвращает наибольшее из этих значений в точку вызова функции.

Вызов функции без параметров имеет вид: имя_функции ().

 

 

Использование указателей при передаче параметров

 

Обмен информацией между вызывающей программой и функцией осуществляется благодаря параметрам. Если данные входные и функцией не изменяются, то передавать в списке параметров нужно значения данных. Сложнее вернуть вызывающей программе выходные данные, если их несколько (если результатом выполнения функции является одно единственное значение, то оно обычно, как вы уже видели, в число параметров не включается, а является значением функции). Если функция должна вернуть вызывающей программе нес колько значений, в этом случае передавать ей в качестве фактических параметров нужно адреса переменных. Вспомните вызов функции scanf(). Если, например, нужно ввести значения двух переменных x и y типа int, вы должны написать:

scanf ("%d %d",&x,&y);

где &x,&y - адреса переменных x и y. Точно так же при обращении к своей функции для выходных параметров нужно указывать адреса.

В описании функции соответствующие формальные параметры должны быть описаны как указатели на переменные соответствующего типа.

Допустим, функция function1() должна изменить значения переменных a и b типа float. В вызывающей программе обращение к функции нужно записать так:

function1 (&a, &b);

а заголовок функции должен иметь вид:

void function1 (float *ptr1, float *ptr2)

 

 

Здесь prt1 и ptr2 - это указатели на переменные типа float (названия их могут быть изменены - это формальные параметры). Значениями указателей являются адреса. При вызове функции function1 переменной pt1 присваивается адрес a, а ptr2=&b.

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

*ptr1 =...;

*prt2 =...;

Итак, если ptr1 и ptr2 являются указателями на переменные, то чтобы взять значения этих переменных, нужно перед именами указателей использовать операцию *.

 

 

Пример.

 

Задача. Нарисовать параллелограмм вида

 

|<---- A ---->|

*************** --

* * ¦

* * H

* * ¦

*************** ------

 

при заданных значениях A, H и C, где C - смещение фигуры по горизонтали вправо относительно левой границы экрана.

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

Программа:

 

 

#include <stdio.h>

#include <conio.h>

 

 

/*************************************************/

/* Функция вывода горизонтального отрезка прямой */

/*************************************************/

 

void line (int k, int n, char simv, int ps)

/* Входные данные: */

/* k - смещение отрезка вправо, */

/* n - длина отрезка, */

/* simv - символ заполнения отрезка, */

/* ps - признак перевода строки: */

/* если ps!=0, то нужен перевод строки после вывода*/

/* отрезка; если ps=0, то не нужен перевод строки */

{ int i; /* параметр цикла */

/* установление левой границы отрезка */

for (i=0; i<k; i++) putchar (' ');

/* вывод отрезка */

for (i=0; i<n; i++) putchar (simv);

if (ps) putchar ('\n');

}

 

/***************************************/

/* О с н о в н а я п р о г р а м м а */

/***************************************/

 

main()

{ int c, /* смещение нижнего левого угла */

a,h, /* основание и высота параллелограмма */

i, /* параметр цикла */

cls; /* смещение левой боковой стороны */

printf ("Введите три числа: смещение, основание, высоту.\n");

scanf ("%d %d %d",&c,&a,&h);

cls=c+h-1;

line (cls,a,'*',1);

for (i=0; i<h-2; i++)

{ line (--cls,1,'*',0);

line (a-2,1,'*',1);

}

line (c,a,'*',1);

getch();

}

 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: