Переменные: let и const
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
В ES-2015 предусмотрены новые способы объявления переменных: через let и const вместо var .
let a = 5;
let
У объявлений переменной через let есть три основных отличия от var :
- Область видимости переменной let – блок <. >. Как мы помним, переменная, объявленная через var , видна везде в функции. Переменная, объявленная через let , видна только в рамках блока <. >, в котором объявлена. Это, в частности, влияет на объявления внутри if , while или for . Например, переменная через var :
var apples = 5; if (true) < var apples = 10; alert(apples); // 10 (внутри блока) >alert(apples); // 10 (снаружи блока то же самое)
В примере выше apples – одна переменная на весь код, которая модифицируется в if . То же самое с let будет работать по-другому:
let apples = 5; // (*) if (true) < let apples = 10; alert(apples); // 10 (внутри блока) >alert(apples); // 5 (снаружи блока значение не изменилось)
Здесь, фактически, две независимые переменные apples , одна – глобальная, вторая – в блоке if . Заметим, что если объявление let apples в первой строке (*) удалить, то в последнем alert будет ошибка: переменная не определена:
if (true) < let apples = 10; alert(apples); // 10 (внутри блока) >alert(apples); // ошибка!
alert(a); // undefined var a = 5;
С переменными let всё проще. До объявления их вообще нет. Такой доступ приведёт к ошибке:
alert(a); // ошибка, нет такой переменной let a = 5;
Заметим также, что переменные let нельзя повторно объявлять. То есть, такой код выведет ошибку:
let x; let x; // ошибка: переменная x уже объявлена
Это – хоть и выглядит ограничением по сравнению с var , но на самом деле проблем не создаёт. Например, два таких цикла совсем не конфликтуют:
// каждый цикл имеет свою переменную i for(let i = 0; i for(let i = 0; i alert( i ); // ошибка: глобальной i нет
for(var i=0; i alert(i); // 10
С переменной let – всё по-другому. Каждому повторению цикла соответствует своя независимая переменная let . Если внутри цикла есть вложенные объявления функций, то в замыкании каждой будет та переменная, которая была при соответствующей итерации. Это позволяет легко решить классическую проблему с замыканиями, описанную в задаче Армия функций.
function makeArmy() < let shooters = []; for (let i = 0; i < 10; i++) < shooters.push(function() < alert( i ); // выводит свой номер >); > return shooters; > var army = makeArmy(); army[0](); // 0 army[5](); // 5
const
Объявление const задаёт константу, то есть переменную, которую нельзя менять:
const apple = 5; apple = 10; // ошибка
В остальном объявление const полностью аналогично let .
Заметим, что если в константу присвоен объект, то от изменения защищена сама константа, но не свойства внутри неё:
const user = < name: "Вася" >; user.name = "Петя"; // допустимо user = 5; // нельзя, будет ошибка
То же самое верно, если константе присвоен массив или другое объектное значение.
константы и КОНСТАНТЫ
Константы, которые жёстко заданы всегда, во время всей программы, обычно пишутся в верхнем регистре. Например: const ORANGE = «#ffa500» .
Большинство переменных – константы в другом смысле: они не меняются после присвоения. Но при разных запусках функции это значение может быть разным. Для таких переменных можно использовать const и обычные строчные буквы в имени.
Итого
- Видны только после объявления и только в текущем блоке.
- Нельзя переобъявлять (в том же блоке).
- При объявлении переменной в цикле for(let …) – она видна только в этом цикле. Причём каждой итерации соответствует своя переменная let .
Переменная const – это константа, в остальном – как let .
Структура программы в Pascal
Любая программа, написанная на языке Pascal состоит из заголовка программы и некоторого блока. Блок содержит раздел описаний, в котором определяются все локальные по отношению к данной программе объекты, и раздел операторов. Он задает действия, которые необходимо выполнять, над этими объектами.
program имя программы; uses Label . . . ; Const . ; . ; Type = ; Var :; Function . ; Procedure . ; begin . ; . ; end.
Заголовок программы
В заголовке программе дается некоторое имя. Обычно стараются выбирать имя, отражающее основную функцию, выполняемую программой. Заголовок всегда начинается со служебного слова program , после которого через пробел пишется имя программы. Оно может состоять из символов английского алфавита, цифр и знака подчеркивания. Имя программы всегда должно начинаться с буквы.
В имени программы нельзя использовать какие-либо предописанные имена (зарезервированные слова). Они используются в программе только в том значении, которое зафиксировано для них разработчиками языка Pascal. Ниже приведен список таких слов.
and | end | nil | set |
array | file | not | then |
begin | for | of | to |
case | function | or | type |
const | goto | packed | until |
div | if | procedure | var |
do | in | program | while |
downto | label | record | with |
else | mod | repeat |
Заголовок носит чисто информативный характер и никак не влияет на программу. Программу можно написать и не используя его. После имени программы в ранних редакциях языка указывались круглые скобки и в них давались имена входных и выходных файлов задачи. В последних версиях языка Pascal имена входных и выходных файлов в заголовке программы отсутствуют.
Пример правильного написания заголовка:
program Perimetr; program Phone37; program one_two_3;
Пример неправильного написания заголовка:
program 9zet; program Samara-63; program repeat;
Label — раздел описания меток
Любой оператор программы можно маркировать, поставив перед ним через двоеточие метку, тем самым появляется возможность ссылаться на эту метку при помощи оператора перехода goto . Однако такая метка, прежде чем она будет использована, должна быть описана в разделе описания меток. Этот раздел начинается со слова Label .
Имя метки может включать в себя буквы английского алфавита, цифры и знак подчеркивания. При этом, в отличии от имени программы метка может начинаться с цифры, да и вообще состоять только из цифр, но это число должно представлять собой целое число без знака, лежащее в диапазоне от 0 до 9999.
Пример правильного написания меток:
label 13, 00100, 99, qwerty, x_y;
Раз уж разговор зашел про метки, то нужно сказать, что использование меток и оператора перехода goto не желательно при написании программы на Pascal. Применять его стоит только в необычных, исключительных ситуациях, когда приходится нарушать естественную структуру алгоритма. Частое появление в программе на Pascal оператора перехода свидетельствует о том, что программист еще не научился думать на Pascal.
Этот раздел необязателен, если у вас в программе не используются метки.
Const — раздел определения констант
Константы — это величины, которые не меняют своих значений в процессе выполнения программы. Допустим, в вашей программе часто приходится оперировать с числом 3,14 (число Пи). Чтобы каждый раз не вводить это число, мы определяем константу с именем Pi и в вычисления уже подставляем ее.
Использование имен констант делает программу более «читаемой» и способствует улучшению ее документируемости. Кроме того, это позволяет программисту сгруппировать в начале программы величины, зависящие от машины или характерные для данного примера: здесь они более заметны и их легче изменить. Тем самым улучшается переносимость программ и их модульность.
Начинается данный раздел со служебного слова Const . Далее идут описания констант, каждое из которых начинается с имени константы, затем идет символ = (равенство), после чего пишется константа или выражение, составленное из констант. Завершается каждое описание точкой с запятой.
Const = ;
Константа может иметь только предопределенный (стандартный) тип данных. Тип присваивается константе по внешнему виду значения и в соответствии с этим типом отводится память для хранения значения константы.
В качестве расширения стандартного Паскаля разрешено использовать выражения, составленные из ранее определенных констант и некоторых стандартных функций: Abs, Chr, Hi, Length, Lo, Odd, Ord, Pred, Prt, Round, SizeOf, Succ, Swap, Trunc . Константные выражения вычисляются компилятором без выполнения программы на этапе ее создания. Пример:
const Avogadro = 6.023Е23; PageLength = 60; MyMove = True; stroka = 'abcdefg'; Min = 0; Max = 250; Centr = (Max-Min) div 2; Beta = Chr(225); NumChars = Ord('2') - Ord('A')+l;
Этот раздел также необязателен, если у вас в программе не используются константы.
Type — раздел описания типов
Помимо стандартных типов данных в Pascal (Real, Integer, Boolean, Char) пользователь может задать новые типы. Структура раздела описания типов имеет вид:
Type = ; = ; … = ;
Имя типа представляет собой идентификатор, который может употребляться в других типах, описанных вслед за данным типом. Вообще, новые типы можно определять и в разделе переменных Var, поэтому можно обойтись без этого раздела. Приведу несколько примеров описания типов:
Type Year = 1800.. 2015; Alfavit = (‘А’, ‘B, ‘C’, ‘T, ‘L’); Matrica = array[1..12, ‘А’.. ‘Z’] of real;
Var — раздел описания переменных
Этот раздел является обязательным. Переменные отличаются от констант тем, что им можно присваивать новые значения при исполнении программы. Любая переменная, которая будет использована в программе должна быть описана. Что включает в себя описание переменной? Это значит, что переменной должен быть присвоен какой-либо тип данных, который характеризует множество значений, которые может принимать объект; множество операций, которые могут применяться к объекту; размер памяти, занимаемый объектом.
Начинается этот раздел с предописанного слова var . Следом идут описания переменных, каждое из которых начинается со списка имен переменных, разделяемых запятыми, затем идет символ : (двоеточие), затем указывается тип этих переменных. Завершается каждое описание точкой с запятой.
Структура раздела имеет вид:
Тип переменных представляет собой имя (идентификатор), описанный в разделе TYPE при явном описании типа, или собственно описание типа в случае его неявного задания. Примеры описания переменных:
Var Year: 1800.. 2000; А, В, C: Real; Istina: Boolean; Stroka: Char; I, J, К: Integer;
Function, Procedure — раздел описаний процедур и функций
В разделе Function и Procedure описываются пользовательские процедуры и функции, если таковые имеются. Если их нет, то этот раздел не обязателен в программе.
Процедура представляет собою подпрограмму и активируется (начинает выполняться) через оператор процедуры. Функция — это тоже подпрограмма, но она выдает некоторое значение — результат и поэтому используется, как компонента выражения.
Структура раздела имеет вид:
Procedure (); Begin End; Function (): ; < заголовок > Begin End;
Структура процедур и функций та же самая, что и у основной программы. Отличие описаний состоит в том, что идентификаторы констант, переменных, процедур и функций, описанных в соответствующих разделах описаний пользовательских процедур и функций, распространяются только на блоки, где они описаны и на блоки внутренние по отношению к ним. На внешние блоки, в том числе на тело основной программы, они не распространяются.
© program4you.ru 2015 — 2022
Копирование материалов сайта разрешено только при наличии активной ссылки на данный сайт
Какое значение имеет служебное слово const
страницы: 1 2 3 4 5
Параметр–значение
Описание
В списке параметров подпрограммы перед параметром–значением служебное слово отсутствует 1 . Например, функция func3 имеет три параметра–значения :
function func3 (x : Real ; k : Integer ; flag : Boolean ) : Real ;
При вызове подпрограммы параметру–значению может соответствовать аргумент , являющийся выражением, переменной или константой, например:
dlina := func3(shirina / 2 , min (a shl 1 , ord ( ‘y’ )) , True ) + 0.5 ;
Для типов данных здесь не обязательно строгое совпадение (эквивалентность), достаточно и совместимости по присваиванию (см. лекцию 2 ).
Механизм передачи значения
В области памяти, выделяемой для работы вызываемой подпрограммы , создаётся переменная с именем . , и в эту переменную записывается значение переданного в соответствующий параметр аргумента . Дальнейшие действия, производимые подпрограммой , выполняются именно над этой новой переменной. Значение же входного аргумента не затрагивается. Следовательно, после окончания работы подпрограммы , когда весь её временный контекст будет уничтожен, значение аргумента останется точно таким же, каким оно было на момент вызова подпрограммы .
В качестве примера рассмотрим последовательность действий, выполняемых при передаче аргументов 1 + а / 2 , а и Тrue в описанную выше функцию func3 . Пусть а — переменная, имеющая тип Byte , тогда значение выражения 1 + a / 2 будет иметь тип Real , а True и вовсе является константой (неименованной).
Итак, при вызове func3(1 + a / 2, a, True) будут выполнены следующие действия:
- создать временные переменные func3.x , func3.k , func3.flag ;
- вычислить значение выражения 1 + а / 2 и записать его в переменную func3.x ;
- записать в переменную func3.k значение переменной а ;
- записать в переменную func3.flag значение константы True ;
- произвести действия, описанные в теле функции ;
- уничтожить все временные переменные, в том числе func3.x , func3.k , func3.flag .
Уже видно, что значения аргументов не изменятся.
Замечание: При использовании параметров–значений в контексте подпрограммы создаются хотя и временные, но вполне полноценные копии входных аргументов . Поэтому нежелательно передавать в параметры–значения «большие» аргументы (например, массивы ): они будут занимать много лишней памяти.
Параметр–переменная
Описание
В списке параметров подпрограммы перед параметром–переменной ставится служебное слово var . Например, процедура proc3 имеет три параметра–переменные и один параметр–значение :
procedure proc3 ( var x , y : Real ; var k : Integer ; flag : Boolean ) ;
При вызове подпрограммы параметру–переменной может соответствовать только аргумент–переменная; константы и выражения запрещены. Кроме того, тип аргумента и тип параметра–переменной должны быть эквивалентными (см. лекцию 2 ).
Механизм передачи значения
В отличие от параметра–значения , для параметра–переменной не создаётся копии при вызове подпрограммы . Вместо этого в работе подпрограммы участвует та самая переменная, которая послужила аргументом . Понятно, что если её значение изменится в процессе работы подпрограммы , то это изменение сохранится и после того, как будет уничтожен контекст подпрограммы . Понятно опять же и ограничение на аргументы , которые должны соответствовать параметрам–переменным : ни константа, ни выражение не смогут сохранить изменения, внесённые в процессе работы подпрограммы .
Итак, параметры–переменные и служат теми посредниками, которые позволяют получать результаты работы процедур , а также увеличивать количество результатов, возвращаемых функциями .
Замечание: Для экономии памяти в параметр–переменную можно передавать и такую переменную, изменять значение которой не требуется. Скажем, если нужно передать в качестве аргумента массив , то лучше не создавать его копию, как это будет сделано при использовании параметра–значения , а использовать параметр–переменную .
Параметр–константа
Описание
В списке параметров подпрограммы перед параметром–константой ставится служебное слово const . Например, процедура proc4 имеет один параметр–переменную и один параметр–константу :
procedure proc4 ( var k : Integer ; const flag : Boolean ) ;
При вызове подпрограммы параметру–константе может соответствовать аргумент , являющийся выражением, переменной или константой. Во время выполнения подпрограммы соответствующая переменная считается обычной константой. Ограничением является то, что при вызове другой подпрограммы из тела текущего параметра–константе не может быть подставлен в качестве аргумента в параметр–переменную .
Для типов данных здесь не обязательно строгое совпадение (эквивалентность), достаточно и совместимости по присваиванию (см. лекцию 2 ).
Механизм передачи значения
В некоторых источниках 2 можно встретить утверждение о том, что для параметра–константы , как и для параметра–переменной , не создаётся копии в момент вызова подпрограммы . Однако выполнение простейшей проверки
procedure prob ( const c : Byte ) ;
begin
WriteLn ( LongInt ( Addr (c))) ;
end ;
begin
a := 0 ;
WriteLn ( LongInt ( Addr (a))) ;
prob(a) ;
end .
доказывает обратное: физические адреса 3 переменной а и параметра с различаются. Следовательно, в памяти эти переменные занимают разные позиции, а не одну, как было бы в случае параметра–переменной . Вы можете убедиться в этом самостоятельно, запустив данную программу в трёх разных вариантах (для параметра–значения , параметра–переменной и параметра–константы ), а затем сравнив результаты.
страницы: 1 2 3 4 5
Примечания
- ^ Иными словами, атрибут является пустым.
- ^ Например, Бежанова М.М., Москвина Л.А. Практическое программирование. Приёмы создания программ на языке Паскаль. М.: «Научный мир», 2001.
- ^ Способы работы с физическими адресами мы рассмотрим в лекции 10 .
Описания и константы
В С++ можно задавать значения всех основных типов: символьные константы , целые константы и константы с плавающей точкой. Кроме того, нуль (0) можно использовать как значение указателя произвольного типа, а символьные строки являются константами типа char[] . Есть возможность определить символические константы . Символическая константа — это имя, значение которого в его области видимости изменять нельзя. В С++ символические константы можно задать тремя способами:
- добавив служебное слово const в определении, можно связать с именем любое значение произвольного типа;
- множество целых констант можно определить как перечисление;
- константой является имя массива или функции.
2.4.1 Целые константы
Целые константы могут появляться в четырех обличьях: десятичные, восьмеричные, шестнадцатеричные и символьные константы. Десятичные константы используются чаще всего и выглядят естественно:
0 1234 976 12345678901234567890
Десятичная константа имеет тип int , если она умещается в память, отводимую для int , в противном случае ее тип long . Транслятор должен предупреждать о константах, величина которых превышает выбранный формат представления чисел. Константа, начинающаяся с нуля, за которым следует x (0x) , является шестнадцатеричным числом (с основанием 16), а константа, которая начинается с нуля, за которым следует цифра, является восьмеричным числом (с основанием 8). Приведем примеры восьмеричных констант:
0 02 077 0123
Их десятичные эквиваленты равны соответственно: 0, 2, 63, 83. В шестнадцатеричной записи эти константы выглядят так:
0x0 0x2 0x3f 0x53
Буквы a, b, c, d, e и f или эквивалентные им заглавные буквы используются для представления чисел 10, 11, 12, 13, 14 и 15, соответственно. Восьмеричная и шестнадцатеричная формы записи наиболее подходят для задания набора разрядов, а использование их для обычных чисел может дать неожиданный эффект. Например, на машине, в которой int представляется как 16-разрядное число в дополнительном коде, 0xffff есть отрицательное десятичное число -1. Если бы для представления целого использовалось большее число разрядов, то это было бы числом 65535.
Окончание U может использоваться для явного задания констант типа unsigned . Аналогично, окончание L явно задает константу типа long . Например:
void f(int); void f(unsigned int); void f(long int); void g() < f(3); // вызов f(int) f(3U); // вызов f(unsigned int) f(3L); // вызов f(long int) >
2.4.2 Константы с плавающей точкой
Константы с плавающей точкой имеют тип double . Транслятор должен предупреждать о таких константах, значение которых не укладывается в формат, выбранный для представления чисел с плавающей точкой. Приведем примеры констант с плавающей точкой:
1.23 .23 0.23 1. 1.0 1.2e10 1.23e-15
Отметим, что внутри константы с плавающей точкой не должно быть пробелов. Например, 65.43 e-21 не является константой с плавающей точкой, транслятор распознает это как четыре отдельные лексемы:
65.43 e - 21
что вызовет синтаксическую ошибку.
Если нужна константа с плавающей точкой типа float , то ее можно получить, используя окончание f :
3.14159265f 2.0f 2.997925f
2.4.3 Символьные константы
Символьной константой является символ, заключенный в одиночные кавычки, например, ‘a’ или ‘0’. Символьные константы можно считать константами, которые дают имена целым значениям символов из набора, принятого на машине, на которой выполняется программа. Это необязательно тот же набор символов, который есть на машине, где программа транслировалась. Таким образом, если вы запускаете программу на машине, использующей набор символов ASCII, то значение ‘0’ равно 48, а если машина использует код EBCDIC , то оно будет равно 240. Использование символьных констант вместо их десятичного целого эквивалента повышает переносимость программ. Некоторые специальные комбинации символов, начинающиеся с обратной дробной черты, имеют стандартные названия:
Конец строки NL(LF) \n Горизонтальная табуляция HT \t Вертикальная табуляция VT \v Возврат BS \b Возврат каретки CR \r Перевод формата FF \f Сигнал BEL \a Обратная дробная черта \ \\ Знак вопроса ? \? Одиночная кавычка ' \' Двойная кавычка " \" Нулевой символ NUL \0 Восьмеричное число ooo \ooo Шестнадцатеричное число hhh \xhhh
Несмотря на их вид, все эти комбинации задают один символ. Тип символьной константы — char . Можно также задавать символ с помощью восьмеричного числа, представленного одной, двумя или тремя восьмеричными цифрами (перед цифрами идет \) или с помощью шестнадцатеричного числа (перед шестнадцатеричными цифрами идет \x ). Число шестнадцатеричных цифр в такой последовательности неограничено. Последовательность восьмеричных или шестнадцатеричных цифр завершается первым символом, не являющимся такой цифрой. Приведем примеры:
'\6' '\x6' 6 ASCII ack '\60' '\x30' 48 ASCII '0' '\137' '\x05f' 95 ASCII '_'
Этим способом можно представить любой символ из набора символов машины. В частности, задаваемые таким образом символы можно включать в символьные строки (см. следующий раздел). Заметим, что если для символов используется числовая форма задания, то нарушается переносимость программы между машинами с различными наборами символов.
2.4.4 Строки
Строка — это последовательность символов, заключенная в двойные кавычки:
"это строка"
Каждая строка содержит на один символ больше, чем явно задано: все строки оканчиваются нулевым символом (‘\0’), имеющим значение 0. Поэтому
sizeof("asdf")==5;
Типом строки считается «массив из соответствующего числа символов», поэтому тип «asdf» есть char[5] . Пустая строка записывается как «» и имеет тип char[1] . Отметим, что для любой строки s выполняется strlen(s)==sizeof(s)-1 , поскольку функция strlen() не учитывает завершающий символ ‘\0’.
Внутри строки можно использовать для представления невидимых символов специальные комбинации с \. В частности, в строке можно задать сам символ двойной кавычки » или символ \. Чаще всего из таких символов оказывается нужным символ конца строки ‘\n’, например:
coutЗдесь 7 - это значение в ASCII символа BEL (сигнал), который в переносимом виде обозначается как \a.
Нет возможности задать в строке "настоящий" символ конца строки:
"это не строка, а синтаксическая ошибка"Для большей наглядности программы длинные строки можно разбивать пробелами, например:
char alpha[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ";Подобные, подряд идущие, строки будут объединяться в одну, поэтому массив alpha можно эквивалентным образом инициализировать с помощью одной строки:
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";В строке можно задавать символ '\0', но большинство программ не ожидает после него встречи с какими-либо еще символами. Например, строку "asdf\000hjkl" стандартные функции strcpy() и strlen() будут рассматривать как строку "asdf".
Если вы задаете в строке последовательностью восьмеричных цифр числовую константу, то разумно указать все три цифры. Запись этой строки и так не слишком проста, чтобы еще и раздумывать, относится ли цифра к числу или является отдельным символом. Для шестнадцатеричных констант используйте два разряда. Рассмотрим следующие примеры:
char v1[] = "a\x0fah\0129"; // 'a' '\xfa' 'h' '\12' '9' char v2[] = "a\xfah\129"; // 'a' '\xfa' 'h' '\12' '9' char v3[] = "a\xfad\127"; // 'a' '\xfad' '\127'2.4.5 Нуль
Нуль (0) имеет тип int . Благодаря стандартным преобразованиям 0 можно использовать как константу целого типа, или типа с плавающей точкой, или типа указателя. Нельзя разместить никакой объект, если вместо адреса указан 0. Какой из типов нуля использовать, определяется контекстом. Обычно (но необязательно) нуль представляется последовательностью разрядов "все нули" подходящей длины.