Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Объявление и определение функций





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

Функция является одним из производных типов С++, типом «функция» считается совокупность типа возвращаемого значения и типов передаваемых параметров.

 
 

 

 


Любая функция должна быть объявлена и определена.

Объявление функции (прототип, заголовок) задает имя функции, тип возвращаемого значения и список передаваемых параметров.

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

тип_возвращаемого_значения имя_функции(список_формальных_параметров, если они есть)

{ тело_функции}

 

Тело_функции – это блок или составной оператор. Функциям в С++ запрещено быть вложенными, т.е. нельзя внутри некоторой функции нельзя определить другую функцию.

В теле функции должен быть оператор, который возвращает полученное значение функции в точку вызова. Он может иметь 2 формы:

1) return выражение;

2) return;

Первая форма используется для возврата результата, поэтому выражение должно иметь тот же тип, что и тип возвращаемого функцией значения в определении. Вторая форма используется, если функция не возвращает значения, т. е. имеет тип void. Программист может не использовать этот оператор в теле функции явно, компилятор добавит его автоматически в конец функции перед «}».

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

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

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

 

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

Пример:

Заданы координаты сторон треугольника. Если такой треугольник существует, то найти его площадь.

1. Математическая модель:

1) l=sqrt(pow(x1-x2,2)+pow(y1-y2,2));/* по этой формуле находим длины сторон треугольника a,b,c

2) если (a+b>c&&a+c>b&&c+b>a)// проверка существования треугольника

то 2.1) находим p=(a+b+c)/2;// полупериметр

2.2) находим площадь

s=sqrt(p*(p-a)*(p-b)*(p-c));// формула Герона

иначе сообщаем о том, что треугольник не существует.

2. Алгоритм:

1)Ввести координаты вершин треугольника (х1,у1),(х2,у2),(х3,у3);

2)Вычислить длины сторон ab, bc, ca;

3)Проверить существует ли треугольник с такими сторонами. Если да, то вычислить площадь и вывести результат.

4)Если нет, то вывести сообщение.

5)Если все координаты равны 0, то конец, иначе возврат на п.1.

 

#include <iostream.h>

#include <math.h>

double line(double x1,double y1,double x2,double y2){

//функция возвращает длину отрезка, заданного координатами x1,y1 и x2,y2

return sqrt(pow(x1-x2,2)+pow(y1-y2,2));

}

double square(double a, double b, double c){

//функция возвращает площадь треугольника, заданного длинами сторон а,b,c

double s, p=(a+b+c)/2;

return s=sqrt(p*(p-a)*(p-b)*(p-c));//формула Герона

}

bool triangle(double a, double b, double c){

//возвращает true, если треугольник существует

if(a+b>c&&a+c>b&&c+b>a)

return true;

else return false;

}

void main()

{

double x1=1,y1,x2,y2,x3,y3;

double ab, ac, bc;

do{

cout<<"\Введите координаты вершин треугольника:";

cin>>x1>>y1>>x2>>y2>>x3>>y3;

ab=line(x1,y1,x2,y2);

ac=line(x1,y1,x3,y3);

bc=line(x2,y2,x3,y3);

if(triangle(ab,ac,bc)==true)//в данном случае он всегда будет существовать!

cout<<"S="<<square(ab,ac,bc)<<"\n";

else cout<<"\nTriagle doesnt exist";

}while(!(x1==0&&y1==0&&x2==0&&y2==0&&x3==0&&y3==0));

}

12.2. Прототип функции

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

double line(double x1,double y1,double x2,double y2);

double square(double a, double b, double c);

bool triangle(double a, double b, double c);

Это прототипы функций, описанных выше.

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

Имя_файла – определяет заголовочный файл, содержащий прототипы группы стандартных для данного компилятора функций. Например, почти во всех программах мы использовали команду препроцессора #include<stdio.h> для описания функций стандартного ввода/вывода или #include <iostream.h> для описания объектов потокового ввода-вывода.

При разработке своих программ, состоящих из большого количества функций, размещенных в разных модулях, прототипы функций и описания внешних объектов (констант, переменных, массивов) помещают в отдельный файл, который включают в начало каждого из модулей программы с помощью директивы #include ”имя_файла”.

 

12.3. Параметры функции

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

При передаче по значению выполняются следующие действия:

- вычисляются значения выражений, стоящих на месте фактических параметров;

- в стеке выделяется память под формальные параметры функции;

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

Пример:

double square(double a, double b, double c){

//функция возвращает площадь треугольника, заданного длинами сторон а,b,c

double s, p=(a+b+c)/2;

return s=sqrt(p*(p-a)*(p-b)*(p-c)); //формула Герона

}

1) double s1=square(2.5,2,1);

2) double a=2.5,b=2,c=1;

double s2=square(a,b,c);

3) double x1=1,y1=1,x2=3,y2=2,x3=3,y3=1;

double s3=square(sqrt(pow(x1-x2,2)+pow(y1-y2,2)),//расстояние между 1и2

sqrt(pow(x1-x3,2)+pow(y1-y3,2)), //расстояние между 1 и 3

sqrt(pow(x3-x2,2)+pow(y3-y2,2)));//расстояние между 2 и3

Стек

A 2.5
B  
C  
S  
P  

P и S – локальные переменные.

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

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

Пример.

1)void change(int a,int b){// передача по значению

int r=a;a=b;b=r;

}

int main(){

int x=1,y=5;

change(x,y);

A    
B    
r    

cout<<”x=”<<x<<”y=”<<y;

return 0;

}

выведется: x = 1 y = 5, т.е. переменные значениями не обменялись

2) void Change(int *a,int *b){//передача по адресу

int r=*a;*a=*b;*b=r;

}

int main(){

int x=1,y=5;

Change(&x,&y);

A &x  
B &y  
R    

cout<<”x=”<<x<<”y=”<<y;

return 0;

}

выведется: x = 5 y = 1, теперь значения переменных обменялись

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

void Change(int &a,int &b){

int r=a;a=b;b=r;

}

int main(){

int x=1,y=5;

Change(x,y);

A &x  
B &y  
r    

cout<<”x=”<<x<<”y=”<<y;

return 0;

}

выведется: x = 5 y = 1, значения переменных обменялись

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

 

12.4. Локальные и глобальные переменные

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

int*f()

{

int a;

....

return&a;// НЕВЕРНО

}

Глобальные переменные – это переменные, описанные вне функций. Они видны во всех функциях, где нет локальных переменных с такими именами.

Пример:

int a,b;//глобальные переменные

void change()

{

int r;//локальная переменная

r=a;a=b;b=r;//a,b - глобальные

}

void main()

{

cin>>a,b;

change();

cout<<”a=”<<a<<”b=”<<b;

}

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

 

Функции и массивы

Date: 2016-11-17; view: 278; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию