![](/stc/img/evkova.png)
Понятие переменной в программировании. Виды и типы переменных ( Виды типизации в языках программирования)
Содержание:
ВВЕДЕНИЕ
Данная курсовая работа посвящена понятию переменной в программировании, а также видам и типам переменных. Если обратиться к статье «Переменная (программирование)» в русскоязычной Википедии, то мы там увидим, что переменная в программировании – это поименованная, либо адресуемая иным способом область памяти, адрес которой можно использовать для осуществления доступа к данным [6]. Из данного определения следует, что переменные используются только для доступа к данным. Однако во многих современных языках программирования это не так. Например, кроме доступа к данным, переменные могут применяться для доступа к объектам (экземплярам класса), к структурам (ассоциативные или обычные массивы) и т.д. В этом и состоит актуальность данного исследования – ни одна программа не обходится без переменных, и программисту необходимо понимать все особенности работы с переменными в различных современных языках программирования, а также особенности их типов данных.
Объектами исследования в данной курсовой работе является переменная в программировании и типы данных различных переменных.
Целью данной работы является провести всестороннее исследование понятия переменная в различных современных языках программирования.
Исходя из поставленной цели работы, задачами данного исследования являются:
1. Дать определение понятию «переменная».
2. Дать трактовку переменной для программирования.
3. Исследовать свойства переменных в различных языках программирования.
4. Рассмотреть понятия «тип данных».
5. Исследовать различные варианты типизации в программировании.
В данной курсовой работе будет две главы. Первая глава будет посвящена понятию переменной, а вторая глава рассматривает вопросы типизации в различных языках программирования.
Курсовая работа содержит 14 рисунков, 0 таблиц.
ГЛАВА 1. Понятие переменной. Типы данных переменной
В самом начале нашего исследования необходимо разобраться в самом понятии «переменная». Само это понятие не очевидно для человека. Дело в том, что когда в школе начинают изучать различные науки, то впервые понятие переменной возникает в разделе математики – алгебра, а вот в арифметике данное понятие отсутствует. В арифметике мы имеем дело с числами. Например, маленький школьник решал следующие задачи: «Сколько будет 2+3?», «Найдите результат следующего выражения: 7-4=?» и т.д. В этих задачах 2, 3, 7, 4 – это числа, а точнее константы, то есть такие сущности, которые не меняют своего значения в течение времени – «семь всегда «семь».
Возьмем калькулятор. Что он умеет делать? Довольно много чего: он успешно справляется с арифметическими и алгебраическими действиями. Например:
- вводим на калькуляторе первое число, например, «2»;
- нажимаем на знак «плюс»;
- вводим второе число, скажем, «3» (см. рис. 1),
- и затем нажимаем знак «=».
Рис. 1. Пример работы калькулятора
Результат работы калькулятора в данном примере очевиден для всех – это цифра 5. Калькуляторы бывают разными: инженерными, для статистики, для программистов, но каким бы сложным калькулятор не был, он всё равно работает только с числами. Другие уровни абстракции ему не подвластны, калькуляторы умеют вычислять только числовые выражения.
Позже школьнику уже приходится иметь дело с выражениями другого вида: a+b=c. В чем тут отличие? Не только в том, что во втором случае вместо чисел мы применили буквы латинского алфавита, но и в том, что мы записали выражение на новом уровне абстракции. Подобные выражения носят названия формул. С помощью формул можно описывать законы окружающего мира, записывать выражения для вычисления площади, объема, длины, скорости и т.д. Введя понятие формул, мы подготовили своего рода «рецепт» какого-либо процесса или явления, то есть, написав формулу скорости , где V – скорость тела, S – пройденный телом путь, t – время движения, то мы описали все возможные значения скорости при различных значениях пройденного расстояния и времени движения. Также буквенная запись позволяет вычислить площадь любого треугольника, независимо от его параметров (длин его сторон, высот и т.д.).
Если бы следующий, новый уровень абстракции не вошел в обиход в компьютерной грамотности, то тогда не появилось бы программирование в том виде, как оно существует в наше время. Программирование, которое позволяет делать программное обеспечение с дружественным интерфейсом, то есть, удобным для последующего пользования.
Вернемся к нашему примеру со скоростью: . Это формула, а V, S, t в ней называются операндами или переменными. Именно подобные буквенные обозначения в формулах и являются переменными. Почему? Потому что они принимают различные значения. Их значения меняются, отсюда и такое название.
Итак, в математике и в программировании мы имеем дело с двумя очень важными сущностями: с переменными и константами. Константы не меняют своего значения с течением времени (смотри пример с числовыми выражениями и с калькулятором), а переменные могут принимать различные значения.
В программировании все выражения пишут как бы наоборот по сравнению с тем, как их пишут в алгебре. Если в алгебре сначала указывают операнды (переменные), над которыми следует произвести действия, а потом после знака равенства указывают результат, как в примере a + b = c, то в программировании делают все наоборот: сначала указывают результат, а потом действие, то есть: C = A + B. Здесь не случайно написаны строчные (заглавные) буквы вместо прописных (маленьких) букв. Это было сделано по двум причинам: во-первых, чтобы отличить алгебру от программирования, а во-вторых, потому что первоначально в нашей стране в программировании использовали в основном заглавные буквы латинского алфавита.
Почему стали в программировании писать наоборот, а именно стали писать C = A + B? Трудно сказать. Так сложилось, что сначала надо было указывать результат, и лишь потом действие.
Что же дает подобное «волшебное» выражение с буквами вместо цифр для программирования? Казалось бы, в чем разница между константами и переменными: 5 = 2 + 3 (напишем наоборот лишь для сравнения) и
C = A + B?
Давайте разберемся. Что может быть результатом сложения 2+3? Большинство ответит, конечно, «5». И хоть это почти правильный ответ, пожалуй, мы с этим согласимся. Почему почти? Да потому что это правильный ответ для десятичной системы исчисления. Для четверичной системы исчисления, в которой используются только цифры от 0 до 3, ответ был бы «11». А в пятеричной системе исчисления, где добавляется еще цифра 4, ответ был бы «10». Но в любом случае, о какой бы системе исчисления мы не говорили, результатом 2+3 всегда будет одно и то же число (константа). В десятичной системе (вернемся к ней теперь надолго), это «5», и только «пять».
А сколько будет A + B? Ответ очевиден: все зависит от того, чему равны A и B. Значит, результатом 2+3 всегда будет 5, а результатом A+B будут разные значения в зависимости от величин A и B.
Достаточно очевидно. Ну и что, что 5 – константа, а тут переменная? А то, что переменные – это другой уровень абстракции. За счет A+B мы теперь можем получать множество разных значений.
Мы разобрались с сутью понятия «переменная», теперь дадим более строгое определение, которое применяется в программировании.
Под переменной в языках программирования понимают программный объект (число, слово, часть слова, несколько слов, символы), имеющий имя и значение, которое может быть получено и изменено программой [5].
Если "заглянуть" в компьютер, то переменную можно определить так: переменная представляет собой контейнер в памяти компьютера, где хранятся данные [2]. Само название "переменная" подразумевает, что содержимое этого участка может изменяться.
Все программы работаю с данными. Данные могут быть представлены в виде документа, графического фрагмента, видеоигры или мгновенного сообщения. Для их хранения программа использует именно переменные.
Каждая переменная характеризуется следующими атрибутами [3]:
- именем;
- типом данных;
- значением;
- временем жизни;
- областью видимости.
О типизации более подробно будет написано во второй главе данной курсовой работы, так как это вопрос очень неоднозначный и все зависит от выбранного языка программирования. А сейчас мы подробно рассмотрим вопрос именования переменных, дадим общее определение понятию «тип данных» и рассмотри вопросы области видимости переменной в программе.
После того как данные сохранены, их можно вызвать, используя имя этой переменной [2]. В качестве имен переменных могут быть латинские буквы с цифрами. Причем может быть не одна буква, а несколько. Имя переменной не может начинаться с цифры, а также программист не может использовать в качестве имени переменной зарезервированные слова языка программирования [2]. Разные языки программирования по-разному чувствительны к регистру имен переменных. Например, в Pascal не имеет значение в обозначении переменных маленькими или большими (строчными или прописными) буквами они написаны, а вот C, C++, C#, Python, Java чувствительны к регистру (переменные «A» и «a» являются разными переменными).
Сформулируем общие правила именования переменных, которые характерны для всех языков программирования [5]:
1) всегда начинаться с буквы, после которой могут другие буквы или цифры;
2) в идентификаторе (имени) не должно быть пробелов, запятых или других непредусмотренных знаков;
3) нельзя использовать в качестве имен переменных слова, которые являются служебными или операторами.
Перед использованием переменной надо объявить. Объявление переменной чаще всего выглядит так: указывается тип и имя [4]. Например, на рис. 2 показан пример объявления переменных на языке программирования C# [4].
Рис. 2. Пример объявления переменных на языке C#
В языке программирования Паскаль существует отдельный раздел программы для описания переменных [5].
______________________________________________________________
var
a: byte;
b: integer;
c, d, e: real;
f:double;
______________________________________________________________
Слово var - это сокращение от слова variable (переменная) и является зарезервированным словом.
В разделе описания переменных может содержаться несколько строчек, каждая из которых заканчивается точкой с запятой. Для описания переменных необходимо перечислить через запятую их имена, а затем после двоеточия «:» указать их тип.
Тип данных характеризует внутреннее представление, множество допустимых значений для этих данных, а также совокупность операций над ними [5]. Каждая переменная и константа программы должны принадлежать к определенному типу данных. Это необходимо для того, чтобы отвести необходимое место в оперативной памяти и для проверки правильности записи выражений. Например, над числовыми данными можно производить арифметические операции, а символьные данные используются для анализа текста.
Среди типов данных различают стандартные (предопределенные разработчиками языка) и пользовательские (определяемые программистом в своей программе) [5].
К стандартным типам данных относят:
- целые числа ( -∞ …-2, -1, 0, 1, 2, … +∞)
- вещественные числа (действительные числа: все)
- логический тип (ложь, истина)
- символьный (символы, слова или текст).
Типы данных различаются, начиная с нижних уровней системы. Так, например, даже в Ассемблере х86 различаются типы «целое число» и «вещественное число». Это объясняется тем, что для чисел рассматриваемых типов отводятся различные объёмы памяти, используются различные регистры микропроцессора, а для операций с ними применяются различные команды Ассемблера и различные ядра микропроцессора [1].
Концепция типа данных появилась в языках программирования высокого уровня как естественное отражение того факта, что обрабатываемые программой данные могут иметь различные множества допустимых значений, храниться в памяти компьютера различным образом, занимать различные объёмы памяти и обрабатываться с помощью различных команд процессора [5].
Важно отметить то, что как правило, типы данных в языках программирования не строго соответствует аналогичным математическим типам. Например, «целое число» в различных языках программирования не соответствует математическому понятию «целое число», так как в математике данные тип не имеет ограничений ни снизу, ни сверху, а в языках программирования такие ограничения есть – компьютерная память имеет физические границы. В программировании существует ни один тип «целое», а множество таких типов, отличающихся друг от друга допустимым диапазоном значений.
Программист может описать свой тип на основе базовых типов данных. Так, например, в языке программирования C++ можно задать тип enum, где программист через запятую прямо перечислит те значения, которые возможны в данном типе [3].
Формальным обоснованием для систем типов служит теория типов [7]. В состав языка программирования включается система типов для осуществления проверки типов во время компиляции или во время выполнения, требующая явного провозглашения типов или выводящая их самостоятельно.
Операция назначения типа, называемая типизацией, придаёт смысл цепочкам бит, таким как значение в памяти компьютера, или объектам, таким как переменная [7]. Компьютер не имеет возможности отличить, к примеру, адрес в памяти от инструкции кода, или символ от целого числа или числа с плавающей запятой, поскольку цепочки бит, представляющие эти различные по смыслу значения, не имеют каких-либо явных особенностей, позволяющих делать предположения об их смысле. Назначение цепочкам бит типа предоставляет это осмысление, превращая тем самым программируемое аппаратное обеспечение в символьную систему, состоящую из этого аппаратного обеспечения и программы.
Процесс проверки и установления ограничений для типов — контроль типов или проверка соответствия типов — может осуществляться как на стадии компиляции (статическая типизация), так и во время выполнения (динамическая типизация). Если спецификация языка требует, чтобы правила типизации исполнялись строго (то есть допуская в той или иной мере лишь те автоматические преобразования типов, которые не теряют информацию), такой язык называется сильно типизированным(англ. strongly typed; в русской литературе преобладает вариант перевода строго типизированным), в противном случае — слабо типизированным [7]. Эти термины являются условными и не используются в формальных обоснованиях.
Например, в языке Python [2] распределение памяти происходит в соответствии с присваиваемыми переменным значениями (динамическая типизация) [2]. Это означает, что переменная может содержать как целые числа, так и числа с плавающей точкой, текстовые строки или логические значения.
В настоящий момент времени большинство высокоуровневых языков программирования поддерживают концепцию объектно-ориентированного программирования. К типам данных можно также отнести классы.
То, что мы сейчас сказали про типы данных, характерно для большинства языков программирования. Более подробно про типизацию будет рассказано во второй главе данной курсовой работы.
Наглядно (см. рис. 3) переменную можно представить как коробочку, в которую можно положить на хранение что-либо. Имя переменной – это надпись на коробочке, значение – это то, что хранится в ней в данный момент, а тип переменной говорит о том, что допустимо класть в эту коробочку.
Рис. 3. Наглядное представление переменной в виде коробочки
В большинстве языков программирования, например в Python [2], переменной должно быть присвоено начальное значение (инициализация переменной) в инструкции, которая объявляет эту переменную, - иначе будет выдана ошибка, что переменная не определена.
Инициализация переменной на языке Python [2] будет выглядеть так, как показано на рис. 4.
Рис. 4. Инициализация сразу трех переменных на языке Python
На рис. 4 показан пример инициализации сразу трех переменных с одним и тем же значением. Знак равно в данном случае это не равенство, а оператор присваивания. Поместить в переменную значение можно при помощи оператора присваивания. Во многих языках программирования (С, С++, C#, Python, Java) он выглядит как знак =. В языке Паскаль он имеет обозначение :=. На рис. 5 показан пример инициализации переменных на языке C#, а на рис. 6 – инициализация переменных на языке Паскаль.
Рис. 5 Инициализация переменных на языке C#
Рис. 6. Инициализация переменных на языке Паскаль
Строго говоря, инициализировать переменные необходимо во всех языках программирования, это общее требование для любых программах. Однако, есть языки программирования, например Паскаль, где происходит автоматическая инициализация переменных (числовые переменные инициализируются значением нуль, строка инициализируется пустой строкой).
Любая переменная обладает еще двумя основными характеристиками: временем жизни и областью видимости [3]. Они зависят от места и способа описания переменной.
Если переменная описана вне любого блока (в частности, функции), она называется глобальной [3] и изначально обнуляется, если вы не предусмотрели ее инициализацию каким-то другим значением. Время её жизни – с начала выполнения программы и до её окончания, а область действия (область, в которой эту переменную можно использовать, обратившись к ней по имени) – весь файл, в котором она описана, начиная с точки описания [3].
Переменная, описанная внутри блока (в частности, внутри функции main), является локальной [3], память под неё выделяется в момент выполнения оператора описания и не обнуляется. Областью её действия является блок, в котором она описана, начиная с точки описания. Время её жизни также ограничено этим блоком [3]. Сколько раз выполняется блок, столько раз «рождается» и «умирает» локальная переменная.
Есть разновидность локальный переменных – статические [3]. Такие переменные существуют в языках программирования C++, C#, Java. Они, подобно глобальным переменным, существуют на всем протяжении выполнении программы и инициализируются однократно. С другой стороны, они, как локальные переменные, видны только в своем блоке. Для описания статических переменных используется ключевое слово static [3]. Ниже приведем пример описания трех переменных на языке C++ (см. рис. 7 и рис. 8).
Рис. 7. Описание различных переменных в языке С++
Рис. 8. Области видимости и время жизни переменных, язык С++
Память под все переменные из примера (рис. 7) выделяет компилятор. Кроме перечисленных существуют динамические переменные, память под которые резервируется во время выполнения программы [4] с помощью операции new в динамической области памяти. Доступ к таким переменным осуществляется не по имени, а через указатели [4].
Добавим еще то, что есть общая рекомендация, согласно которой не следует часто использовать глобальные переменные в своих программах. Переменная должна иметь минимальную из возможных областей действия, поскольку это значительно облегчает поиск ошибок [3].
Сделаем выводы по первой главе курсовой работы:
1. Под переменной в языках программирования понимают программный объект (число, слово, часть слова, несколько слов, символы), имеющий имя и значение, которое может быть получено и изменено программой [5].
2. Каждая переменная характеризуется следующими атрибутами [3]:
- именем;
- типом данных;
- значением;
- временем жизни;
- областью видимости.
3. Мы сформулировали общие правила именования переменных.
4. Дали определение понятию тип данных. Тип данных характеризует внутреннее представление, множество допустимых значений для этих данных, а также совокупность операций над ними [5]. Каждая переменная и константа программы должны принадлежать к определенному типу данных. Это необходимо для того, чтобы отвести необходимое место в оперативной памяти и для проверки правильности записи выражений. Например, над числовыми данными можно производить арифметические операции, а символьные данные используются для анализа текста.
5. Рассмотрели особенности работы глобальных и локальных переменных.
Вторая глава курсовой работы будет посвящена вопросам типизации.
ГЛАВА 2. Виды типизации в языках программирования
Для начала введем строгие определения.
Система типов данных языка — это система, которая ставит в соответствие каждому значению, вычисленному в процессе выполнения программы, свой тип данных [8].
Основные функции систем типов данных [8]:
- обеспечение безопасности: системы типов данных предотвращают так называемые «ошибки типов», проверяя, что каждая операция получает аргументы именно тех типов, для которых она имеет смысл, например, математические операции не получают аргументов типа строка или массив;
- оптимизация: типы, сопоставленные значениям, могут использоваться компилятором для оптимизации их обработки, например, для выбора способа их хранения и алгоритма их обработки;
- документация: использование определенных типов данных может подчеркивать намерения программиста;
- абстракция: использование типов данных высокого уровня позволяет программисту думать о значениях как о высокоуровневых сущностях, а не как о наборе битов.
Типизация языка определяется природой ограничений на типы данных и тем, как они проверяются и претворяются в жизнь. Типизация берет начало от практических вопросов архитектуры компьютеров, реализации компилятора и модели языка.
Языки программирования по типизации принято делить на два больших лагеря — типизированные и нетипизированные (бестиповые). К первому, например относятся C, Python, Scala, PHP и Lua, а ко второму — язык ассемблера, Forth и Brainfuck [5].
В бестиповых языках программирования — все сущности считаются просто последовательностями бит, различной длины [1]. Бестиповая типизация обычно присуща низкоуровневым (язык ассемблера, Forth) и эзотерическим (Brainfuck, HQ9, Piet) языкам. Однако и у нее, наряду с недостатками, есть некоторые преимущества [1].
Преимущества бестиповой типизации:
- позволяет писать на предельно низком уровне, причем компилятор / интерпретатор не будет мешать какими-либо проверками типов. Вы вольны производить любые операции над любыми видами данных;
- получаемый код обычно более эффективен;
- прозрачность инструкций. При знании языка обычно нет сомнений, что из себя представляет тот или иной код.
Так же существует сильная безтиповая типизация. Например в языке ассемблер [1] для архитектуры х86/х86-64 нельзя ассемблировать программу, если вы попытаетесь загрузить в регистр cx (16 бит) данные из регистра rax (64 бита).
Далее рассмотри понятия статической и динамической типизации.
Главное, что отличает статическую (static) типизацию от динамической (dynamic) то, что все проверки типов выполняются на этапе компиляции, а не этапе выполнения [5]. Компиляция – это процесс сборки программы, когда весь код на языке программирования высокого уровня переводится (транслируется) на язык машинных команд.
Некоторым может показаться, что статическая типизация слишком ограничена (на самом деле так и есть, но от этого давно избавились с помощью некоторых методик). Некоторым же, что динамически типизированные языки — это игра с огнем, так не ясно, какое именно значение находится сейчас в переменной. Неужели оба вида имеют шансы на существование? Если нет, то почему много как статически, так и динамически типизированных языков? Давайте разберемся.
Преимущества статической типизации [5]:
- Проверки типов происходят только один раз — на этапе компиляции. А это значит, что нам не нужно будет постоянно выяснять, не пытаемся ли мы поделить число на строку (и либо выдать ошибку, либо осуществить преобразование).
- Скорость выполнения. Из предыдущего пункта ясно, что статически типизированные языки практически всегда быстрее динамически типизированных.
- При некоторых дополнительных условиях, позволяет обнаруживать потенциальные ошибки уже на этапе компиляции.
- Ускорение разработки при поддержке IDE (отсеивание вариантов, заведомо не подходящих по типу).
Преимущества динамической типизации [5]:
- Простота создания универсальных коллекций — куч всего и вся (редко возникает такая необходимость, но когда возникает динамическая типизация выручит).
- Удобство описания обобщенных алгоритмов (например сортировка массива, которая будет работать не только на списке целых чисел, но и на списке вещественных и даже на списке строк).
- Легкость в освоении — языки с динамической типизацией обычно очень хороши для того, чтобы начать программировать.
Самый важный аргумент за динамическую типизацию — удобство описания обобщенных алгоритмов. Давайте представим себе проблему — нам нужна функция поиска по нескольким массивам (или спискам) — по массиву целых чисел, по массиву вещественных и массиву символов. Как же мы будем ее решать? Решим ее на 3-ех разных языках: одном с динамической типизацией и двух со статической.
Алгоритм поиска возьмем один из простейших — перебор. Функция будет получать искомый элемент, сам массив (или список) и возвращать индекс элемента, или, если элемент не найден — (-1).
Рис. 9 Динамическое решение на Python
Как видно из рис. 9 никаких проблем с тем, что список может содержать хоть числа, хоть списки, хоть другие массивы нет [2]. Это удобно и всё хорошо работает. Теперь решим ту же самую задачу на языке программирования С++.
Рис. 10 Статическое решение на языке программирование C++
Здесь каждая функция в отдельности похожа на версию из Python, но почему их три. Неужели статическое программирование проиграло? И да, и нет. Есть несколько методик программирования, одну из которых мы сейчас рассмотрим. Она называется обобщенное программирование, и язык C++ ее неплохо поддерживает. Давайте посмотрим на новую версию (рис. 11):
Рис. 11 Статистическое решение, обобщенное программирование C++
Реализация, показанная на рис. выглядит не сильно сложнее, чем версия на Python. Более того мы получили реализацию для всех массивов, а не только для трех, необходимых для решения задачи. В данном варианте мы совместили плюсы и статической и динамической типизации. Стоит добавить, что обобщенное программирование может быть реализовано удобнее и красивее (например в языке Haskell). Помимо обобщенного программирования также можно применить полиморфизм (результат будет хуже), перегрузку функций (аналогично) или макросы [3].
Многие статические языки позволяют использовать динамическую типизацию, например [5]:
- C# поддерживает псевдо-тип dynamic;
- F# поддерживает синтаксический сахар в виде оператора ?, на базе чего может быть реализована имитация динамической типизации;
- Haskell — динамическая типизация обеспечивается модулем Data.Dynamic;
- Delphi — посредством специального типа Variant.
Также, некоторые динамически типизированные языки позволяют воспользоваться преимуществами статической типизации:
Common Lisp — декларации типов.
Perl — с версии 5.6, довольно ограниченно.
Далее рассмотрим вопросы сильной и слабой типизации. Языки с сильной типизацией не позволяют смешивать сущности разных типов в выражениях и не выполняют никаких автоматических преобразований [7]. Также их называют «языки с строгой типизацией». Английский термин для этого — strong typing.
Слабо типизированные языки, наоборот всячески способствуют, чтобы программист смешивал разные типы в одном выражении, причем компилятор сам приведет все к единому типу. Также их называют «языки с нестрогой типизацией» [7]. Английский термин для этого — weak typing.
Слабую типизацию часто путают с динамической, что совершенно неверно. Динамически типизированный язык может быть и слабо и сильно типизирован.
Однако мало кто придает значение строгости типизации. Часто заявляют, что если язык статически типизирован, то программист сможет отловить множество потенциальных ошибок при компиляции. Это не так. Язык при этом должен иметь еще и сильную типизацию. Если компилятор вместо сообщения об ошибке будет просто прибавлять строку к числу, или что еще хуже, вычтет из одного массива другой, какая разница, если все «проверки» типов будут на этапе компиляции? Многие авторы учебников по программированию считаю, что слабая статическая типизация еще хуже, чем сильная динамическая. Рассмотри отдельно преимущества слабой и сильной типизации
Преимущества сильной типизации [5]:
- Надежность. Мы получаем исключение или ошибку компиляции, взамен неправильного поведения.
- Скорость работы программы. Вместо скрытых преобразований, которые могут быть довольно затратными, с сильной типизацией необходимо писать их явно, что заставляет программиста как минимум знать, что этот участок кода может быть медленным.
- Понимание работы программы. Вместо неявного приведения типов, программист пишет все сам, а значит, примерно понимает, что сравнение строки и числа происходит не само по себе и не по какому-либо волшебству.
- Определенность. Когда программист пишет преобразования вручную, то он точно знает, что и во что преобразуется. Также всегда понятно, что такие преобразования могут привести к потере точности и к неверным результатам.
Преимуществ слабой типизации [5]:
- удобство использования смешанных выражений (например из целых и вещественных чисел);
- абстрагирование от типизации и сосредоточение на задаче;
- краткость записи.
Далее перейдем к вопросу явной и неявной типизации.
Язык с явной типизацией предполагает, что программист должен указывать типы всех переменных и функций, которые объявляет. Английский термин для этого — explicit typing [5]. Язык с неявной типизацией, напротив, предлагает вам забыть о типах и переложить задачу вывода типов на компилятор или интерпретатор. Английский термин для этого — implicit typing [5].
Сначала можно решить, что неявная типизация равносильна динамической, а явная — статической, но дальше мы увидим, что это не так.
Есть ли плюсы у каждого вида, и опять же, есть ли их комбинации и есть ли языки с поддержкой обоих методов?
Преимущества явной типизации [5]:
- наличие у каждой функции сигнатуры (например int add(int, int)) позволяет без проблем определить, что функция делает;
- программист сразу записывает, какого типа значения могут храниться в конкретной переменной, что снимает необходимость запоминать это.
Преимущества неявной типизации [5]:
- сокращение записи — def add(x, y) явно короче, чем int add( int x, int y).
- устойчивость к изменениям. Например, если в функции временная переменная была того же типа, что и входной аргумент, то в явно типизированном языке при изменении типа входного аргумента нужно будет изменить еще и тип временной переменной.
Есть языки, с неявной типизацией по умолчанию и возможностью указать тип значений при необходимости. Настоящий тип выражения транслятор выведет автоматически. Один из таких языков — Haskell, давайте приведем простой пример, для наглядности (см. рис. 12).
Рис. 12 Явное и неявное указание типа
Как мы видим, это очень красиво и коротко. Запись функции занимает всего 18 символов на одной строчке, включая пробелы. Однако автоматический вывод типов довольно сложная вещь, и даже в таком языке как Haskell, он иногда не справляется. Есть ли языки с явной типизацией по умолчанию и неявной по необходимости? Конечно. В новом стандарте языка C++, названном C++11 (ранее назывался C++0x), было введено ключевое слово auto, благодаря которому можно заставить компилятор вывести тип, исходя из контекста (см. рис. 13)
Рис. 13 Явное и автоматическое определение типа в C++
В конце нашего исследования приведем список популярных языков программирования и опишем, как они подразделяются по каждой категории «типизации» (см. рис. 14).
Рис. 14 Классификация языков программирования по типизации
Стоит дать небольшие комментарии к рис.14 :
- C# — поддерживает динамическую типизацию, посредством специального псевдотипа dynamic с версии 4.0. Поддерживает неявную типизацию с помощью dynamic и var.
- С++ — после стандарта C++11 получил поддержку неявной типизации с помощью ключевых слов auto и decltype. Поддерживает динамическую типизацию, при использовании библиотеки Boost (boost::any, boost::variant). Имеет черты как сильной, так и слабой типизации.
- Common Lisp — стандарт предусматривает декларации типов, которые некоторые реализации могут использовать также для статической проверки типов.
- D — также поддерживает неявную типизацию.
- Delphi — поддерживает динамическую типизацию посредством специального типа Variant.
Вторая глава данной курсовой работы была посвящена вопросам типизации в различных языка программирования. Было дано определение понятию типизации. Система типов данных языка — это система, которая ставит в соответствие каждому значению, вычисленному в процессе выполнения программы, свой тип данных [8]. Описаны основные функции систем типов данных. Были подробно рассмотрены вопросы статической и динамической типизации, вопросы строгой и нестрогой типизации. В конце главы представлена классификация по типизации современных высокоуровненвых языков программирования.
ЗАКЛЮЧЕНИЕ
Данная курсовая работа была посвящена понятию переменной в программировании, а также видам и типам переменных. Актуальность данной работы заключалась в том, что ни одна программа не обходится без переменных и поэтому программист должен глубоко разбираться в видах переменных, уметь работать с ними.
Объектами исследования в данной курсовой работе являлись переменная в программировании и типы данных.
Целью данной работы было проведение всестороннего исследования понятия переменная в различных современных языках программирования.
Исходя из поставленной цели работы в ходе работы, были решены следующие задачи:
1. Дано определение понятию «переменная».
2. Дана трактовку переменной для программирования.
3. Исследованы свойства переменных в различных языках программирования.
4. Рассмотрены понятия «тип данных».
5. Исследованы различные варианты типизации в программировании.
Курсовая работа была логически разбита на две главы. В первой главе были решении первые четыре поставленные задачи. Решению пятой задачи была посвящена вторая глава курсовой работы.
По итогам работы можно сделать следующие выводы:
1 Под переменной в языках программирования понимают программный объект (число, слово, часть слова, несколько слов, символы), имеющий имя и значение, которое может быть получено и изменено программой [5].
2. Ни одна программа не обходится без переменных.
3. Все программы работаю с данными. Данные могут быть представлены в виде документа, графического фрагмента, видеоигры или мгновенного сообщения. Для их хранения программа использует именно переменные. Каждая переменная характеризуется следующими атрибутами [3]:
- именем;
- типом данных;
- значением;
- временем жизни;
- областью видимости.
4. общие правила именования переменных, которые характерны для всех языков программирования [5]:
- всегда начинаться с буквы, после которой могут другие буквы или цифры;
- в идентификаторе (имени) не должно быть пробелов, запятых или других непредусмотренных знаков;
- нельзя использовать в качестве имен переменных слова, которые являются служебными или операторами.
5. Тип данных характеризует внутреннее представление, множество допустимых значений для этих данных, а также совокупность операций над ними [5]
6. Переменные обязательно необходимо инициализировать.
7. Любая переменная обладает еще двумя основными характеристиками: временем жизни и областью видимости [3]. Они зависят от места и способа описания переменной.
8. Система типов данных языка — это система, которая ставит в соответствие каждому значению, вычисленному в процессе выполнения программы, свой тип данных [8].
9. Языки программирования по типизации принято делить на два больших лагеря — типизированные и нетипизированные (бестиповые). К первому, например относятся C, Python, Scala, PHP и Lua, а ко второму — язык ассемблера, Forth и Brainfuck [5].
10. Преимущества сильной типизации [5]:
- Надежность. Мы получаем исключение или ошибку компиляции, взамен неправильного поведения.
- Скорость работы программы. Вместо скрытых преобразований, которые могут быть довольно затратными, с сильной типизацией необходимо писать их явно, что заставляет программиста как минимум знать, что этот участок кода может быть медленным.
- Понимание работы программы. Вместо неявного приведения типов, программист пишет все сам, а значит, примерно понимает, что сравнение строки и числа происходит не само по себе и не по какому-либо волшебству.
- Определенность. Когда программист пишет преобразования вручную, то он точно знает, что и во что преобразуется. Также всегда понятно, что такие преобразования могут привести к потере точности и к неверным результатам.
11. Преимущества слабой типизации [5]:
- удобство использования смешанных выражений (например из целых и вещественных чисел);
- абстрагирование от типизации и сосредоточение на задаче;
- краткость записи.
Таким образом, все задачи курсовой работы выполнены. Цель работы достигнута.
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. Калашников О.А. Ассемблер – это просто. Учимся программировать. – 4-е изд., перераб. и доп. – СПб.: БХВ-Петербург, 2016 – 336 с.
2. МакГрат Майк. Программирование на Python для начинающих: [перевод с англ. М.А. Райтмана] / Майк МакГрат. – Москва: Эксмо, 2015 – 192 с. – (Программирование для начинающих).
3. Павловская Т. А., Щупак Ю.А. C/C++. Структурное и объектно-ориентированное программирование: Практикум. – СПб.: Питер, 2017. – 352 с.: ил. – (Серия «Учебное пособие»).
4. Стиллмен Э., Грин Дж. Изучаем C#. 4-е изд. – СПб.: Питер, 2016. – 816 с.: ил. – (Серия «Head First O’Reilly»).
5. Тюгашев А.А. Основы программирования. Часть I. – СПб.: Университет ИТМО, 2016. – 160 с.
6. Статья на сайте русскоязычной Википедии «Переменная (программирование)»: https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
7. Статья русскоязычной Википедии «Система типов» https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2
8. Прогопедия. Статья «Типизация». http://progopedia.ru/typing/
- Офис управления проектами: функции, структура, особенности формирования (Общие подходы к управлению)
- Оценка результативности деятельности персонала организации
- Офис управления проектами: функции, структура, особенности формирования (Теоретические аспекты проектного управления)
- Методы управления инновационными проектами
- Использование в современной организации двухфакторной модели мотивации менеджеров и сотрудников (по Ф. Герцбергу)
- Эффективность менеджмента организации(Понятие менеджмента и его основные характеристики)
- Формирование ассортимента товаров на предприятиях торговли (на примере ООО «T-best»)
- Учет внешнего окружения (среды) при выработке стратегии
- Анализ конкурентов на рынке и определение собственной конкурентоспособности (на примере ООО «Фольксваген центр Евразия») (Теоретические основы конкурентоспособности предприятия)
- Разработка регламента выполнения процесса «Складской учет» (Описание принципов организации складского учета)
- Отладка и тестирование программ: основные подходы и ограничения
- Разработка проекта подсистемы учета реализации товаров в оптовой торговле