1.  Краткие теоретические сведения

 

 

1.1. Функции

 

Функцию в Си можно рассматривать:

·      как один из производных типов данных (наряду с массивами и указателями);

·      как минимальный исполняемый модуль программы (подпрограмму).

     Все функции имеют единый формат определения:

 

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

<тело_функции> , где

 

<тип> - либо void, если функция не возвращает значения, либо тип возвращаемого функцией значения;

 

<имя_функции> - либо main для основной функции, либо произвольный идентификатор, не совпадающий со служебными словами и именами других объектов программы;

 

<список_формальных_параметров> - либо пустой ( ), либо список, каждый элемент которого имеет вид:

 

<обозначение_типа><имя_параметра>

 

 

Например:

(int k )

(char i, char j, int z)

 

<тело_функции>  - это часть определения функции, заключенная в фигурные скобки { }.Тело функции может быть либо составным оператором, либо блоком. Определения функций не могут быть вложенными.

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

1)  return; - завершает функцию возвращающую никакого значения (т. е.  перед именем функции указан тип void)

2)  return <выражение>; - возвращает значение выражения, выражение должно иметь тип, указанный перед именем функции.

3)   

Если программист не пишет оператор return явно, то компилятор автоматически дописывает return в конец тела функции перед закрывающей фигурной скобкой}.

 

Пример:

int op (char c, int x, int  y)

{

switch c

{

case ‘+’ : return x+y;

case ‘-’ : return x-y;

case ‘*’ : return x*y;

case ‘/’ : return x/y;

default: cout<<“\nОперация не определена”;return 0;

}

}

 

Вызов  функции осуществляется следующим образом:

 

<обозначение функции>(<список фактических параметров>); где

 

<обозначение функции> - либо имя функции, либо указатель на функцию;

 

<список фактических параметров> - список выражений, количество которых равно числу формальных параметров функции. Между формальными и фактическими параметрами должно быть соответствие по типам.

 

Например:

c = op ( ‘+’, 5 ,4 );

 

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

 

Пример (ошибка!!!):

1)

//описание функции для обмена переменных а и b

void change (int a,int b)

{

int r;

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

}

// вызов функции

change(a, b);

 

Обмена не произойдет, т. к. результат не будет передан в вызывающую программу.                 

 

2)

void change (int *a,int *b)

{

int r;

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

}

// вызов функции

change(&a, &b);

При вызове передаются адреса, по которым находятся значения и выполняется обмен значений, которые находятся по этим адресам.

 

 

1.2. Массивы и строки как параметры функций

    

 

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

Пример:

//вычисление суммы элементов массива

//вариант 1

int sum (int n, int a[] )

{

int i,int s=0;

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

       s+=a[i]

   return s;

}

void main()

{

 int a[]={ 3, 5, 7, 9, 11, 13, 15 };

 int s = sum( 7, a );

 cout<<s;

}

 

//вариант 2

int sum (int n, int *a)

{

for(int i=0, s=0; i<n; s+=*(a+i),i++ );

return s;

}

void main()

{

 int a[]={ 3, 5, 7, 9, 11, 13, 15 };

 int s = sum( 7, a );

 cout<<s;

}

     Строки в качестве фактических параметров могут быть определены либо как одномерные массивы типа char[], либо как указатели типа char*.  В отличие от обычных массивов в этом случае нет необходимости явно указывать длину строки.