Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МП_С / Лабор6.doc
Скачиваний:
8
Добавлен:
05.06.2015
Размер:
114.69 Кб
Скачать

7

Лабораторная работа № 6 Программирование с использованием функций

Цель работы: 1) изучить правила описания функций;

2) приобрести навыки использования функций при написании программ на языке C.

Теоретические сведения

Функции – это базовые блоки С, в которых выполняются все операции. Стандартный вид функции следующий:

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

{

тело функции

}

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

Оператор return

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

Выход из функции

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

void pr_reverse(char *s)

{

register int t;

for(t=strlen(s)-1; t > -1; t--) printf(“%c”,s[t]);

}

После отображения строки функция ничего не делает, поэтому управление передаётся вызвавшему её коду.

Тем не менее, не многие функции используют данный метод окончания своего выполнения. Большинство функций используют оператор return для окончания выполнения с целью возврата значения или упрощения кода функции и увеличения его эффективности путём создания нескольких точек выхода. Например, функция, показанная ниже, возвращает или индекс первого появления подстроки, указываемой в s2, в строке, указываемой в s1, или -1, если не обнаружено совпадений:

int find_substr(char *s1, char *s2)

{

register int t;

char *p, *p2;

for(t=0; s1[t]; t++) {

p = &s1[t];

p2 = s2;

while(*p2 && *p2==*p) {

p++;

p2++;

}

if(!*p2) return t;

}

return –1;

}

Надо обратить внимание, как два оператора return упрощают функцию.

Возвращаемые значения

Все функции, кроме функций типа void, возвращают значения. Данное значение определяется в операторе return. Если функция не определена как void и если не указано возвращаемое значение, то возвращается случайное значение. Если функция не объявлена как void, она может использоваться в качестве операнда в любом корректном выражении. Следовательно, каждое из следующих выражений корректно:

x = power(y);

if (max(x, y) > 100) printf(“greater”);

for(ch=getchar(); isdigit(ch); )…;

Тем не менее функция не может стоять с левой стороны оператора присваивания. Оператор типа

swap(x, y) = 100;

неправилен. Компилятор выдаст ошибку.

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

Аргументы функции

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

/* возвращает 1 в случае, если с является частью строки s; в противном случае возвращается 0*/

int is_in(char *s, char c)

{

while(*s)

if(*s==c) return 1;

else s++;

return 0;

}

Передача по значению и передача по ссылке

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

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

Создание передачи по ссылке

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

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

void swap(int *x, int *y)

{

int temp;

temp = *x;

*x = *y;

*y =temp;

}

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

#include <stdio.h>

void swap(int *x, int *y);

int main(void)

{

int x, y;

x = 10;

y = 20;

swap(&x, &y);

printf(“%d %d”, x, y);

return 0;

}

Передача массивов в функции

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

#include <stdio.h>

void display(int num[10]);

int main(void)

{

int t[10], i;

for(i=0; i<10; i++) t[i]=i;

display(t);

return 0;

}

void display(int num[10])

{

int i;

for(i=0; i<10; i++) printf(“%d “, num[i]);

}

Хотя параметр num объявляется как целочисленный массив из десяти элементов, С автоматически преобразует его к указателю на переменную целого типа, поскольку не существует параметра, который мог бы принять весь массив.

Следующий способ состоит в объявлении параметра для указания на безразмерный массив, как показано ниже:

void display(int num[])

{

int i;

for(i=0; i<10; i++) printf(“%d “, num[i]);

}

Последний способ, которым может быть объявлен num, - через указатель.

void display(int *num)

{

int i;

for(i=0; i<10; i++) printf(“%d “, num[i]);

}

Соседние файлы в папке МП_С