Распределение памяти при использовании функций

Распределение памяти компьютера

Когда вы запускаете программу, операционная система выделяет для нее различные области оперативной памяти, такие как область глобальных имен, область кода программы, регистры процессора, свободную память и стековую память. Глобальные переменные программы размещаются в области глобальных имен. Регистры – специальная область очень быстродействующей и дорогой по стоимости памяти, встроенная в центральный процессор. Существуют специальные регистры, называемые указателем команд (Instructions Pointer). В области кода программы находятся двоичные команды (машинные инструкции), созданные компилятором из исходного текста программы. Каждая инструкция имеет определенный адрес. В указателе команд хранится адрес следующей инструкции, которую должен выполнить процессор.

Стек – специальная область памяти, выделенная программе для хранения данных, необходимых каждой функции программы. Когда данные помещаются в стек («заталкиваются» - push) – стек растет; по мере извлечения («выталкивания» - pop) данных из стека - стек сокращается. Данные можно помещать/брать только на вершине стека. Стек похож на стопку монет (тарелок), т.е. чтобы взять самую нижнюю монету, нужно снять сначала все верхние. Размер стека ограничен. Его величину можно изменять при компоновке программы.

Вот что происходит, когда программа переходит к выполнению функции:

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

2. В стеке выделяется место для объявленного типа возвращаемого значения. Например, если функция объявлена возвращающей int, то два байта добавляются в стек, но никакое значение туда не помещается. Если функция объявлена как void, то место для возвращаемого значения в стеке не выделяется.

3. Адрес вызываемой функции помещается в регистр указателя команд процессора, поэтому следующая выполняемая инструкция будет инструкцией из вызванной функции.

4. В стеке выделяется место для всех параметров функции и ее локальных переменных.

 

Когда функция завершает свою работу, то выполняются следующие действия:

 

1. Возвращаемое значение помещается в зарезервированное в стеке место для хранения результата.

2. Из стека выталкиваются и становятся недоступными локальные переменные и параметры функции.

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

4. Адрес следующей за функцией инструкции, запомненный в стеке в момент ее вызова извлекается и помещается в указатель команд и программа продолжает свою работу.

 

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

 

Практические задания

 

1.

-b ±Öb2-4ac 2a
x1,2 =
Вычислить корни квадратного уравнения вида ax2+bx+c=0 по формуле

 

 

2.

a=Ö b2+c2-2bc cos a
Вычислить третью сторону треугольника, если известны две другие и угол между ними в градусах по формуле

 

 

3.

distance=Ö (x1-x2)2 + (y1-y2)2
Напишите программу, запрашивающую у пользователя декартовы координаты двух точек (x1,y1) и (x2,y2) с клавиатуры, вычисляющую и печатающую расстояние между ними по следующей формуле:

 

 

4.

 
Записать на С++ следующие формулы

 
 

 


5. Напишите программу, определяющую большее из трех случайных чисел.

6. Введите с клавиатуры число в буфер программы - строку С-стиля. Преобразуйте строку в целое, длинное целое и вещественное. Выведите числа на экран.

7. Реализуйте набор личных функций tolowerR(ch), toupperR (ch), isalphaR(ch), islowerR(ch), isupperR(ch), isalnumR(ch) для работы с символами русского алфавита.

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

9. Напишите прототип функции с именем Perimeter(), которая возвращает беззнаковое длинное целое и принимает два параметра типа int.

10. Напишите определение функции Perimeter(), вычисляющую периметр прямоугольника.

 

11. Что неверно в следующем фрагменте?
#include <iostream.h>
void myFunc (int x);
void main()
{
int x, y; y = myFunc(int);
}
void myFunc (int a)
{
return 4*a;
}

12. Напишите функцию, возвращающую частное от деления двух целых чисел. Если второе число 0, то деление не выполняйте и верните –1.

13. Напишите драйвер (main - фукцию) для проверки функции п.4.

14. Напишите и проверьте функцию, возвращающую истину, если с клавиатуры введены символы ‘Y’, ‘y’, ‘д’, ‘Д’ и ложь в противном случае.

15. Напишите и проверьте inline – функцию, возвращающую числовое значение переданного ей символа.

16. Напишите и проверьте работу void-функции для удваивания числа, используя механизм передачи параметров по значению. Убедитесь в неправильности ее работы.

17. Перепишите п.8, применив механизм С++ для передачи параметров по ссылке.

18. Напишите функцию для сложения двух чисел, имеющую одно значение по умолчанию.

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

Контрольные вопросы

1. Чем отличаются прототип функции и определение функции?

2. Должны ли совпадать имена параметров в прототипе, определении и вызове функции?

3. Как объявить функцию, если она не должна возвращать значение?

4. Если вы на объявите тип возврата, какой тип будет принят по умолчанию?

5. Сколько операторов return может быть в функции?

6. Что такое локальная переменная?

7. Что такое область видимости?

8. Почему бы не сделать все переменные глобальными?

9. Что такое параметры по умолчанию?

10. Что такое перегрузка (полиморфизм) функций?

11. Для чего применяются inline – функции?

12. Что такое рекурсия?

13. Какие два типа передачи параметров в функции применяются в информатике? Какая между ними разница?

14. Какие виды оперативной памяти необходимо различать прикладному программисту?

15. Что такое стек и стековая память?

16. Как работают функции?


 

Тема 6: Структуры. Классы и объекты.