Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

пОНЯТИЕ ПЕРЕМЕННОЙ В ПРОГРАММИРОВАНИИ.виды и типы переменных

Содержание:

Введение

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

Объектом исследования является виды и типы переменных в программировании.

Предметом исследования является переменная.

При написании данной курсовой работы я использовал труды таких писателей и ученных как: нашего соотечественник, переводчика учебников по программированию Александр Пирамидин, Брайана Кернигана и Денниса Ритчи, причём последний — один из непосредственных авторов и разработчиков языка Си, а также Линды Дейли Полсон, книга которой «Разработчики переходят на динамические языки» очень помогла мне детально разобраться в динамических языках программирования.

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

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

Для достижения поставленных целей необходимо выполнить следующие задачи:

- понять роль переменной в программировании;

- изучить статические и динамические переменные;

- изучить локальные и глобальные переменные;

-изучить типы переменных;

- понять значение систем проведения проверки соответствия типов переменных;

- сделать вывод какой же способ типизации лучше статический или динамический;

1.ПОНЯТИЕ ПЕРЕМЕННОЙ В ПРОГРАММИРОВАНИИ

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

Переменная характеризуется:

  • Именем («обозначением ячейки памяти»)
  • Значением (данными, содержащимися в переменной в конкретный момент времени)
  • Типом (определяющим: а) какие значения может принимать переменная; б) какие операции можно производить с этими значениями; в) как данные представлены в памяти компьютера)

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


Хорошим стилем является осмысленное именование переменных. Разрешается использовать строчные и прописные буквы, цифры и символ подчёркивания, который в Си считается буквой. Первым символом обязательно должна быть буква, в имени переменной не должно быть пробелов. В современных версиях компиляторов длина имени практически не ограничена. Имя переменной не может совпадать с зарезервированными ключевыми словами. Заглавные и строчные буквы в именах переменных различаются, переменные a и A — разные переменные.
В языке Си все переменные должны быть объявлены. Это означает, что, во-первых, в начале каждой программы или функции Вы должны привести список всех используемых переменных, а во-вторых, указать тип каждой из них.

2. СТАТИЧЕСКИЕ И ДИНАМИЧЕСКИЕ ПЕРЕМЕННЫЕ

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

Статическая переменная (или еще как её называют «переменная со статической продолжительностью») сохраняет свое значение даже после выхода из блока, в котором она определена. То есть она создается (и инициализируется) только один раз, а затем сохраняется на протяжении всей программы. Соответственно время жизни статических переменных определяется: от загрузки до выгрузки mql4-программы.

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

Пример статистической переменной через свойство функции в языке JavaScript:

function incr(){

return incr.count++;

}

incr.count = 0; // начальное значение

incr();

incr();

incr();

incr(); // 3

Динамическая переменная — такая переменная в программе, под которую выделяется место в оперативной памяти в то время, когда программа выполняется. Во время работы программы она является участком памяти, выделенным системой программе для конкретных целей. Это и есть её главная отличительная черта по сравнению с глобальной статической переменной - участка памяти, выделенного системой программе для конкретных целей перед началом работы программы.

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

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

Пример создания динамической переменной с помощью указателя в языке Pascal:

type tMyArray = array [1..3] of real;

var pMyArray = ^tMyArray;

begin

new (pMyArray); {выделение памяти под массив из трех чисел}

pMyArray^[1] := 1.23456;

pMyArray^[2] := 2.71828;

pMyArray^[3] := 3.14159;

......

Указатели используются явно в языках программирования относительно низкого уровня, что в большинстве случаев оборачивается серьёзными ошибками. В языках более высокого уровня динамические типы данных могут быть оформлены как динамические массивы — это массивы такого размера, которые могут «динамически» изменяться при выполнении программы (например, — уменьшаться после выгрузки неактуальных данных)

Пример создания динамического массива в языке Delphi:

var MyArray = array of real;

begin

SetLength(MyArray,3); {выделение памяти под массив из трех чисел}

MyArray[0] := 1.23456; {в Delphi динамические массивы нумеруются в си-образном стиле: от 0 до n-1}

MyArray[1] := 2.71828;

MyArray[2] := 3.14159;

......

2.2 ЛОКАЛЬНЫЕ И ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ. ОБЛАСТЬ ВИДИМОСТИ.

Область видимости (англ. scope) обозначает такая область программы, в пределах которой идентификатор (имя) некоторой переменной продолжает быть связанным с этой переменной и возвращать её значение. За пределами области видимости один и тот же идентификатор может быть свободным (не связанным ни с какой из них, либо быть связан с другой переменной).

В большинстве языков программирования область видимости переменной определяется местом её объявления. А также, область видимости может задаваться с помощью пространств имён или классов памяти.

Для языков разметки область видимости также может иметь смысл: например, в HTML областью видимости имени элемента управления является форма (HTML) от <form> до </form>.

Виды переменных по области видимости

В языках, поддерживающих структурное программирование, переменные в большинстве случаев разделяются на два типа по области видимости:

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

- Локальные переменные — объявляются внутри функции и недоступны снаружи неё. То есть Локальной областью видимости называют любую область видимости, определённую после глобальной.

В объектно-ориентированном программировании каждый объект содержит три специфические области видимости:

- Закрытая (англ. private) — переменная используется только в реализации объекта;

- Общедоступная (англ. public) — переменная используется только при инициализации и использовании объекта;

- Защищённая (англ. protected) — переменная используется, только в реализации объекта или его потомка.

Подробно рассмотрим глобальные и локальные переменные.

Как мы уже знаем по зоне видимости различают локальные и глобальные переменные. Локальные переменные доступны только конкретной подпрограмме, а вот глобальные переменны всей программе. С распространением объектного и модульного программирования, появились ещё и так называемые общие переменные (которые доступные только для определённых уровней иерархии подпрограмм). Область видимости в некоторых случаях задаётся классом памяти, а ограничение видимости может производиться путём введения пространств имён.

Локальной переменной принято называть переменную, объявленную внутри блока кода. Область видимости локальной переменной начинается в точке её объявления и заканчивается в конце этого блока. Например, в языке Си локальными являются переменные объявленные внутри блока или функции (в Си, блоки ограничиваются фигурными скобками {и}).

Существуют языки программирования такие как JavaScript, которые разрешают создавать локальные переменные только в теле функции, а переменные объявленные внутри блоков добавляются в область видимости функции.

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

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

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

Локальной переменной может является любой параметр функции (например, в языке Си), который не использует ссылок или указателей.

Рассмотрим локальные переменные в языке Ruby:

#include <stdio.h>

int a = 0; // глобальная переменная

int main()

{

printf("%d", a); // будет выведено число 0

{

int a = 1; // объявлена локальная переменная а, глобальная переменная a не видна

printf("%d", a); // будет выведено число 1

{

int a = 2; // еще локальная переменная в блоке, глобальная переменная a не видна, не видна и предыдущая локальная переменная

printf("%d", a); // будет выведено число 2

}

}

}

В этом случае запись сделана следующим образом: имени глобальной переменной должен предшествовать знак $, например, $variable_name, в то время как локальная переменная просто не имеет знака $ перед её именем, например, variable_name (в то время как в Perl все скалярные значения имеют $ спереди).

Глобальной переменной называют такую переменную, областью видимости которой является целая программа (кроме затенённых (англ.) областей). Механизмы взаимодействия с глобальными переменными называют механизмами доступа к глобальному окружению или состоянию (англ. global environment). Глобальные переменные в основном могут использоваться для взаимодействия между функциями и процедурами или как альтернатива передачи аргументов и возвращения значений.

Глобальные переменные имею ряд недостатков:

1.Глобальная переменная может быть изменена в любой точке программы (если только она не объявлена как переменная только для чтения) или не располагается в защищённой памяти, что скорее всего повлияет на работу других частей программы. По этой причине глобальные переменные имеют неограниченный потенциал для создания взаимных зависимостей, что приводит к усложнению программы.

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

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

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

С увеличением количества переменных, увеличивается вероятность взаимных блокировок.

Например, на языке С/С++ можно привести следующие примеры кода:

int a; /* Объявление глобальной целочисленной переменной «а» */

float b = 6; /* Объявление глобальной переменной с плавающей запятой «b» и присваивание ей значения «6» */

int main(void)

{

a = 12; /* Присваивание переменной «а» значения «12» */

return a+b;

}

2.3 ТИПЫ ПЕРЕМЕННЫХ

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

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

2.Сложные типы —состоят из несколько примитивных типов, например, массив или запись (но не хэш). Все сложные типы считаются структурами данных.

3.Абстрактные типы — типы, у которых нет конкретной реализации, такие как хэш, множество, очередь и стек.

4.Прочие типы — например, указатели (тип, в значении которого хранится ссылка на другое место в памяти).

Подробнее рассмотрим простые и сложные типы переменных так они более распространены.

Простые типы в свою очередь делятся на:

1.Дискретные (можно перечислить возможные значения):

  • целые (integer, longint)
  • символьный (char)
  • логический (boolean)
  • диапазон (часть значений стандартного дискретного типа, например, 1..100)
  • перечисляемый (явно перечислены все допустмые значения)

2. Вещественные (real, double, extended) — служат для представления действительных чисел с ограниченной точностью.

В основном простые типы — это типы о объектах, которых, постоянных или переменных, можно сказать следующее:

1. Работа осуществляется с помощью конструкций языка;

2. Внутреннее представление значений объектов зависит от реализации транслятора (интерпретатора или компилятора) и соответственно от платформы;

3. Основой для построения других объектов служат объекты, которые не включают в себя другие объекты.

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

В каждом языке программирования доступны разные простые типы данных. В некоторых языках для контролеров с программируемой логикой имеются простые типы для хранения времени. Способы записи констант разных типов определяются стандартом языка. Например, запись 1 может описывать константу целого типа, а запись 1.0 - вещественного.

Введение простых типов преследовало несколько целей:

  1. Упрощение жизни программистов путём предоставления стандартных контейнеров для размещения данных;
  2. Предотвращение ошибок и неоднозначностей, связанных со случайным или преднамеренным доступом к внутреннему представлению значений простых типов.
  3. Предотвращение логических ошибок (ошибок программиста), связанных с применением к данным несвойственных им команд;

Большое количество языков программирования содержат предопределённые функции для работы с простыми типами:

- функция для получения знака числа;

- функция для проверки чётности/нечётности числа

- функция для получения модуля числа;

- функции для приведения типов с округлением или без.

- функции для получения целой и дробной частей вещественного числа;

Некоторые языки (например, C и C++) не ограничивают программиста в выборе способа обработки значений простых типов, даже позволяют определить поля для простого типа.

Сложные или структурированные типы

  • Массив (фиксированное количество данных одного типа)
  • Строка
  • Запись (связанные данные, в общем случае, разных типов)
  • Множество
  • Файл (данные одного типа, хранящиеся на внешнем носителе)

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

Очень важной идеей, родившейся на границе 60-70-х годов XX века, является возможность произвольного конструирования нужных структур из небольшого набора предопределённых типов. Чем адекватнее программист смоделировал обрабатываемые данные в рамках такого «конструктора», тем безошибочнее и долговечнее будет разработанная программа.

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

Integer (простой) – целый тип. Переменные этого типа могут хранить целые числа в диапазоне от −2147483648 до 2147483647 (это −231 и 231−1).

Real (сложный) – вещественный тип. Так называемые числа с плавающей точкой. Может быть обычной десятичной дробью (например, 1234.543), но может также содержать порядок – символ «е» и какое-либо число за ним, например, 1.2345е3. Такая запись означает, что число 1.2345 нужно умножить на 103. Максимальное количество цифр в числе 15, порядок может быть в диапазоне от −308 до 308.

Char (простой) – символьный тип. Значением этой переменной может быть одиночный символ – буква латинского алфавита (большие и малые буквы здесь различаются), цифра или какой-либо из специальных символов.

String(сложный) – строка. Значения — наборы символов.

Boolean(простой) – логический тип. Переменная может принимать два значения: true (истина) и false (ложь). Такие значения могут быть, например, у логических выражений наподобие «x>2». Если истинно, что x>2, то выражение принимает значение true иначе значение false.

2.4 ПРОВЕРКА СООТВЕТСТВИЯ ТИПОВ ПЕРЕМЕННЫХ

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

Существование типов не имеет смысла без процесса подтверждения того, что эти типы имеют логический смысл и программа может быть корректно исполнена. Тут и приходит на помощь проверка соответствия типов. Это процесс подтверждения и применения ограничений типов, и он может проходить как во время компиляции (т.е. статически), так и во время выполнения (т.е. динамически). Проверка соответствия типов нужна, чтобы убедиться в типобезопасности программы, что сведёт количество ошибок, связанных с типами, к минимуму. Это такие ошибки, которые возникают, когда операция производится с тем типом, с каким она производиться не должна: например, когда целое число принимается за число с плавающей запятой, или когда происходит сложения строки и целого: x = 1 + "2"

Хотя во многих языках и строки, и числа могут использовать оператор +, это зачастую приводит к ошибкам типа, поскольку это выражение обычно не работает с разными типами данных.

Для случая не типобезопасной программы единого алгоритма действий нет. Какие-то языки выдают ошибку типа, которая останавливает компиляцию или выполнение, а в каких-то есть встроенные обработчики таких ошибок (что позволяет разработчикам порой ошибаться при работе с типами). Вне зависимости от этого, процесс проверки типов — это необходимость.

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

- Языки со статической типизацией (static typing languages).

- Языки с динамической типизацией (dynamic typing languages).

- Языки с постепенной типизацией (gradual typing languages).

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

Статическая типизация — широко используемый приём в языках программирования при котором параметр подпрограммы, переменная возвращаемое значение функции связывается с типом в момент объявления и тип не может быть изменён в последующим (параметр или переменная будут принимать, а функция — возвращать значения только этого типа). Существуют такие примеры статически типизированных языков — С++, Ада, D, Паскаль, Nim , Java, ML.

Статические языки проверяют типы в программе во время компиляции, еще до запуска программы. Любая программа, в которой типы нарушают правила языка, считается некорректной. Например, большинство статических языков отклонит выражение "a" + 1 (язык Си — это исключение из этого правила). Компилятор знает, что "a" — это строка, а 1 — это целое число, и что + работает только когда левая и правая часть относятся к одному типу. Так что ему не нужно запускать программу чтобы понять, что существует проблема. Каждое выражение в статически типизированном языке относится к определенному типу, который можно определить без запуска кода.


Многие статически типизированные языки требуют обозначать тип. Функция в Java выглядит следующим образом public int add(int x, int y) принимает два целых числа и возвращает третье целое число. Другие статически типизированные языки могут определить тип автоматически. Та же самая функция сложения в Haskell выглядит так: add x y = x + y. Мы не сообщаем языку типы, но он может определить их сам, потому что знает, что + работает только на числах, так что x и y должны быть числами, значит функция add принимает два числа как аргументы.

Это не уменьшает "статичность" системы типов. Система типов в Haskell знаменита своей статичностью, строгостью и мощностью, и по всем этим фронтам Haskell опережает Java.

Преимущества статической типизации заключаются в следующем:

  1. Статическая типизация даёт самый простой машинный код. Поэтому для языков, дающих исполняемые файлы ОС или JIT-компилируемые промежуточные коды она очень удобна.
  2. Большинство ошибок исключаются уже на стадии компиляции. 3.
  3. Статическая типизация хорошо подходит для написания сложного, но быстрого кода.
  4. В интегрированной среде разработки релевантное автодополнение более осуществимо, особенно если типизация — сильная статическая: можно отбросить множество вариантов как не подходящие по типу.
  5. Чем проект больше и сложнее в реализации, тем большее преимущество дает использование статической типизации.

К недостаткам статической типизации относятся:

  1. Языки с недостаточно проработанной математической базой оказываются довольно многословными: каждый раз нужно указывать, какого типа будет переменная. В некоторых языках присутствует автоматическое выведение типа, но оно может привести к труднонаходимым ошибкам. IDE функции нивелируется, например, quick fix.

Но для языков семейства ML это не является недостатком так как они основаны на «главной типизации» которая одновременно автоматически выводит наиболее общий тип всякого выражения и строго проверяет согласование типов зависимостей. Это придаёт языку выразительность динамически типизируемых, но обеспечивает лучшую типобезопасность и быстродействие.

  1. Очень тяжело и неудобно работать с данными из внешних источников (например, в десериализации данных и реляционных СУБД).

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

Динамически типизированные языки не требуют указывать тип, но и не определяют его сами. Типы переменных неизвестны до того момента, когда у них есть конкретные значения при запуске.

Например, функция в Python

def f(x, y):

return x + y

Даная функция может складывать два целых числа, склеивать строки, списки и так далее, и мы не можем понять, что именно происходит, пока не запустим программу. Возможно, в какой-то момент функцию f вызовут с двумя строками, и с двумя числами в другой момент. В таком случае x и y будут содержать значения разных типов в разное время. Поэтому говорят, что значения в динамических языках обладают типом, но переменные и функции — нет. Значение 1 это определенно integer, но x и y могут быть чем угодно.

Также можно привести пример динамической типизации в таких языках как:

В языке программирования Lua;

var="string" -- Переменная строкового типа

var={} -- Переменная стала таблицей

oldprint=print

print=1 -- Такое тоже возможно!

print("somestring") -- attempt to call a nil value

oldprint("somestring") – somestring

В языке программирования JavaScript;

var res = "string1"; alert(res); // выводит 'string1'

res = 1; alert(res); // выводит 1

res += 2; alert(res); // выводит 3

res += 'string2'; alert(res); // выводит '3string2'

К преимущества динамической типизации можно отнести:

  1. Значительно упрощенное написание несложных программ, например, различных скриптов.
  2. Работа прикладного программиста с СУБД значительно облегчается. СУБД принципиально возвращают информацию в динамически типизированном» виде. Поэтому ценность динамических языков очень большая, например, для программирования веб-служб.
  3. В некоторых случаях требуется работать с данными переменного типа. Например, функция поиска подстроки возвращает позицию найденного символа (число) или маркер «не найдено». В языке программирования PHP этот маркер — булевое false. В языках с использованием статической типизацией это особая константа (std::string::npos в C++ и 0 в Паскале).

К недостаткам динамическая типизация относятся:

  1. Для динамической типизации требуется как минимум выполнить данный участок кода.
  2. Не действует в объектно-ориентированных языках, либо действует с значительными ограничениями, автодополнение: невозможно или трудно понять, к какому типу относится переменная, и вывести набор её методов и полей.
  3. Динамическая типизация по определению не проявляет свойства самодокументирования, что затрудняет разработку структурно сложных программ.
  4. Ощутимое снижение производительности из-за большого количества затрат процессорного времени на динамическую проверку типа, и излишние расходы памяти на переменные, которые могут хранить «что угодно». А также большинство языков с динамической типизацией не компилируемые, а интерпретируемые.

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

В некоторых языках есть опциональная или постепенная типизация (gradual typing): они динамические по умолчанию, но позволяют добавлять некоторые статические аннотации. В Python недавно добавили опциональные типы; TypeScript — это надстройка над JavaScript, в котором есть опциональные типы; Flow производит статический анализ старого доброго кода на JavaScript.


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

2.1.1 СРАВНЕНИЕ СТАТИСТИЧЕСКОЙ И ДИНАМИЧЕСКОЙ СИСТЕМЫ ТИПИЗАЦИИ

Большинство динамических языков выдадут ошибку, если типы используются некорректно (JavaScript — известное исключение; он пытается вернуть значение для любого выражения, даже когда оно не имеет смысла). При использовании динамически типизированных языков даже простая ошибка вида "a" + 1 может возникнуть в боевом окружении. Статические языки предотвращают такие ошибки, но, конечно, степень предотвращения зависит от мощности системы типов.

Статические и динамические языки построены на фундаментально разных идеях о корректности программ. В динамическом языке "a" + 1 это корректная программа: код будет запущен и появится ошибка в среде исполнения. Однако, в большинстве статически типизированных языков выражение "a" + 1 — это не программа: она не будет скомпилирована и не будет запущена. Это некорректный код, так же, как набор случайных символов! &%^@*&%^@* — это некорректный код. Это дополнительное понятие о корректности и некорректности не имеет эквивалента в динамических языках.

Статическая типизация имеет место если тип данных определяется на этапе компиляции, а если на этапе выполнения программы, то динамическая. Иногда говорят, что переменная не имеет типа, хотя содержащиеся в ней данные, относятся к определённому типу данных, но выясняется это уже в то время, когда программа выполняется.

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

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


Сторонники динамических языков указывают на то, что на таких языках, кажется, легче писать код. Это определенно справедливо для некоторых видов кода, который мы время от времени пишем, как, например, тот код с eval.

JavaScript пытается продолжить работу, даже если это означает бессмысленную конвертацию (вроде "a" + 1, дающее "a1"). Python в свою очередь старается быть консервативным и часто возвращает ошибки, как в случае с "a" + 1.

Существуют разные подходы с разными уровнями безопасности, но Python и JavaScript оба являются динамически типизированными языками.

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

Haskell же не позволит сложить integer и float без явного преобразования перед этим. Си и Haskell оба являются статически типизированными, не смотря на такие большие отличия.

Заключение

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

Итак, подводя итоги, можно констатировать следующее:

1.Понятие переменной - важнейшее понятие в программировании. Переменная используется для хранения различных данных в языках программирования и характеризуется именем, значением и типом.

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

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

4.Что типы можно разбить на категории простые, сложные, абстрактные и прочие типы. В основном используются простые и сложные типы. В каждом языке программирования доступны разные простые типы данных. В некоторых языках для контролеров с программируемой логикой имеются простые типы для хранения времени, а набор базовых сложных типов может отличаться чаще по названию и деталям реализации. Но также у сложных типов есть и объективные критерии — однотипность элементов и способ доступа, позволяющие выделить главные представители сложных типов.

5.Понято, что существование типов не имеет смысла без процесса подтверждения того, что эти типы имеют логический смысл и программа может быть корректно исполнена. Тут и приходит на помощь проверка соответствия типов. Это процесс подтверждения и применения ограничений типов, и он может проходить как во время компиляции (т.е. статически), так и во время выполнения (т.е. динамически). Проверка соответствия типов нужна, чтобы убедиться в типобезопасности программы, что сведёт количество ошибок, связанных с типами, к минимуму.

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

Список литературы

  1. А. Пирамидин. Учебник РНР в переводе на русском и авторском дополнении. –– М.: 2014.
  2. Брайан У. Керниган, Деннис М. Ритчи. «Язык программирования Си». –– М.:2005
  3. Линда Дейли Полсон. Разработчики переходят на динамические языки. –– М.:2007
  4. Агафонов, В.Н. Логическое программирование. – М.: 2018. - 936 c.
  5. Ашманов, С.А. Линейное программирование. - М.: 2010. - 520 c.
  6. Кнут, Д.Э. Искусство программирования (Том 1. Основные алгоритмы) – М.: 2009. - 228 c.
  7. Кнут, Д.Э. Искусство программирования (Том 2. Получисленные алгоритмы) - М.: 2010. - 386 c.
  8. Кнут, Д.Э. Искусство программирования (Том 3) - М.: 2011. - 125 c.
  9. Спольски Джоэл о программировании / Спольски, Джоэл. - М.: СПб: Символ-Плюс, 2006. - 352 c.
  10. Урман Oracle 8. Программирование на языке PL/SQL. Руководство для программистов Oracle / Урман, Скотт. - М.: ЛОРИ, 2014. - 610 c.
  11. Виленкин Н.Я., Виленкин А.Н., Виленкин П.А. Комбинаторика. –– ФИМА, МЦНМО, 2006.
  12. Дасгупта С., Пападимитриу Х., Вазирани У. Алгоритмы. –– М.: МНЦМО, 2014
  13. Achour Mehdi и др. Аргументы функции // Руководство по PHP. –– 2015