Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Изучение Си после Паскаля.rtf
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

Функции с параметрами

Рассмотрим функции с параметрами на примере. Нужно написать функцию, вычисляющую значение , где a и n – целые числа. Решим эту задачу «в лоб», используя многократное умножение в цикле:

Реализация на Паскале:

{ Функция, вычисляющая и возвращающая a^n }

{ ^ - возведение в степень}

function power(a, n: integer):longint;

var

res : longint; { Результат (степень) }

i : integer;

begin

res := 1;

for i := 1 to n do

res := res * a;

power :=res; { Возвращаем значение из функции }

end;

var

x, n: integer;

begin

x := power(2, 3); {x = 2 ^ 3 = 8}

n := 2;

writeln(x, ' ^ ', n, ' = ', power(x, n));

{Будет выведено: 8 ^ 2 = 64}

end.

Реализация на Си:

#include <stdio.h>

//Функция, вычисляющая и возвращающая a^n

//^ - возведение в степень

long power(int a, int n)

{

long res = 1;

int i;

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

res *= a;

return res; // Возвращаем значение res

}

int main()

{

int x = power(3, 2); // x = 3 ^ 2 = 9

int n = 5;

printf("\n %d ^ %d = %ld\n", x, n, power(x, n));

// Будет выведено: 9 ^ 2 = 81

return 0; // Возвращаем значение 0

}

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

ТИП_ВОЗВРАЩАЕМОГО_ЗНАЧЕНИЯ ИМЯ_ФУНКЦИИ(СПИСОК_ПАРАМЕТРОВ)

{

ТЕЛО_ФУНКЦИИ

}

Список параметров представляет собой параметры, разделенные запятыми. Каждый параметр имеет вид:

ТИП_ПАРАМЕТРА ИМЯ

В нашем примере функция power имеет два целых параметр: a и y. Параметры в Си также называют аргументами.

Способы передачи параметров в подпрограммы

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

В Паскале параметры в подпрограммы могут передаваться либо по значению, либо по ссылке. При передаче параметра по значению в подпрограмму передается значение фактического параметра. В этом случае фактическим параметром может быть выражение. Перед передачей в подпрограмму вычисляется значение выражения, и именно это вычисленное значение передается. В подпрограмме это значение можно спокойно изменять – изменения не затронут фактический параметр. При передаче параметра по ссылке на самом деле в подпрограмму передается адрес изменяемой переменной. В этом случае фактическим параметром может быть только какая-нибудь переменная, но не составное выражение (!). Все действия в подпрограмме с таким параметром на самом деле производятся над полученным фактическим параметром. Для обращения к нему используется переданный адрес переменной. Передача по ссылке в Паскале может быть объявлена либо var (параметры-переменные), либо const (параметры-константы).

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

Рассмотрим вопросы передачи параметров на следующем примере.

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

Типичное решение этой задачи на Паскале:

{

Процедура делит a на b.

В c заносится частное, в d – остаток от деления.

}

procedure divide(a, b: integer; var c, d: integer);

begin

c := a div b;

d := a mod b;

end;

var

x1, x2, y1, y2: integer;

begin

x1 := 13;

x2 := 3;

divide(x1, x2, y1, y2);

writeln(x1, ' div ', x2, ' = ', y1);

writeln(x1, ' mod ', x2, ' = ', y2);

end.

В этом решении используются параметры-переменные.

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

Пример решения:

type

PInteger = ^ Integer; {Указатель на целое число}

{Процедура делит a на b.

В c заносится частное, в d – остаток от деления.

C и D – указатели на изменяемые в процедуре переменные

}

procedure divide(a, b: integer; c, d: PInteger);

begin

c^ := a div b;

d^ := a mod b;

end;

var

x1, x2, y1, y2: integer;

begin

x1 := 13;

x2 := 3;

{В divide передаются указатели на y1 и y2}

divide(x1, x2, @y1, @y2);

writeln(x1, ' div ', x2, ' = ', y1);

writeln(x1, ' mod ', x2, ' = ', y2);

end.

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

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