
- •Лабораторная работа №4 Программирование пользовательских функций.
- •Теоретические сведения.
- •Время жизни и область видимости переменной.
- •Функции, общие понятия.
- •Использование переменных в функции. Локальные переменные.
- •Статические переменные.
- •Глобальные переменные.
- •Статические переменные.
- •Передача параметров в функцию
- •Передача параметров по значению
- •Передача массива в функцию
- •Примеры программирования.
- •Вопросы.
- •Варианты заданий. Общие требования.
Статические переменные.
Статические переменные, определенные в теле функции сохраняют свои значения между вызовами. Следующий пример демонстрирует разницу между локальными и статическими переменными, определенными в функции.
. . .
int g=10; // глобальная переменная
void plus1() // определение функции plus1()
{ static int k=0; // статическая переменная (сохраняется)
int p=10; // локальная переменная (уничтожается)
g=g+1;
p=p+1;
printf("Плюс %d: g=%d\tp=%d\n",k,g,p);
}
void main ()
{ setlocale(0,"Russian");
printf("начало: g=%d\n",g);
plus1();
plus1();
plus1();
. . .
}
В результате работы программы, на экране будет напечатано :
Начало : g=10
Плюс 1: g=11 p=11
Плюс 2: g=12 p=11
Плюс 3: g=13 p=11
. . .
Передача параметров в функцию
Параметры позволяют передать информацию из вызывающей программы в функцию. В теле функции параметрами можно пользоваться так же, как и локальными переменными. При вызове функции:
для каждого формального параметра создаётся локальная переменная;
начальными значениями созданных переменных являются фактические параметры, определяемые при вызове функции.
Пример 5:
int sum(int a, int b)
{ return a+b;
}
void main()
{ int x =5,y=10,z;
z = sum(x,y);
}
При вызове функции создаются две локальные a b переменные, которые инициализируются фактическими параметрами x y :
a=x
b=y
Передача параметров по значению
Во всех предыдущих примерах вызываемой функции передавались не сами переменные, а лишь их значения. При таком вызове функция не может изменить саму переменную в вызывающей программе, она может изменить лишь её временную копию (параметр), значение которой теряется при выходе из функции.
Пример 6: функция power() возводит base в n-ю степень.
#define dec 25
int power (int base, int n)
{ int p;
for (p = 1; n > 0; --n)
p = p * base;
return p;
}
void main()
{ i, p=0;
for(i=0 ; i<5 ; i++)
p=p+power(dec , i);
….
}
При вызове функции : base=dec, n=i
Обратите внимание, что бы мы ни делали с n внутри функции power(), это не окажет никакого влияния на переменную i в вызывающей программе.
Передача массива в функцию
Для того, чтобы организовать обработку массива при помощи функции, необходимо сообщить ей информацию об имени и размере массива, это можно сделать по-разному, например :
Передать массив определенного размера, определение функции:
int func (char s[100])
{ . . . }
Такое определение функции ограничивает её применение, обрабатываться будут только массивы размером 100.
Вызов функции :
int A[100];
func (A)
Передать массив неопределенного размера, определение функции:
int func (char s[], int n)
{ . . . }
Такое определение функции более предпочтительно, так как позволяет обрабатывать массивы произвольного размера. При этом первый параметр – имя массива, второй – его размер.
Вызов функции :
// Пример обработки массива в 100 элементов.
int A[100];
func (A, 100)
Примеры программирования.
Пример 7: Вычисление суммы массива.
В примере первый параметр определяет сам массив, а второй – его размер.
…
int summa (int array[ ], int n)
{ int res=0;
for (int i = 0; i < n; i++)
res+= array[i];
return res;
}
void main()
{// определение массива в 30 элементов
int mas[30];
// инициализация массива
for (int i = 0; i < 30; i++)
mas[i] = 2*i + 1;
// создание переменной s и вычисление суммы
int s = summa (mas, 30);
}
Пример 8: С помощью датчика случайных чисел создать матрицу вещественных чисел 5Х5, вывести на экран, найти минимальные элементы в строках и максимальные элементы в столбцах. Все действия с матрицей оформить в виде функций, создать следующие функции:
#include <stdio.h>
#include <time.h>
#include <windows.h>
#define raw 5 // количество строк
#define col 5 // количество столбцов
// ______область определения функций________________________
//функция для инициализации матрицы;
void initmatr(double M[raw][col])
{
int i, j;
for (i = 0; i < raw; i++)
for (j = 0; j < col; j++)
M[i][j] = rand() % 100 / 3.;
}
//функция для печати матрицы
void printmatr(double M[raw][col])
{
int i, j;
for (i = 0; i < raw; i++)
{
for (j = 0; j < col; j++)
printf("%7.3f\t", M[i][j]);
printf("\n");
}
}
// поиск минимального элемента в строке.
double rawmin(double M[raw][col], int traw)
{
double min;
int i;
for (i = 0, min = M[traw][0]; i < col; i++)
if (min > M[traw][i]) min = M[traw][i];
return min;
}
// поиск максимального элемента в столбце
double colmax(double M[raw][col], int tcol)
{
double max;
int i;
for (i = 0, max = M[0][tcol]; i < raw; i++)
if (max < M[i][tcol]) max = M[i][tcol];
return max;
}
//конец области определения функций____________________
void main()
{
setlocale(0, "Russian");
// область определения объектов (выделение памяти)
double MATR[raw][col], cmax;
int i;
srand(time(0));
initmatr(MATR);
printf("Исходная матрица:\n");
printmatr(MATR);
printf("Минимальные значения в строках:\n");
for (i = 0; i < raw; i++)
printf("%d строка - %7.3f\n", i + 1, rawmin(MATR, i));
printf("Максимальные значения в столбцах:\n");
for (i = 0; i < col; i++)
{
cmax = colmax(MATR, i);
printf("%d столбец - %4.3f\n", i + 1, cmax);
}
return 0;
}
Функции initmatr() и printmatr() не возвращают значений и имеют по одному параметру, определяющему матрицу.
Функции rawmin() и colmax() возвращают результат и имеют по два параметра, первый определяет матрицу, а второй обрабатываемую строку (столбец). Возвращаемое значение без запоминания выводится на экран, когда вызов функций rawmin() является параметром в функции printf(). Результат, возвращаемый функцией colmax() запоминается в переменной cmax, а затем выводится на экран.