ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Динамическое распределение памяти из кучи (heap).Часто бывает удобно создать новый объект, который существует до тех пор, пока он не станет ненужным. В частности, бывает удобно создать объект, который можно использовать после возврата из функции, где он был создан. (определение из лекции) Или Динамическое распределение памяти — способ выделения оперативной памяти компьютера для объектов в программе, при котором выделение памяти под объект осуществляется во время выполнения программы. (используется, если На момент написания программы известен только тип данных, не известен объем выделяемой памяти. В этом случае память должна выделяться в момент исполнения программы) Преимущества динам. распределения: · Гибкость использования · Часто бывает удобно создать новый объект, который существует до тех пор, пока он не станет ненужным · Бывает удобно создать объект, который можно использовать после возврата из функции, где он был создан. Недостатки: · Большие накладные расходы · Сложность использования 13. Отличие глобальных, статических и локальных переменных. С примерами. Область жизни и область видимости. Локальные переменные: Переменная, объявленная внутри функции, считается локальной, т.е. на неё можно ссылать только внутри данной функции. При любом присвоении вне функции, используется другая переменная, которая не имеет ничего общего, кроме имени, к переменной объявленной внутри функции. При выходе из функции, в которой объявлена локальная переменная, эта переменная уничтожается вместе со значением.
В первом примере, переменная статическая – память под неё выделяется сразу при загрузке программы и инициализируется нулем, а потом при каждом вызове функции f выделение памяти уже не происходит, поэтому изменяется старое значение статической переменной a. Во втором примере, при каждом заходе в функцию, для автоматической переменной a выделяется память и инициализируется нулем, поэтому пи каждом вызове функции f, мы видим, что она выводит “1”. Глобальные переменные: Глобальные переменные, в отличие от локальных, доступны в любой точке программы. Но чтобы изменить значение глобальной переменной, необходимо специально объявить её как глобальную. Глобальные переменные хранятся в отдельной фиксированной области памяти, созданной компилятором специально для этого. Глобальные переменные используются в тех случаях, когда разные функции программы используют одни и те же данные. Однако рекомендуется избегать излишнего использования глобальных переменных, потому что они занимают память в течение всего времени выполнения программы, а не только тогда, когда они необходимы. Кроме того, и это еще более важно, использование глобальной переменной делает функцию менее универсальной, потому что в этом случае функция использует нечто, определенное вне ее. К тому же большое количество глобальных переменных легко приводит к ошибкам в программе из-за нежелательных побочных эффектов. При увеличении размера программы серьезной проблемой становится случайное изменение значения переменной где-то в другой части программы, а когда глобальных переменных много, предотвратить это очень трудно. В следующем примере переменная count объявлена вне каких бы то ни было функций. Ее объявление расположено перед main(), однако, оно может находиться в любом месте перед первым использованием этой переменной, но только не внутри функции. Объявлять глобальные переменные рекомендуется в верхней части программы. #include <stdio.h> int count; /* глобальная переменная count */ void func1(void); void func2(void); int main(void) { count = 100; func1(); return 0; } void func1(void) { int temp; temp = count; func2(); printf("count равно %d", count); /* напечатает 100 */ } void func2(void) { int count; for(count=1; count<10; count++) putchar('.'); } Статические переменные: В отличие от переменных, объявленных параметрами и уничтожающимися при выходе из функции, статическая переменная сохраняет своё значение и при повторном вызове. Время жизни и область видимости объектов Время жизни – это части программы или вся программа, при выполнении которой переменная существует. Область видимости – это часть программы или вся программа, когда возможно получить доступ к объекту. В общем случае область видимости и время жизни не совпадают.
14. Автоматический стековый механизм распределения памяти. Используется ли стековый механизм для глобальных переменных? Стек – это область памяти, в которой хранятся локальные переменные и параметры функций. При вызове функции ее параметры и локальные переменные помещаются в стек. Стек функционирует по принципу стакана – значение, помещенное в стек первым, оказывается на дне стека, в то время как последнее значение – на вершине стека. По завершении работы функции все данные, принадлежащие этой функции, удаляются из стека. Очистка стека начинается с вершины, т. е. со значений, помещенных в стек последними;Скомпилированная программа С имеет четыре логически обособленные области памяти.Первая — это область памяти, содержащая выполнимый код программы. Во второй области хранятся глобальные переменные. Оставшиеся две области — это стек и динамически распределяемая область памяти. Стек используется для хранения вспомогательных переменных во время выполнения программы. Здесь находятся адреса возврата функций, аргументы функций, локальные переменные и т.п. Глобальные переменные хранятся отдельно!!!
15. Стековый механизм распределения памяти. Примеры и траектория вызова функций. Стек – это область памяти, в которой хранятся локальные переменные и параметры функций. При вызове функции ее параметры и локальные переменные помещаются в стек. Стек функционирует по принципу стакана – значение, помещенное в стек первым, оказывается на дне стека, в то время как последнее значение – на вершине стека. По завершении работы функции все данные, принадлежащие этой функции, удаляются из стека. Очистка стека начинается с вершины, т. е. со значений, помещенных в стек последними;
16. Отличие статических переменных от локальных. Статические переменные внутри функций: Время жизни от момента запуска до момента окончания программы-на протяжении выполнения всей программы. Область видимости: видна только внутри функции. Может быть перекрыта одноименными переменными во внутренних блоках {}, например, внутри цикла. Статические переменные объявляются директивой static. Они инициализируются только один раз - при первом вызове функции и сохраняют свое значение даже после выхода из функции. В следующий раз при новом вызове функции статические переменные будут иметь то же значение, которое они имели перед выходом из функции в послений раз.Статические переменные объявляются в пределах описания функции и поэтому доступны для использования только в пределах той функции, в которой они объявлены. Пример объявления статической переменной:int GetOpenPositionsNumber(){static int Count = 0;...}Локальные переменные – автоматические: Время жизни существуют от момента объявления до окончания того блока, в котором переменная объявлена. Блок – это все, что заключено между {}. Функция – тоже блок. Область видимости: видны внутри блока, в котором объявлены. Могут быть перекрыты одноименными переменами во внутренних блоках. Их значения и даже сам факт, что локальные переменные существуют, известны только данной функции, Другими словами, если вы объявляете локальную переменную с именем salary в функции payroll, то другие функции не имеют доступа к значению переменной salary. Фактически, другие функции не имеют никакого представления о том, что переменная salary существует. При объявлении локальных переменных внутри функции очень вероятно, что имя локальной переменной, объявляемой вами в одной функции, будет таким же, как и имя переменной, используемой в другой функции. Как уже упоминалось, локальные переменные известны только в текущей функции. Таким образом, если две функции используют одно и то же имя для своих локальных переменных, это не приводит к конфликту. Время жизни – это части программы или вся программа, при выполнении которой переменная существует. Область видимости – это часть программы или вся программа, когда возможно получить доступ к объекту. 17. Функции для работы с динамической памятью. Примеры. Динамическое распределение памяти из кучи (heap). Часто бывает удобно создать новый объект, который существует до тех пор, пока он не станет ненужным. В частности, бывает удобно создать объект, который можно использовать после возврата из функции, где он был создан. (определение из лекции) Или Динамическое распределение памяти — способ выделения оперативной памяти компьютера для объектов в программе, при котором выделение памяти под объект осуществляется во время выполнения программы. (используется, если на момент написания программы известен только тип данных, не известен объем выделяемой памяти. В этом случае память должна выделяться в момент исполнения программы). Часто бывает удобно создать новый объект, который существует до тех пор, пока он не станет ненужным. В частности, бывает удобно создать объект, который можно использовать после возврата из функции, где он был создан. Для работой с памятью используются следующие основные функции:
Основу системы динамического распределения в С составляют функции malloc() и free(). Функция malloc() выделяет память, а free() — освобождает ее. Это значит, что при каждом запросе функция malloc() выделяет требуемый участок свободной памяти, a free() освобождает его, то есть возвращает системе. Функции malloc и free описаны в библиотеке <stdlib.h>. Функция malloc() возвращает указатель типа void *, поэтому его можно присвоить указателю любого типа. int *p1 = malloc(400); double *p2= malloc(400); Выделаются НЕПРЕРЫВНО 400 байт. Указатели p1 и p2 указывают на начало блока. По-сути – p1 ссылается на массив из 100 элементов типа int, а p2 – ссылается на 50 элементов типа double. При успешном выполнении malloc() возвращает указатель на первый байт непрерывного участка памяти, выделенного в динамически распределяемой области памяти. При необходимости выделения динамической памяти под массив определенного типа и для улучшении переносимости программы на другие платформы нужно использовать sizeof. int *p;p = malloc(50*sizeof(int));Если в динамически распределяемой области памяти недостаточно свободной памяти для выполнения запроса, то память не выделяется и malloc() возвращает нуль (0 или NULL). При каждом размещении данных необходимо проверять, состоялось ли оно. p = malloc(100);if(!p) { printf("Нехватка памяти.\n"); exit(1); Не использовать указатель р, если он равен нулю! Функция free() противоположна функции malloc() в том смысле, что она возвращает системе участок памяти, выделенный ранее с помощью функции malloc(). Иными словами, она освобождает участок памяти, который может быть вновь использован функцией malloc().18. Что такое sizeof. Почему надо использовать sizeof при написании программ. С помощью операции sizeof можно определить размер памяти которая соответствует идентификатору или типу. Операция sizeof имеет следующий формат: sizeof(выражение). В качестве выражения может быть использован любой идентификатор, либо имя типа, заключенное в скобки. Отметим, что не может быть использовано имя типа void, а идентификатор не может относится к полю битов или быть именем функции. Если в качестве выражения указанно имя массива, то результатом является размер всего массива (т.е. произведение числа элементов на длину типа), а не размер указателя, соответствующего идентификатору массива. Однако убедиться, что вы каждый раз выделяете и освобождаете один и тот же объем памяти, недостаточно. Вы должны обеспечить распределение правильного объема памяти. Надежнее всего использовать в программе функцию SizeOf. Это не только обеспечивает, что вы выделяете и освобождаете один и тот же объем, но гарантирует, что при изменении размера типа ваша программа все равно будет выделять нужную память. Не нашли, что искали? Воспользуйтесь поиском:
|