- •О.Ф.Власенко, и.В.Беляева изучение си после паскаля: циклы, развилки, функции, обработка одномерных массивов
- •Оглавление
- •Вывод в языке си Простейшая программа «Привет, мир!»
- •Функция printf – форматированный вывод
- •Циклы в языке си «Привет, мир!» 100 раз
- •Цикл с предусловием в Паскале и Си
- •Цикл с постусловием в Паскале и Си
- •Цикл for в Паскале и Си
- •Задачи средней сложности
- •Задачи сложные
- •Задачи простые
- •Функции в языке си Локальные и глобальные переменные
- •Функции без параметров в Си
- •Функции с параметрами
- •Способы передачи параметров в подпрограммы
- •Работа с указателями: операции взятия адреса и разыменования адреса
- •Ввод в языке си Функция getch – ввод символа
- •Функция scanf - форматированный ввод
- •Развилки Пример задачи: размер файла в байтах
- •Усеченные развилки
- •Полные развилки
- •Варианты для простых заданий и для заданий средней сложности
- •Задания среднего уровня сложности
- •Рекуррентные соотношения для вычисления корней
- •Разложение в ряд некоторых функций
- •Пример выполнения лабораторной работы по заданиям среднего уровня сложности
- •Сложные задания
- •Пример выполнения лабораторной работы по сложным заданиям
- •Варианты для сложных заданий
- •Организация меню. Управляющая структура Выбор (switch) Организация простейшего меню
- •Массивы в си Объявление и инициализация одномерных массивов в Си
- •Вычисление адреса элемента массива
- •Адресная арифметика
- •Имя массива является указателем на нулевой элемент массива
- •Передача массива в функцию через параметр
- •Примеры обработки массивов в Си
- •Задание для лабораторной работы по теме «Обработка одномернЫх массивОв» Цель работы
- •Общее задание
- •Пример выполнения лабораторной работы
- •Задачи простые
- •Задачи средней сложности
- •Задачи сложные
- •Список литературы
- •Изучение си после паскаля: циклы, развилки, функции, обработка одномерных массивов
- •432027, Г. Ульяновск, Сев. Венец, 32.
Функции с параметрами
Рассмотрим функции
с параметрами на примере. Нужно написать
функцию, вычисляющую значение
,
где 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.
Второй пример выглядит более сложным, чем первый, но работает он так же, как и первый.
Поскольку в Си нет передачи параметров по ссылке, то в случае необходимости изменять параметры внутри функции нужно в функцию передавать указатель на изменяемый параметр. То есть передачу параметров нужно производить по схеме, продемонстрированной в последнем примере. Но прежде чем приводить решение поставленной задачи на Си мы должны разобраться с операциями над указателями.
