Назначение (информатика) - Assignment (computer science)


Из Википедии, свободной энциклопедии

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

На сегодняшний день наиболее часто используемые обозначения для этой базовой операции очутились (первоначально Superplan 1949-51, популяризировали Fortran 1957 и C ) , а затем (первоначально Алгол 1958, популяризировал Паскаль ), хотя есть много других обозначений в использовании. В некоторых языках используется символ рассматривается как оператор (имея в виду , что назначение имеет значение) , тогда как другие определяют назначение как утверждение (что означает , что оно не может быть использовано в выражении). x = exprx := expr

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

Семантика

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

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

  • expressionОценивается в текущем состоянии программы.
  • variableПрисваивается вычисленное значение, заменив предварительное значение этой переменной.

Пример: Если предположить , что aэто числовая переменная, присвоение a := 2*aозначает , что содержание переменной aудваивается после выполнения оператора.

Пример сегмент C кода:

int x = 10; 
float y;
x = 23;
y = 32.4f;

В этом примере переменная xсначала объявлен как INT, а затем присваивается значение 10. Обратите внимание , что декларация и назначение произойдет в том же заявлении. Во второй строке, yобъявляется без задания. В третьей строке, xпереназначается значение 23. Наконец, yприсваивается значение 32,4.

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

Одно задание

Любое задание , которое изменяет существующее значение (например x := x + 1) запрещено в чисто функциональных языках. В функциональном программировании , назначение не рекомендуется в пользу одной уступки, также называется инициализация . Одно задание является примером связывания имен и отличается от присвоения , как описано в этой статье , в том , что это может быть сделано только один раз, как правило , когда создается переменный; никакого последующее переназначение не допускаются.

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

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

Нечистый функциональные языки обеспечивают как единое назначение, а также истинное назначение (хотя истинное назначение , как правило , используются с меньшей частотой , чем в императивных языках программирования). Например, в схеме, как одного назначения (с let) и истинным назначением (с set!) могут быть использованы на всех переменных, а также специализированные примитивы предусмотрены для разрушающего обновления внутри списков, векторов, строки и т.д. В OCaml, только одно назначение допускается для переменных, через синтаксис; Однако разрушительное обновление может быть использовано на элементах массивов и строк с отдельным оператором, а также на полях записей и объектов , которые были явно объявлены изменяемыми (значение может быть изменено после того, как их первоначальной декларации) программистом. let name = value<-

Функциональные языки программирования, использующие одно назначение включают Clojure (для структур данных, а не VARS), Erlang (он принимает множественное присваивание , если значения равны, в отличие от Haskell), F # , Haskell , Lava , OCaml , Oz (для потоковых переменных, не клетки), ракетка (для некоторых структур данных , таких как списки, а не символов), SASL , Scala (для вальса), сизаль , Standard ML . Non- возвратов Prolog код можно считать явным одинарной назначение, явное в том смысле , что его (названные) переменные могут быть в явном Unassigned состояние, или быть установлен ровно один раз. В Haskell, напротив, не может быть никакого нераспределенной переменными, и каждый переменный может быть представлены как неявно устанавливаются его значение (или , вернее , к вычислительному объекту , который будет производить его значение по требованию ) , когда он будет создан.

Значение присвоения

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

В большинстве экспрессионных-ориентированных языков программирования (например, C ), то оператор присваивания возвращает присвоенное значение, позволяя такие идиомы , как x = y = a, в которой оператор присваивания y = aвозвращает значение a, которое затем назначено x. В заявлении , такие как , возвращаемое значение функции используются для управления циклом при назначении этого же значения переменного. while ((ch = getchar()) != EOF) {}

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

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

Вариант формы присвоения

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

Дополненная назначение

Случай , когда присвоенное значение зависит от предыдущего является настолько общим , что многие императивные языки, в первую очередь C и большинство его потомков, предоставляют специальные операторы , называемые дополненной назначение , как *=, так что a = 2*aвместо того, чтобы можно записать в виде a *= 2. Помимо синтаксического сахара, это помогает задачу компилятора, сделав ясно , что в месте модификации переменной aвозможно.

Прикованный назначение

Заявление , как w = x = y = zназывается цепью присваивания , в котором значение zприсваивается нескольким переменным w, x,и y. Цепные задания часто используется для инициализации нескольких переменных, как и в

a = b = c = d = f = 0

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

В некоторых языках программирования ( C , например), цепочечные задания поддерживаются , поскольку задания являются выражениями, и имеют значение. В этом случае назначение цепи может быть реализовано при наличии правоассоциативного назначения и задание произойдет справа налево. Например, i = arr[i] = f()эквивалентно arr[i] = f(); i = arr[i]. В C ++ они также доступны для значений типов классов, объявляя соответствующий тип возвращаемого значения для оператора присваивания.

В Python , операторы присваивания не являются выражениями и , следовательно , не имеют значения. Вместо этого, прикованные задания представляют собой последовательность операторов с несколькими целями для одного выражения. Задания выполняются слева-направо , так что i = arr[i] = f()вычисляет выражение f(), а затем присваивает результат к крайней левой мишени, iи затем присваивает один и тот же результат , к следующей цели, arr[i]с использованием нового значения i. Это, по существу эквивалентно , tmp = f(); i = tmp; arr[i] = tmpхотя никакой фактической переменной не производится для временного значения.

Параллельное назначение

Некоторые языки программирования, такие как APL , Go , JavaScript (с 1.7), PHP , Maple , Lua , Оккама 2 , Perl , Python , REBOL , Ruby , и Windows PowerShell позволяют несколько переменных , которые будут назначены параллельно, с синтаксисом , как:

a, b := 0, 1

который одновременно присваивает 0 до aи от 1 до b. Это наиболее часто называют параллельным назначением ; она была введена в КПЛ в 1963 году под названием одновременное присвоение , и иногда называется множественное присваивание , хотя это сбивает с толку , когда используется с «одной уступки», так как они не являются противоположностями. Если правая сторона задания является одной переменной (например , массив или структуру), то функция называется распаковкой или уничтожение того, назначение :

var list := {0, 1}
a, b := list

Список будет распакованы , так что 0 назначается aи 1 к b. Более того,

a, b := b, a

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

var t := a
a := b
b := t

так как a := b; b := aлистья как aи bс первоначальным значением b.

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

def f():
    return 1, 2
a, b = f()

Это обеспечивает альтернативу использование выходных параметров для возвращения нескольких значений из функции. Это относится к CLU (1974), и CLU способствовал популяризации параллельного назначения в целом.

В C и C ++, то оператор запятой похож на параллельное присвоение в позволяя множество назначений происходят в течение одного оператора, записывая a = 1, b = 2вместо a, b = 1, 2. Это используется в основном для петель , и заменяется параллельным назначением на других языках , таких как Go. Тем не менее, выше код C ++ не обеспечивает идеальные одновременности, так как правая часть следующего кода a = b, b = a+1вычисляется после левой стороны. В таких языках, как Python, a, b = b, a+1будет назначать две переменные одновременно, используя начальное значение , чтобы вычислить новые б.

Назначение против равенства

Использование знака равенства , =как оператор присваивания неоднократно критиковали из - за конфликта с равными , как сравнения на равенство. Это приводит как к путанице новичками в написании кода, и замешательство даже опытных программистов в чтении кода. Использование равных для присвоения восходит к Хайнц Ратишозер языка «s SUPERPLAN , разработанных с 1949 по 1951 году , и особенно популяризировали Fortran:

Известный пример плохой идеи был выбором знака равенства для обозначения назначения. Она восходит к Fortran в 1957 году и слепо скопированы армиями разработчиков языка. Почему это плохая идея? Потому что низвергает старую традицию века, чтобы позволить «=» обозначает сравнение на равенство, предикат, который является истинным или ложным. Но Fortran сделал это означает присваивание, принуждение равенства. В этом случае операнды находятся в неравном положении: левый операнд (переменный) должны быть сделан равной правый операнд (выражение). х = у не означает то же самое, что и у = х.

-  Никлаус Вирт , Хорошие идеи, Зазеркалье

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

В некоторых языках, таких как BASIC , один знак равенства ( "=") используется как для оператора присваивания и реляционного оператора равенства, с контекстом определения , которое имеется в виду. Другие языки используют разные символы для двух операторов. Например:

  • В Алголом и Паскаль , оператор присваивания является двоеточие и знак равенства ( ":=") , а оператор равенства является единственным равно ( "=").
  • В C , оператор присваивания является единым знаком равенства ( "=") , а оператор равенства пары знаков равенства ( "==").
  • В R , оператор присваивания, в основном <-, как в x <- value, но один знак равенства может использоваться в определенных контекстах.

Сходство двух символов может привести к ошибкам , если программист забывает , которые образуют (» =», „ ==“, „ :=„) уместно, или ошибок при вводе“ , =“ когда „ ==“ было задумано. Это общая проблема программирования с языками , такими как C ( в том числе один известную попытки бэкдора ядро Linux), где оператор присваивания также возвращает значение , присвоенное (таким же образом , что функция возвращает значение), и может быть надлежащим образом вложено внутри выражений. Если целью было сравнить два значения в ifзаявлении, например, назначение вполне может возвращать значение интерпретируемого , как Boolean верно, и в этом случае thenбудет выполняться условие, что ведет программу вести себя неожиданно. Некоторые процессоры языка (например, GCC ) могут обнаружить такие ситуации, и предупредить программист потенциальной ошибки.

нотация

Два наиболее распространенных представлений для задания копирования являются знак равенства ( =) и двоеточие-равно ( :=). Обе формы могут семантически обозначают либо присваивания заявления или присвоение оператор (который также имеет значение), в зависимости от языка и / или использования.

variable = expression Fortran , PL / I , Cпотомки , такие как C ++ , Java и т.д.), Bourne оболочки , Python , Go (присвоение предварительно объявленных переменных), R , Windows PowerShell и т.д.
variable := expression Алгол (и его производные), Симула , CPL , BCPL , Паскаль (и потомки , такие как Modula ), Mary , PL / M , Ada , Smalltalk , Eiffel , Оберон , Дилэном , Seed7 , Go (сокращение для объявления и определения переменной), Io , AMPL , ML , AutoHotkey и т.д.

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

variable << expression Magik
variable <- expression F # , OCaml , R , S
variable <<- expression р
assign("variable", expression) р
variableexpression АПЗ , Smalltalk
variable =: expression J
LET variable = expression Бейсик
let variable := expression XQuery
set variable to expression AppleScript
set variable = expression C оболочки
Set-Variable variable (expression) Windows PowerShell
variable : expression Macsyma, Maxima , Rebol , K
var variable expression Mirc язык сценариев
reference-variable :- reference-expression Симула

Математическая псевдокод задания , как правило , изображены с левой стрелкой.

Некоторые платформы поставить выражение слева и переменные справа:

MOVE expression TO variable Кобол
expressionvariable TI-BASIC , Casio BASIC
expression -> variable POP-2 , бета , R
put expression into variable LiveCode

Некоторые экспрессирующие-ориентированные языки, такие как Lisp и Tcl, равномерно используйте префикс (или постфикс) синтаксис для всех операторов, в том числе присвоения.

(setf variable expression) Common Lisp
(set! variable expression) Схема
set variable expression Tcl
expression variable ! вперед

Смотрите также

Заметки

Рекомендации