Файл: Понятие переменной в программировании. Виды и типы переменных (Понятие Переменная в программировании).pdf
Добавлен: 31.03.2023
Просмотров: 83
Скачиваний: 2
В случае, когда разрабатываемое приложение состоит из нескольких форм и в них используются одни и те же переменные, то эти общие для всех форм и процедур переменные следуют объявлять в разделе General Declarations программного модуля Module. Такие переменные называются глобальными в приложении.
В кратком и в систематизированном виде все изложенное выше приведено в следующей таблице.
Область видимости переменных и их объявление
Область видимости переменной |
Место объявления |
Глобальная в приложении |
В разделе General Declarations программного модуля Module оператором Public |
Локальная в форме |
В разделе General Declarations формы оператором Dim или Public |
Локальная в процедуре |
В процедуре оператором Dim или Static |
Классификация
Статическая и динамическая типизация переменных
Статическая типизация — приём, широко используемый в языках программирования, при котором переменная, параметр подпрограммы, возвращаемое значение функции связывается с типом в момент объявления и тип не может быть изменён позже (переменная или параметр будут принимать, а функция — возвращать значения только этого типа). Примеры статически типизированных языков — Ада, С++, D, Java, ML, Паскаль.
Преимущества:
- Статическая типизация даёт самый простой машинный код. Поэтому она удобна для языков, дающих исполняемые файлы ОС или JIT-компилируемые промежуточные коды.
- Многие ошибки исключаются уже на стадии компиляции.
- Поэтому статическая типизация хороша для написания сложного, но быстрого кода.
- В интегрированной среде разработки осуществимо более релевантное автодополнение, особенно если типизация — строгая статическая: множество вариантов можно отбросить как не подходящие по типу.
- Чем больше и сложнее проект, тем большее преимущество дает статическая типизация, и наоборот.
Недостатки:
- Языки с недостаточно проработанной математической базой оказываются довольно многословными: каждый раз надо указывать, какой тип будет иметь переменная. В некоторых языках есть автоматическое выведение типа, однако оно может привести к трудноуловимым ошибкам. Нивелируется функциями IDE вроде quick fix.
- Тяжело работать с данными из внешних источников (например, в реляционных СУБД / десериализация данных).
Динамическая типизация — приём, широко используемый в языках программирования и языках спецификации, при котором переменная связывается с типом в момент присваивания значения, а не в момент объявления переменной. Таким образом, в различных участках программы одна и та же переменная может принимать значения разных типов. Примеры языков с динамической типизацией — Smalltalk, Python, Objective-C, Ruby, PHP, Perl, JavaScript, Lisp, xBase, Erlang.
В некоторых языках со слабой динамической типизацией стоит проблема сравнения величин, так, например, PHP имеет операции сравнения «==», «!=» и «===», «!==», где вторая пара операций сравнивает и значения, и типы переменных. Операция «===» даёт true только при полном совпадении, в отличие от «==», который считает верным такое выражение: (1=="1"). Стоит отметить, что это проблема не динамической типизации в целом, а конкретных языков программирования.
Преимущества:
-
- Упрощается написание несложных программ, например, скриптов.
- Облегчается работа прикладного программиста с СУБД, которые принципиально возвращают информацию в «динамически типизированном» виде. Поэтому динамические языки ценны, например, для программирования веб-служб.
- Иногда требуется работать с данными переменного типа. Например, функция поиска подстроки возвращает позицию найденного символа (число) или маркер «не найдено». В PHP этот маркер — булевое false. В языках со статической типизацией это особая константа (0 в Паскале, std::string::npos в C++).
Недостатки:
- Статическая типизация позволяет уже при компиляции заметить простые ошибки «по недосмотру». Для динамической типизации требуется как минимум выполнить данный участок кода.
- Особенно коварны в динамическом языке программирования опечатки: разработчик может несколько раз просмотреть неработающий код и ничего не увидеть, пока наконец не найдёт набранный с ошибкой идентификатор.
- В объектно-ориентированных языках не действует, либо действует с ограничениями, автодополнение: трудно или невозможно понять, к какому типу относится переменная, и вывести набор её полей и методов.
- Развитая статическая система типов (такая как Хиндли-Милнер) играет значительную роль в самодокументировании программы[1]; динамическая типизация по определению не проявляет этого свойства, что затрудняет разработку структурно сложных программ.
- Снижение производительности из-за трат процессорного времени на динамическую проверку типа, и излишние расходы памяти на переменные, которые могут хранить «что угодно». К тому же большинство языков с динамической типизацией интерпретируемые, а не компилируемые.
- Невозможна перегрузка процедур и функций по типу данных — только по количеству операндов.
Если тип данных определяется на этапе компиляции, имеет место статическая типизация, а если на этапе выполнения программы — динамическая. В последнем случае иногда говорят, что переменная не имеет типа, хотя данные, содержащиеся в ней, безусловно, относятся к определённому типу данных, но выясняется это уже во время выполнения программы.
В большинстве случаев статическая типизация позволяет уменьшить затраты ресурсов при выполнении программы, поскольку для динамической типизации требуются затраты ресурсов на выяснение типов данных и их приведение в выражениях со смешанными типами. Статическая типизация позволяет проводить проверку типов на этапе компиляции программы. Это также упрощает обнаружение ошибок ещё на этапе разработки, когда их исправление обходится менее дорого.
Тем не менее, во многих случаях необходимо применение динамической типизации. Например, необходимость поддержания совместимости при переходе на новый формат представления данных (например, старая часть проекта посылает процедуре дату символьной строкой, а новые объекты используют более современный числовой тип).
Статические и динамические переменные
Адрес поименованной ячейки памяти также может определяться как на этапе компиляции, так и во время выполнения программы. По времени создания переменные бывают статическими и динамическими. Первые создаются в момент запуска программы или подпрограммы, а вторые создаются в процессе выполнения программы.
Динамическая адресация нужна только тогда, когда количество поступающих на хранение данных заранее точно не известно. Такие данные размещают в специальных динамических структурах, тип которой выбирается в соответствии со спецификой задачи и с возможностями выбранной системы программирования. Это может быть стек, куча, очередь и т. п. Даже файл, в том смысле, который заложил Н. Вирт в Паскаль, является динамической структурой.
Локальные и глобальные переменные. Области видимости
По зоне видимости различают локальные и глобальные переменные. Первые доступны только конкретной подпрограмме, вторые — всей программе. С распространением модульного и объектного программирования, появились ещё и общие переменные (доступные для определённых уровней иерархии подпрограмм). Область видимости иногда задаётся классом памяти. Ограничение видимости может производиться путём введения пространств имён.
Ограничение зоны видимости придумали как для возможности использовать одинаковые имена переменных (что разумно, когда в разных подпрограммах переменные выполняют похожую функцию), так и для защиты от ошибок, связанных с неправомерным использованием переменных (правда, для этого программист должен владеть и пользоваться соответствующей логикой при структуризации данных).
Простые и сложные переменные
По наличию внутренней структуры, переменные могут быть простыми или сложными (составными).
Простые переменные не имеют внутренней структуры, доступной для адресации. Последняя оговорка важна потому, что для компилятора или процессора переменная может быть сколь угодно сложной, но конкретная система (язык) программирования скрывает от программиста её внутреннюю структуру, позволяя адресоваться только «в целом».
Рассмотрим подробнее простой тип.
Простым типом в информатике называют тип данных, о объектах которого, переменных или постоянных, можно сказать следующее:
- работа с объектами осуществляется с помощью конструкций языка;
- внутреннее представление значений объектов может зависеть от реализации транслятора (компилятора или интерпретатора) и от платформы;
- объекты не включают в себя другие объекты и служат основой для построения других объектов (см. составной (сложный) тип).
Создание переносимого кода (кода, результат компилирования/интерпретации которого разными трансляторами одинаков на разных платформах) возможно, если не пытаться интерпретировать значения простых типов. Например, на разных платформах числа могут отличаться основанием системы счисления, разрядностью, порядком байт, форматом представления. При работе форматами представления чисел код выполняется быстрее, но переносимость теряется.
Как правило, к простым относятся числовые типы:
- целочисленные типы:
- типы для хранения целых чисел с разной точностью;
- типы для хранения символов строк;
- тип для хранения значений true и false;
- тип для хранения одного значения из конечного множества;
- вещественные типы:
- типы для хранения вещественных чисел с разной точностью;
- и другие.
В каждом языке программирования доступны разные простые типы данных. Например, в некоторых языках для контролеров с программируемой логикой имеются простые типы для хранения времени. Способы записи констант разных типов определяются стандартом языка. Например, запись 1 может описывать константу целого типа, а запись 1.0 - вещественного.
Введение простых типов преследовало несколько целей:
-
- упрощение жизни программистов путём предоставления стандартных контейнеров для размещения данных;
- предотвращение логических ошибок (ошибок программиста), связанных с применением к данным несвойственных им команд;
- предотвращение ошибок и неоднозначностей, связанных со случайным или преднамеренным доступом к внутреннему представлению значений простых типов.
Большинство языков программирования содержат предопределённые функции для работы с простыми типами:
-
- функция для получения знака числа;
- функция для получения модуля числа;
- функция для проверки чётности/нечётности числа;
- функции для получения целой и дробной частей вещественного числа;
- функции для приведения типов с округлением или без.
Некоторые языки (например, C и C++) не ограничивают программиста в выборе способа обработки значений простых типов, даже позволяют определить поля для простого типа.
Сложные переменные программист создаёт для хранения данных, имеющих внутреннюю структуру. Соответственно, есть возможность обратиться напрямую к любому элементу.
Самыми характерными примерами сложных типов являются массив (все элементы однотипные) и запись (элементы могут иметь разный тип).
Следует подчеркнуть относительность такого деления: для разных программ одна и та же переменная может иметь разную структуру.
Например, компилятор различает в переменной вещественного типа 4 поля: знаки мантиссы и порядка, плюс их значения, но для программиста, компилирующего свою программу, вещественная переменная — единая ячейка памяти, хранящая вещественное число.
Рассмотрим подробнее сложный тип.
Сложный (составной) тип — тип данных, объекты (переменные или постоянные) которого имеют внутреннюю структуру, доступную программисту.
В разных языках программирования набор базовых сложных типов может несколько отличаться (чаще по названию и деталям реализации). Есть, однако, объективные критерии — однотипность элементов и способ доступа, позволяющие выделить главные представители сложных типов (названия приводятся на примере Pascal, в котором Н.Вирт наиболее чётко сформулировал эти идеи).
-
-
- Массив (array) — элементы только однотипные, доступ произвольный;
- Запись (record) — элементы возможно разных типов, доступ произвольный;
- Файл (file) — элементы однотипные, доступ последовательный (примечание: не путать с дисковым файлом!).
-
Разумеется, этот список не включает даже всех предопределённых в языках типов, но он отражает большинство моделируемых программистами структур данных.
Очень важной идеей, также родившейся на границе 60-70-х годов XX века, является возможность произвольного конструирования нужных структур из небольшого набора предопределённых типов. Чем адекватнее программист смоделировал обрабатываемые данные в рамках такого «конструктора», тем безошибочнее и долговечнее будет разработанная программа.