Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций по курсу 'Информатика'.doc
Скачиваний:
11
Добавлен:
14.07.2019
Размер:
483.84 Кб
Скачать

Подпрограммы.

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

Все программы на С состоят из подпрограмм, с главной подпрограммой - main() мы уже встречались. Она выглядит так:

main()

{

операторы реализующие алгоритм.

}

Первая строка – заголовок функции далее в{} ее тело.

main – имя подпрограммы, в скобках перечень параметров, в данном случае отсутствует.

Иначе заголовок главной функции можно записать так:

void main( void )

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

main()

Поэтому при таком оформлении функции транслятор требует оператор - return 1 ;

Описание подпрограммы, в общем виде, выглядит так:

тип результата ИМЯ( тип параметр1,тип параметр2,…тип параметрК)

{ формальные параметры

тело

return результат ;

}

Если нет результата, а есть эффект, то в теле функции нет оператора return.

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

ИМЯ( параметр1, параметр2,… параметрК)

фактические параметры

Например следующие вызовы стандартных функций:

scanf (“%d”, &a) ; // вызов функции самостоятельный оператор, у нее нет результата.

h=strlen(text) ; // результат выполнения функции присваивается переменной.

printf (“%d”, strlen(text)) ; // два вызова разных функций, один внутри другого.

Выполняется правило - формальные и фактические параметры соответствуют друг другу по количеству, типу и порядку следования.

Как располагаются подпрограммы друг относительно друга? Существуют два разных варианта.

#include< > #include< >

int func( int a) // подпрограмма int func( int ) ; // декларация

{ main() // главная программа

int b ; {

… int k, s ;

return b ; …

} k=func(s) ;

main() // главная программа }

{ int func( int a) // подпрограмма

int k, s ; {

… int b ;

k=func(s) ; …

… return b ;

} }

Для чего нужны подпрограммы? Они реализуют два важнейших принципа программирования:

- модульность

- повторяемость

Модульность это возможность разбивать программу на небольшие логически законченные фрагменты.

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

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

В таких случаях каждый раз вызывается одна и та же подпрограмма.

Рассмотрим простейшие подпрограммы.

Заданы 2 целых числа, используя подпрограмму, определить максимальное из них.

#include<stdio.h>

int max( int a , int b)

{

if( a>b ) return a ;

else return b ;

}

main()

{

int m , n , maxim ;

scanf (“%d” , &m ) ;

scanf (“%d” , &n ) ;

maxim=max( m , n ) ; // вызов функции max

printf (“максимальное число = %d “ , maxim ) ;

}

Заданы два целых числа, поменять местами их значения.

#include<stdio.h>

void change ( int a , int b )

{

int x ;

x=a ; a=b ; b=x ; // обмен значениями а и b через промежуточную переменную – х.

}

main ()

int a=5 , b=10 ;

printf (“%d %d” , a , b ) ;

change (a , b) ;

printf (“\n%d %d” , a , b ) ;

}

На экране вы увидите неожиданную вещь:

5 10

5 10

Значения переменных не переставляются! Где же ошибка? Если вставить печать в функцию change, то увидим, что там все в порядке и значения a и b переставляются. Почему же в main не изменилось ни чего? Для того чтобы это понять, нужно знать, как осуществляется движение информации в подпрограмму и обратно. Разберемся в этом..

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

Исправим эту ошибку. В главной функции main изменится только вызов функции:

change (&a , &b) ;

что означает передать в подпрограмму не значения переменных –а и b, а их адреса.

Функция будет выглядеть по другому:

void change ( int *a , int *b )

{

int x ;

x=*a ; *a=*b ; *b=x ; // перестановка значений в главной программе через их адреса.

}

В этом случае работа в подпрограмме change производится не с формальными параметрами, а с фактическими через их адреса, т.е. из функции change мы ссылаемся на место в памяти отведенное на а и b в main.

Интересные примеры работы с подпрограммами при использовании векторов и матриц.

Обнулить вектор при помощи функции.

#include<stdio.h>

void arrz ( int [] , int) ; // декларация функции

void main ( void )

{

int arr[10] , i ;

for ( i=0 : i<10 ; i++)

scanf (“%d” , &arr[i]) ;

arrz ( arr ,10) ; // вызов функции

for ( i=0 : i<10 ; i++)

printf (“%d” , &arr[i]) ;

}

void arrz ( int array[] , int num) // заголовок функции

{

int i ;

for ( i=0 : i<num ; i++)

array[i]=0 ;

}

В данном случае функция arrz тоже работает с адресом вектора arr[10], расположенного в main. И обнуляет она именно его, поэтому функция arrz не имеет результата, а имеет эффект.

При работе с матрицей в подпрограмме нужно соблюдать большую осторожность. Необходимо указывать структуру матрицы, хотя бы в одном индексе array[10][], или работать через адрес, для матрицы этот формальный параметр будет выглядеть так int **array. Подробнее об этом можно прочесть у Т.А. Павловской, С/С++ программирование на языке высокого уровни, С-П, 2001, стр.78.

Рассмотрим пример: каждую из произвольного количества матриц разной размерности транспонировать.

#include<stdio.h>

void mtran( int matr[10][], int n )

{

int i, j, k ;

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

for ( j=i+1 ; j<n ; j++)

{

k=matr[i][j] ;

matr[i]j]=matr[j][i] ;

matr[j]i]=k ;

}

}

void main (void)

{

int arr[10][10], i, j, k, n ;

do // цикл для обработки произвольного количества матриц «пока не надоест»

{

printf(“ введите размерность матрицы “) ;

scanf(“%d” , &n );

printf(“ введите матрицу \n “) ;

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

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

scanf(“%d” , &arr[i][j] );

mtran( arr, n ) ; // вызов функции, транспонирующей матрицу

printf(“ транспонированная матрица \n“) ;

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

{

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

printf(“%d” , arr[i][j] );

printf(“ \n“) ;

}

printf(“ повторить? 1-да, 0-нет “) ;

scanf(“%d” , &k );

while (k==1) ;

}

}