Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tekhnologia_programmirovania.pdf
Скачиваний:
182
Добавлен:
08.04.2015
Размер:
1.76 Mб
Скачать

887

7.3.Автоматические и статические переменные

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

Если необходимо сохранить значения локальных переменных внутри функции, их следует объявить статическими с использованием ключевого слова static. В программе 15 функции fauto и fstat увеличивают на 1 свою локальную переменную k и возвращают ее значение.

Программа 15. Автоматические и статические переменные

// Файл AutoStat.cpp

 

int fauto ()

 

{

 

int k = 0;

// Автоматическая локальная переменная

return ++k;

 

}

 

int fstat ()

 

{

 

static int k = 0;

// Статическая локальная переменная

return ++k;

 

}

 

#include <iostream.h>

 

#include <conio.h>

 

void main()

 

{

 

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

// 10 раз вызываем fauto

cout << fauto() << ” ”;

 

cout << "\n";

 

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

// 10 раз вызываем fstat

cout << fstat() << ” ”;

 

getch();

 

}

 

Функции 89

Программа выводит:

1 1 1 1 1 1 1 1 1 1

1 2 3 4 5 6 7 8 9 10

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

Все переменные внутри функции являются автоматическими по умолчанию, но можно явно указать на это, используя ключевое слово

auto:

auto int k = 0;

// Автоматическая переменная

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

int power(int m, int n)

// Возведение m в степень n

{

 

int p = 1;

 

while(n-- > 0)

 

p = p * m;

 

return p;

 

}

 

Здесь в заголовке цикла while текущее значение n сравнивается с нулем и затем уменьшается на 1. Но изменение параметра n внутри функции никак не повлияет на фактический аргумент. Инструкция

cout << power(3, 2);

напечатает 9.

Использование параметров функции позволяет обойтись меньшим числом переменных.

907

7.4.Прототипы функций

Прототипом функции называется ее предварительное объявление. Прототип имеет вид:

тип-результата имя-функции(объявления аргументов);

то есть состоит из заголовка функции и точки с запятой. Например, для функции возведения в степень прототип имеет вид:

int power(int m, int n);

Имена аргументов в объявлении (прототипе) функции можно не указывать и писать:

int power(int , int);

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

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

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

7.5. Массивы как аргументы функций

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

Итак, запомним, если массив является аргументом функции, его элементы можно изменить внутри функции.

Функции 91

7.6. Внешние переменные

Внешние переменные определяются вне любой функции, благодаря чему они могут быть доступны любой функции программы. Память под внешние переменные выделяется в момент начала выполнения программы, поэтому они существуют в течение всего времени ее работы. Внешние переменные могут быть доступны по именам из любой функции. Чтобы внешняя переменная была доступна внутри функции, она должна быть в ней объявлена. Объявление начинается ключевым словом extern. Внешняя переменная доступна без дополнительных описаний во всех функциях, расположенных после ее объявления ниже по тексту программы. Пример использования внешних переменных приведен в программе 16.

Программа 16. Сортировка массива

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

Впрограмме надо выполнить действия:

1)заполнить массив значениями;

2)распечатать исходный массив;

3)отсортировать массив;

4)распечатать упорядоченный массив.

Заполнение, печать и сортировку массива реализуем в виде отдельных функций.

Массив для сортировки и его максимальный размер объявляются в начале программы как внешние переменные, а определяются в ее конце. Размер массива задается константой SIZEARR достаточно большого размера, чтобы выделенной под массив памяти хватило в большинстве случаев использования программы. Конкретный размер массива вводится пользователем и проверяется на допустимость. При вводе недопустимого размера массива вызывается функция

void exit(int k),

которая завершает работу программы и возвращает в вызывающую программу значение своего аргумента. Эта функция объявлена в stdlib.h.

Для заполнения массива числами в программе предусмотрена функция

void get_array(int x[], int n);

92 7

В ней элементам массива x присваиваются случайные целые значения, генерируемые функцией стандартной библиотеки

int rand(),

объявленной в stdlib.h. Функция rand возвращает псевдослучайное число в диапазоне от 0 до RAND_MAX. Величина RAND_MAX определяется в файле stdlib.h. Обычно это 32767.

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

void randomize(void);

которая инициализирует генератор случайных чисел, связывая первое случайное число с показаниями системных часов. Эта функция объявлена также в stdlib.h.

Для сортировки массива по возрастанию написана функция: void bubble_sort(int x[], int n);

использующая алгоритм «пузырька», состоящий в следующем. Организуется проход по массиву, в котором сравниваются соседние элементы и, если предшествующий элемент оказывается больше следующего, они меняются местами. В результате первого прохода наибольший элемент оказывается на своем, последнем месте («всплывает»). Затем проход по массиву повторяется до предпоследнего элемента, затем до третьего с конца массива и т.д. В последнем проходе по массиву сравниваются только первый и второй элементы.

//Файл SortArr.cpp

//Сортировка массива #include <iostream.h> #include <conio.h>

//Объявление внешних переменных

extern int x[];

// Объявление массива

extern const int SIZEARR;

// Объявление размера массива

// Объявления функций

 

void get_array(int[], int n);

// Заполнение массива из n элементов

void bubble_sort(int[], int n);

// Сортировка массива методом пузырька

void prn_array(int[], int n);

// Вывод массива

#include <stdlib.h>

// Для exit, rand и randomize

int main()

 

{

 

int n;

// Размер массива

 

Функции

93

 

 

cout << "\nВведите размер массива < " << SIZEARR << ": ";

 

cin >> n;

 

 

if(n > SIZEARR || n<=0){

// Проверка размера

 

cout << "Размер массива " << n << "не подходит \n";

 

exit(1);

// Завершение программы

 

}

 

 

get_array(x, n);

// Заполнение массива

 

cout << "Исходный массив: \n";

 

 

prn_array(x, n);

// Вывод исходного массива

 

bubble_sort(x, n);

// Сортировка

 

cout << "\nОтсортированный массив: \n";

 

prn_array(x, n);

// Вывод упорядоченного массива

 

getch();

 

 

return 0;

 

 

}

//Определение функций

//get_array: заполняет массив x случайными числами void get_array(int x[], int n)

{

int i;

// Локальная переменная

randomize();

// Инициализация генератора случайных чисел

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

 

x[i] = rand();

// rand генерирует целое случайное число

}

//prn_array: вывод массива void prn_array(int x[], int n)

{

int i;

for(i = 0; i < n; i++) cout << x[i] << ", ";

}

//bubble_sort: сортировка массива x методом пузырька void bubble_sort(int x[], int n)

{

int i, j, tmp;

for(i = n - 1; i > 0; i--)

// i задает верхнюю границу

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

// Цикл сравнений соседних элементов

if(x[j] > x[j + 1]){

// Если нет порядка,

tmp = x[j];

// перестановка местами

x[j] = x[j + 1];

// соседних

x[j + 1] = tmp;

// элементов

}

 

}

// Определение внешних переменных