упражнение №3

Функции

 

1.   Дефиниране на функции

Основната програмна единица в С++ е функцията. Дефинирането на функции се подчинява на следния синтаксис:

    име на тип          име на функция ( списък на формални параметри )

{

оператори 

} 

Името на тип е всеки допустим за С++ тип. Той определя типът на функцията. Когато не се запише име на тип се подразбира int. Когато функцията не връща стойност се записва типът void.

Името на функцията се формира по всички правила за формиране на имена на променливи в С++.

В списъка на формалните параметри (аргументи) се дефинират параметрите чрез име на тип и име на променлива и се разделят със запетаи. Тип на формалните параметри може да бъде всеки от простите типове данни в С++. Формални параметри могат да бъдат и указатели към произволен тип данни. Сложните типове данни не могат да се предават като формални параметри на функция.

В тялото на функцията се дефинират локални променливи и оператори, изпълняващи алгоритъма на функцията. Изпълнението на функцията се прекратява при достигане на оператор return или при достигане на затварящата скоба на тялото на функцията. Когато функцията връща стойност израза, чиято стойност се връща  се записва след оператора return. Допустимо е в тялото на функцията да се включат няколко оператора return. Типът на върнатата стойност трябва да съответства на типа на функцията.

return     израз     ;

Примери

Функцията input не връща стойност и няма формални параметри.

void input(void)

{

  int i;

  cout<<”Въведете стойности за елементите на масива\n”;

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

  {

     cout<<”a[=”<<i<<”]=”; 

     cin>>a[i];

  }

}

Функцията change не връща стойност и има един формален параметър от тип int.

void change(int n)

{

  int i;

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

     if (a[i]<0) a[i]=-1;

}

Функцията GetMax връща стойност от тип float и има два формални параметъра от тип float. В тялото на функцията се среща два пъти оператора return, т.е. стойност се връща в две точки.

float GetMax(float x, float y)

{

  if (x>y) return x;

  else     return y;

}

Функцията Rp изчислява еквивалентното съпротивление на два паралелно свързани резистора със съпротивления съответно R1 и R2(R1 и R2се подават като формални параметри на функцията). Функцията връща -1, ако някое от съпротивленията има стойност 0, т.к. в математиката делението на 0 е недефинирана операция или   стойноста на израза, записан след втория оператор return.

float Rp(float R1, float R1)

{

  if (R1==0 || R2==0) return -1;

  else     return (R1+R2)/(R1*R2);

}

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

Формалните параметри и данните, дефинирани в тялото на функцията са дъстърни само за операторите на тази функция и са невидими за другите функции, включително и за гламната функция main.

G ВНИМАНИЕ! Функциите могат да получават като аргументи много стойности, но могат да връщат само една стойност.

 

2.   Деклариране на функции

При декларирането на функциите се задава само техният заглавен оператор (тип на върнатата стойност, име на функцията и списък на формалните параметри) без да се изписва тялото на функцията. Декларацията на функцията завършва с точка и запетая (;).  Имената на формалните параметри могат да не се записват, но техният тип се записва задължително.

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

Заглавният оператор се нарича още прототип. Прототипът на функцията декларира функцията преди тя да се използва и преди нейната дефиниция. Прототипът се състои от името на функцията, типът на резултата и списъкът с параметрите и. Той завършва с точка и запетая. Компилаторът трябва да знае тази информация, за да може правилно да изпълни обръщенията към функцията. Нека например да е дадена следната проста функция:

void myfunc(void)

{

printf("This is a test.");

}

Нейният прототип е

void myfunc(void);

Единствената функция, която няма нужда от прототип, е main( ), тъй като тя е предварително дефинирана от езика С.

 

Примери

#include <iostream.h>


void input(void);

void change(int n);

float GetMax(float x, float y);

float Rp(float R1, float R1);


 

или


void change(int);

float GetMax(float, float);

float Rp(float, float);


 

. . .

void main(void)

{

            . . .

}

 

3.   Извикване на функции

За да бъде извикана една функция, тя трябва да е дефинирана или декларирана в по-горна точка на програмата, т.е. в момента на извикване нейният профил трябва да бъде известен.  Извикването може да става многократно от тялото на коя да е функция.

Пример: Тази програма отпечатва на екрана 1 2 3:

/* Тази програма има три функции. */

#include <stdio.h>

void func1(void); /* прототипи */

void func2(void);

int main(void)

{

func2( );

printf("3");

return 0;

}

void func2(void)

{

func1( );

printf("2 ");

}

void func1(void)

{

printf("1 ");

}

 

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

При извикването на всички функции в обикновени скоби се задават фактическите параметри (променливи или константи, чиито стойности се присвояват на формалните параметри). Типът и броят на формалните и фактическите параметри трябва да съвпадат. Имената на формалните и фактическите параметри, когато последните са именовани,  могат да бъдат различни или еднакви. И в двата случая те се разглеждат като различни променливи, т.к. са дефинирани на различно ниво.

G ВНИМАНИЕ! Типът на фактическите параметри не се записва.

G ВНИМАНИЕ! Обикновените скоби се запазват дори когато функцията не получава аргументи, но в тях не се пише нищо. Обикновените скоби са най-характерната синтактична особеност на функциите, която ги отличава от операторите, променливите и другите синтактични категории в С++.

G ВНИМАНИЕ! Функциите не могат да участват от лявата страна на оператора за присвояване.

Пример

Функцията input не връща стойност, поради което може да бъде използвана единствено като оператор на езика. Тя няма аргументи, но задължително се пише с обикновени скоби.

input();

Функцията change също не връща стойност и също  може да бъде използвана единствено като оператор на езика. Тя може да получава като аргумент константна стойност, променлива с различно или същото име.

1)  change(10);

2)  int br=10;

  change(br);

3)  int n;

  cin>>n;

  change(n);

Функцията GetMax връща стойност и може да бъде използвана като оператор на езика и като операнд във израз. В случая абаче самостоятелната й употреба няма смисъл.

1)  max=GetMax(4.5, 7.2);

2)  float a,b;

. . .

max=GetMax(a, b);

3)  float b;

. . .

max=GetMax(1, b);

4)  cout<<”Max=”<< GetMax();

Функцията Perform преобразува всички отрицателни числа на един масив в нули и връща броя на преобразуванията. При извикване тази функция може да се използва както като самостоятелен оператор така и в израз.

Дефиниция:

int Perform(void)

{

      int i, br;

      for(i=0,br=0;i<n;i++)

          if (a[i]<0)

          {

            a[i]=0;

            br++;

          }

      return br;

}

Извикване І вариант:

Perform();

Извикване ІІ вариант:

int x=Perform();

 

Задача:  Да се напише програма на С++, която въвежда от клавиатурата 3 масива и изчислява и извежда сумите им по двойки. Програмата да не използва глобални променливи и предаването на масивите да стане чрез указатели. Да се използват динамични масиви.

 

 

Решение

 

#include <iostream.h>

#include <stdlib.h>

 

void input(int k,float *s)

{ int i;

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

    {  cout<<"el["<<i<<"]=";

       cin>>s[i];

    }

}

   void output(int br,float *s)

   { int i;

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

 

     cout<<s[i]<<'\n';

 

   }

void main(void)

{

            int n,i;

            float *a;

            float *b;

            float *c;

            float *d;

            float *e;

            float *f;

 

            cout<<"n="; cin>>n;

                                    a=new float[n];

                                    b=new float[n];

                                    c=new float[n];

                                    d=new float[n];

                                    e=new float[n];

                                    f=new float[n];

 

     cout<<"vavedete el na mas. A \n";

    input(n,a);

      cout<<"vavedete el na mas. B \n";

    input(n,b);

      cout<<"vavedete el na mas. C \n";

    input(n,c);

 

 

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

      d[i]=a[i]+b[i];

      cout<<"mas d"<<'\n';

      output(n,d);

 

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

            e[i]=b[i]+c[i];

            cout<<"mas e"<<'\n';

            output(n,e);

 

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

      f[i]=a[i]+c[i];

      cout<<"mas f"<<'\n' ;

            output(n,f);

delete []a;

delete []b;

delete []c;

delete []d;

delete []e;

delete []f;

 

}

 

 

 

 

 

 

ЗАДАЧИ ЗА САМОСТОЯТЕЛНА РАБОТА

При решаването на долните задачи да не се използват глобални променливи, масивите да се създават динамично и да се използват указатели.

Œ        Да се намери и изведе на екрана средната аритметична стойност на четните елементи на даден масив А от  N цели числа (N£100). При решаването на задачата да се оформят 2 подпрограми.

        Към всеки елемент на даден масив А от N цели числа (N£100) да се добави неговият индекс. Преобразуваният масив да се изведе на екрана. При решаването на задачата да се оформят 3 подпрограми.

Ž        По дадени два едномерни числови масива A и B с еднаква дължина N (N£100), да се генерира трети масив С, за който Ci=max(Ai,Bi), i=1,2,…,N. При решаването на задачата да се оформят 3 подпрограми.

        Да се намерят и изведат на екрана минималните числови стойности на всеки ред на дадена матрица А с N реда и M колони, (N£100; M£100). За решаването на задачата да се използват подпрограми.

        Да се разменят местата на два реда на дадена  целочислена матрица А с N реда и M колони, (N£100; M£100). Номерата на редовете за размяна да се задават от клавиатурата. За решаването на задачата да се използват подпрограми.

   Да се намери лицето на изпъкнал петоъгълник по зададени координати на върховете (фиг. 6.9).

         

à   Ä   Ç