Переменная какого типа требует больше оперативной памяти
Аннотация: Из этой лекции вы узнаете, что такое переменная, и какие типы переменных бывают. Также познакомитесь с типом "Строка". Затем мы затронем стили программирования, познакомимся с комментариями и напишем две программы.
В любом языке программирования приходится использовать переменные . При загрузке программы, компьютер вначале считывает все необходимые данные в оперативную память , после чего уже имеет возможность работать с ними. Переменная – это ячейка оперативной памяти, которая может хранить данные какого-то одного типа. Переменная похожа на ячейку в MS Excel , там тоже в ячейке можно указать нужный формат данных. Если переменная имеет тип данных "строка", то в нее нельзя записать число. А в переменную с типом " целое число " нельзя записать вещественное число. В языках программирования вещественным называют число, у которого есть запятая, после которой имеются цифры, хотя бы нули:
Каждая переменная имеет уникальное имя. Для компьютера имя переменной – это адрес ячейки памяти, где хранятся данные. Присваиванием имен (идентификаторов) переменным занимается программист. Имена переменным в Delphi даются по определенным правилам:
- Имя переменной может содержать любое количество английских букв, цифр и знака подчеркивания, другие символы недопустимы.
- Первым символом обязательно должна быть буква или знак "_" (подчеркивание).
- В Delphi нет разницы, какие буквы вы даете переменным – большие или маленькие. То есть, myperem, MyPerem, MYPEREM – это одна и та же переменная.
Совет: Переменную можно назвать одной буквой. Однако уже через месяц или раньше вам очень трудно будет вспомнить, зачем вы делали переменную F, и какие данные в ней хранятся. Поэтому старайтесь давать переменным осмысленные имена и сочетайте большие буквы с маленькими для разделения на слова. Хорошие примеры – MinZarplata или Glav_Param.
Объект в куче
При динамическом создании объекта, то есть, выделении памяти в куче, помимо размера самого экземпляра класса можно учесть также и размер указателя на него:
Получается даже, что размер указателя может быть больше самого объекта:
В первом случае - int var = 5; - компилятор выделяет sizeof(int) байтов памяти под переменную var . Это совсем не обязательно 32 бита.
Во втором случае - Class a = 5; - компилятор точно таким же образом выделяет sizeof(Class) байтов под переменную a . Все совершенно единообразно.
Выделение памяти в таких примерах никоим образом не зависит правой части данного объявления, т.е. = 5 никак не влияет на размер выделяемой памяти.
А затем, когда память уже выделена, значение 5 используется в качестве инициализатора для нового объекта. Как именно оно используется - зависит от конкретного типа. В первом случае оно просто заносится в переменную var . А что произойдет во втором случае уже зависит от деталей типа Class . Инициализация в С++ - процесс, описываемый целым набором весьма запутанных правил.
Программистам сплошь и рядом приходится использовать данные целого типа. Целое число – это число, не имеющее запятой. Число может быть беззнаковым (положительным), и со знаком минус (отрицательным). Примеры:
Давайте разберемся, как работает любая программа . Когда мы загружаем программу, она считывается в оперативную память компьютера. Туда же считываются и данные, с которыми программа работает. Только после этого программа начинает выполняться. Если современные жесткие диски имеют достаточно большой размер, этого нельзя сказать об оперативной памяти. Поэтому ее следует экономить везде, где только можно.
Чаще всего вам придется работать с переменными типа Integer , это самый распространенный тип целых чисел, он годится почти для всех расчетов. Однако бывают моменты, когда не нужно такого большого диапазона значений. Например, вы будете использовать переменную для счетчика какого-то цикла , и знаете, что он будет длиться, к примеру, от 1 до 100. В таком случае, указав в качестве счетчика тип Integer , мы зря украдем у оперативной памяти 3 байта! 3 байта – это немного, но ведь в большой программе переменных будет очень много, и если все они будут тратить память попусту, то такая программа будет, мягко говоря, непрофессиональной. Приучайтесь сразу тратить столько байт оперативной памяти, сколько нужно. Не зря ведь придумали столько типов! Если Вы знаете, что в переменной будут числа от нуля и выше, то нет никакой необходимости брать знаковый тип, ведь отрицательным Ваше число все равно не будет!
Типы переменных
Каждая переменная имеет свой тип. Тип переменной обязательно нужно указывать, потому что разные типы переменных занимают разный размер, и компьютеру нужно знать, сколько байт в оперативной памяти требуется отвести под указанную переменную. Создание переменной состоит из двух этапов:
- Объявление переменной (указываем имя и тип переменной ). Переменная объявляется в специальном разделе var (позже мы познакомимся с этим разделом).
- Присвоение переменной какого-то значения.
Объявление переменной выглядит так:
Как видно из примера, вначале указывается имя переменной , затем, после двоеточия указывается тип переменной . Если нужно объявить несколько переменных одного типа, их имена разделяются запятыми. В приведенном примере мы объявили одну вещественную переменную типа Real и две целые переменные типа Integer .
Присваивать значение переменным можно неоднократно. Переменная потому и называется так, что ее значение в процессе работы программы может меняться. Оператор присвоения значения выглядит так:
Примеры присвоения значений переменным:
Механизм присвоения значения работает следующим образом: вначале рассчитывается значение в правой части команды, то есть, после знака " := ". Затем результат этого значения записывается в переменную. В последней строке примера мы использовали выражение "3+5-1". Вначале получается результат, в нашем случае он равен 7. Затем этот результат записывается в переменную.
В дальнейшем, имя переменной можно использовать в различных выражениях, например:
В первой строке мы записали в переменную число 3. Вторая строка содержит выражение , результатом которого будет число 10. А вот третья строка интересней. Как вы полагаете, что будет записано в переменную A1 ? Если ваш ответ 4, вы совершенно правы: вначале рассчитывается результат правой части команды, где в переменной A1 еще старое значение , затем он записывается в эту же переменную, изменяя ее значение .
В таблице 2.1 перечислены основные типы переменных:
На самом деле, типов переменных значительно больше, и по мере усложнения программ мы будем изучать эти типы. В таблице представлены только основные типы.
Как я понимаю, обычно тип integer весит 4 байта, в том числе и unsigned integer . Но есть случаи где в зависимости от разрядности процессора integer может иметь как 2 байта так и 8. Не понимаю, как разрядность влияет на размер целочисленного типа и что это меняет для разработчика кроме того, что в него можно вместить шире диапазон чисел(или меньший)?
UPD
Что значить переводить программу из x32 в x64 ? Грубо говоря, это использования типов x64 ? Если я правильно понимаю, причина по которой программа написанная под x64 не будет работать на x32 , это оверхед по память в типах данных? Почему тогда мы можем допустим в Visual Studio выбрать под какую разрядность делать build ? Как это будет влиять на размер самой программы и размер, который будут забирать обычные типы данных?
2 ответа 2
Есть такая таблица соответствия размеров фундаментальных типов в зависимости от используемой модели данных:
Модель данных в общем случае не привязана непосредственно к железу (разрядности процессора), и зависит от используемой операционной системы (если она присутствует). При этом должно быть очевидно, что на 32bit процессоре не удастся запустить 64bit ОС, но обратное вполне себе имеет место быть.
Размер фундаментальных типов в конкретной реализации компилятора (т.е. под конкретную платформу) подбирается так, чтобы обеспечивать оптимальную производительность.
Помимо увеличения диапазона значений фундаментальных типов, бОльшая разрядность позволяет адресовать больше памяти. Например, при 32bit можно адресовать не более 4Gb, а при 64bit уже 16Eb.
Когда говорят о переводе программы с x32 на x64 имеют в виду, что должна обеспечиваться в первую очередь работоспособность программы в 64bit окружении. Т.е. что из-за изменения размеров типов ничего не сломается. Такого рода проблемы часто возникают, когда при первичной разработке закладываются на фиксированный размер фундаментальных типов, например, что указатель всегда будет 4 байта. А когда при сборке в 64bit режиме он "вдруг" становится в 2 раза больше программа просто начинает крашиться.
Поэтому, чтобы программа была переносима между x32 ↔ x64 при необходимости обеспечить нужную разрядность вычислений стоит полагаться на типы из .
Когда мы создаем переменную int var = 5 , все понятно, компьютер берет (выделяет) память 32 бита и записывает туда значение 5 в двоичном виде.
Но что происходит когда мы создаем переменную типа класс? class a = 5 . Что происходит? Сколько байт выделяется под эту переменную?
В первом случае ничего не понятно, так как размер типа int и количество реально выделяемой под него памяти определяется компилятором. Во втором случае ошибка синтаксиса.
class a = 5 - такого в С++ не бывает. class - это ключевое слово и оно не может быть использовано таким образом .
@VTT почему пишут такое? "myVar1 = 25; Указывает компьютеру, что нужно выделить память для переменной myVar1 типа int. Размер памяти выделяемой для нее зависит от самого компьютера. Например на 32-х разрядном компьютере он равен 4 байтам(32 бит)."
myVar1 = 25; можно написать только для уже ранее объявленной переменной. Поэтому не не ясно о каком "указывает компьютеру, что нужно выделить память" вы ведете речь. Нет, ничего подобного это не указывает.
При создании экземпляра класса автоматически запускается конструктор, который может делать с памятью что угодно, хоть всю память зарезервировать.
Типы переменных
Каждая переменная имеет свой тип. Тип переменной обязательно нужно указывать, потому что разные типы переменных занимают разный размер, и компьютеру нужно знать, сколько байт в оперативной памяти требуется отвести под указанную переменную. Создание переменной состоит из двух этапов:
- Объявление переменной (указываем имя и тип переменной ). Переменная объявляется в специальном разделе var (позже мы познакомимся с этим разделом).
- Присвоение переменной какого-то значения.
Объявление переменной выглядит так:
Как видно из примера, вначале указывается имя переменной , затем, после двоеточия указывается тип переменной . Если нужно объявить несколько переменных одного типа, их имена разделяются запятыми. В приведенном примере мы объявили одну вещественную переменную типа Real и две целые переменные типа Integer .
Присваивать значение переменным можно неоднократно. Переменная потому и называется так, что ее значение в процессе работы программы может меняться. Оператор присвоения значения выглядит так:
Примеры присвоения значений переменным:
Механизм присвоения значения работает следующим образом: вначале рассчитывается значение в правой части команды, то есть, после знака " := ". Затем результат этого значения записывается в переменную. В последней строке примера мы использовали выражение "3+5-1". Вначале получается результат, в нашем случае он равен 7. Затем этот результат записывается в переменную.
В дальнейшем, имя переменной можно использовать в различных выражениях, например:
В первой строке мы записали в переменную число 3. Вторая строка содержит выражение , результатом которого будет число 10. А вот третья строка интересней. Как вы полагаете, что будет записано в переменную A1 ? Если ваш ответ 4, вы совершенно правы: вначале рассчитывается результат правой части команды, где в переменной A1 еще старое значение , затем он записывается в эту же переменную, изменяя ее значение .
В таблице 2.1 перечислены основные типы переменных:
На самом деле, типов переменных значительно больше, и по мере усложнения программ мы будем изучать эти типы. В таблице представлены только основные типы.
Как я понимаю, обычно тип integer весит 4 байта, в том числе и unsigned integer . Но есть случаи где в зависимости от разрядности процессора integer может иметь как 2 байта так и 8. Не понимаю, как разрядность влияет на размер целочисленного типа и что это меняет для разработчика кроме того, что в него можно вместить шире диапазон чисел(или меньший)?
UPD
Что значить переводить программу из x32 в x64 ? Грубо говоря, это использования типов x64 ? Если я правильно понимаю, причина по которой программа написанная под x64 не будет работать на x32 , это оверхед по память в типах данных? Почему тогда мы можем допустим в Visual Studio выбрать под какую разрядность делать build ? Как это будет влиять на размер самой программы и размер, который будут забирать обычные типы данных?
2 ответа 2
Вещественные числа
Как мы уже говорили раньше, вещественные числа – это числа с запятой, после которой идут десятичные значения. Еще говорят, что они имеют плавающую точку (запомните это определение , оно будет часто встречаться). Некоторые начинающие программисты считают, что лучше такой тип переменных использовать всегда, даже при обработке целых чисел. Это большое заблуждение! Операции над числами с плавающей точкой отнимают у процессора гораздо больше времени, и требуют больше памяти. Компьютер воспринимает вещественное число , как два целых, и делает двойную работу при обработке чисел до запятой, и после нее. Однако иной раз бывает необходимо использовать именно такой тип данных. К примеру, если нужно поделить одно целое на другое. Хорошо, если это будет "4/2", результат тоже будет целым – 2. А если "4/3"? Тогда результатом будет 1,3333… и уж тут без вещественного числа не обойтись! А ведь мы заранее не знаем, какие числа будет делить пользователь , поэтому лучше сразу иметь в виду, что результат может быть не целым числом.
Как и целые, вещественные числа имеют несколько типов.
Третий столбец таблицы указывает количество максимально значащих цифр. Цифры, которые выходят за этот предел , будут игнорироваться. Тут важно помнить, что вещественные числа не равны целым. То есть, число 3,0 не будет равно 3! Чтобы сравнить оба эти числа, придется округлить вещественное число .
Изучим целые и вещественные типы на практике. Для этого создадим простую программу, которая делит одно целое число на другое. Результат будет выводиться, как вещественное число .
Откройте Delphi, создайте новый проект. На форму нужно поместить три компонента Label , три компонента Edit и одну кнопку, чтобы получилась такая картина:
Совет: чтобы выполнить одинаковую операцию над несколькими компонентами сразу, их можно выделить один за другим, удерживая клавишу
Сохраните проект под именем MyCalc. Затем дважды щелкните по кнопке, чтобы создать обработчик нажатия на кнопку.
Перед begin процедуры следует создать раздел var , и объявить там три переменных:
Затем вернемся в тело процедуры (между командами begin и end ), и присвоим целым переменным введенные пользователем значения. Здесь нужно понять одну важную вещь. Пользователь будет вводить значения в компоненты Edit , и там они будут храниться в свойстве Text в виде строкового типа данных. Строку нельзя будет присвоить переменной какого-либо другого типа данных, присвоение
будет ошибочным. Разница довольно существенная: даже если пользователь вводит, казалось бы, целое число , например,
то компьютер видит строку символов, а вовсе не число:
Выход – преобразовать один тип данных в другой, в нашем случае, строку в целый тип. Преобразованием типов приходится заниматься сплошь и рядом, по мере изучения материала мы будем знакомиться с различными способами преобразования. Преобразовать строку в целый тип можно с помощью функции
В качестве параметра (в скобках) указывается строка. Функция преобразует ее в целое число и вернет его как результат. Примеры использования функции (эти примеры не нужно вводить в редактор кода):
Как видно из примера, имеется масса возможностей передать в функцию строку. В первом случае преобразования мы передаем строковую переменную s , в которой хранится строка '1234'. Функция преобразует эту строку в целое число , и в результате в переменную i попадет уже число 1234.
Во втором случае мы передаем непосредственно строку '123456', а в переменную i попадает преобразованное из этой строки число. В третьем случае мы в качестве параметра передаем тот текст, который пользователь ввел в поле ввода Edit1 . Здесь следует сделать оговорку. Функция сработает правильно, если пользователь ввел туда действительно целое число . В противном случае возникнет ошибка. Пользователь – личность непредсказуемая, поэтому программист в таких случаях перед преобразованием типов всегда делает проверку – а действительно ли в поле ввода имеются только цифры от 0 до 9? Нет ли там случайно буквы или запятой? Такую проверку мы научимся делать позднее. Пока что придется самим следить, чтобы в этих полях ввода были только целые числа.
Вернемся к программе. Сразу после begin присваиваем целым переменным значения, которые ввел пользователь :
В третью, вещественную переменную, мы должны записать результат деления первого числа на второе. Тут может крыться еще один "подводный камень" - что, если во второе поле пользователь ввел число 0? Еще со школы все мы знаем, что на ноль делить нельзя. Если же мы попробуем это сделать, то компьютер , в лучшем случае, зависнет. Здесь опять придется делать проверку на правильность введенных данных, ставить, как говорят, "защиту от дураков". Подробнее о таких проверках мы поговорим на следующих лекциях, когда изучим условные конструкции. А пока просто наберите этот код:
Здесь следует обратить внимание на предпоследнюю строку. Функция FloatToStr() в качестве параметра принимает вещественное число , и возвращает это же число в виде строки. Например, в результате преобразования
переменной s будет присвоена строка '123.45', которую затем уже можно будет вывести пользователю в качестве результата. В нашем примере мы результат деления двух целых чисел преобразуем в строку и выводим его в поле Edit3 . Справедливости ради следует заметить, что в качестве параметра можно передавать не только значение , но и выражение . Например, если указать
то надобность в использовании вещественной переменной Perem3 отпадает. Попробуйте, как работают оба варианта.
4. Переменные: тип, имя, значение.
В объектно-ориентированном языке программирования Visual Basic переменные используются для хранения и обработки данных в программах.
Переменные задаются именами, которые определяют области оперативной памяти компьютера, в которых хранятся значения переменных. Значениями переменных могут быть данные различных типов (целые или вещественные числа, последовательности символов, логические значения и т. д.).
Переменная в программе представлена именем и служит для обращения к данным определенного типа, конкретные значения которых хранятся в ячейках оперативной памяти.
Тип переменной . Тип переменных определяется диапазоном значений, которые могут принимать переменные, и допустимыми операциями над этими значениями. Значениями переменных числовых типов Byte , Short , Integer , Long , Single , Double являются числа, логического типа Boolean — значения True («истина») или False («ложь»), строкового типа String — последовательности символов.
Различные типы данных требуют для своего хранения в оперативной памяти компьютера различное количество ячеек (байтов) (табл. 2.2).
Таблица 2.2. Некоторые типы переменных в языке Visual Basic 2 010
Возможные значения
Объем занимаемой памяти
Целые неотрицательные числа от 0 до 255
Целые числа от –32 768 до 32 767
Целые числа от –2 147 483 648 до 2 147 483 647
Целые числа от –9 223 372 036 854 до
9 223 372 036 853
Десятичные числа одинарной точности (7-8 значащих цифр) от –1,4·10 –45 до 3,4·10 38
Десятичные числа двойной точности (15-16 значащих цифр) от -5,0·10 –324 до 1,7·10 308
Логическое значение True или False
Строка символов в кодировке Unicode
Даты от 1 января 0001 года до 31 декабря 9999 года и время от 0:00:00 до 23:59:59
Имя переменной. Имена переменных определяют области оперативной памяти компьютера, в которых хранятся значения переменных. Имя каждой переменной (идентификатор) уникально и не может меняться в процессе выполнения программы. Имя переменной может состоять из различных символов (латинские и русские буквы, цифры и т. д.), но должно обязательно начинаться с буквы и не должно включать знак точка «.». Количество символов в имени не может быть более 1023, однако для удобства обычно ограничиваются несколькими символами.
Объявление переменных. Необходимо объявлять переменные, для того чтобы исполнитель программы (компьютер) «понимал», переменные какого типа используются в программе.
Для объявления переменной используется оператор Dim . С помощью одного оператора можно объявить сразу несколько переменных, например:
Dim A As Byte, В As Short, С As Single, D As String, G As Boolean
Присваивание переменным значений. Переменная может получить или изменить значение с помощью оператора присваивания. При выполнении оператора присваивания переменная, имя которой указано слева от знака равенства, получает значение, которое находится справа от знака равенства. Например:
Значение переменной может быть задано числом, строкой или логическим значением, а также может быть представлено с помощью арифметического, строкового или логического выражения.
Проект «Переменные». Создать проект, в котором объявить переменные различных типов, присвоить им значения и вывести значения в поле списка, размещенное на форме.
Создадим графический интерфейс (рис. 2.8).
1. Поместить на форму:
• поле списка ListBox 1 для вывода значений переменных;
• кнопку Button 1 для запуска событийной процедуры.
Создадим событийную процедуру, реализующую присваивание значений переменным различных типов. Вывод значений переменных в поле списка произведем с использованием метода Items . Add () , аргументами которого будут переменные.
2. Dim A As Byte, В As Short, С As Single, D As String, G As Boolean
Private Sub Button1_Click (. )
End Sub
3. Запустить проект на выполнение. После щелчка по кнопке начнет выполняться событийная процедура, в которой будут выполнены операции присваивания (в отведенные переменным области оперативной памяти будут записаны их значения).
Затем с помощью метода Items . Add () будет произведен вывод значений переменных в поле списка. В этом процессе значения переменных считываются из оперативной памяти и печатаются в столбик в поле списка (см. рис. 2.8).
Рис. 2.8. Проект «Переменные»
Проанализируем процесс выполнения программы компьютером. После запуска проекта оператор объявления переменных Dim отведет в оперативной памяти для их хранения необходимое количество ячеек (табл. 2.3):
Объект в стеке
В программе выделяется столько байт, сколько требуется для хранения данных экземпляра данного класса. Например, объект пустого класс займёт один байт, если в нём хранится int , то его размер прибавится к размеру объекта класса. Вот интересный код для исследования этих свойств:
Результат выполнения с моим компилятором:
Меняя число переменных можно заметить, что поля с модификатором static не влияют на размер выделенной памяти, что и логично, ведь она не относится к конкретным экземплярам класса.
Читайте также: