Spec-Zone.ru › Octave 6

8.6 Присваивающие выражения

Присваивание — это выражение, которое сохраняет новое значение в переменной. Например, следующее выражение присваивает значение 1 переменной z:

z = 1

После выполнения этого выражения переменная z имеет значение 1. Предыдущее значение z до присваивания забывается. Знак ‘=’ называется оператором присваивания.

Присваивания могут хранить и строковые значения. Например, следующее выражение сохранит значение "this food is good" в переменной message:

thing = "food"
predicate = "good"
message = [ "this " , thing , " is " , predicate ]

(Это также иллюстрирует конкатенацию строк.)

Большинство операторов (сложение, конкатенация и т. д.) не имеют эффекта, кроме вычисления значения. Если вы игнорируете значение, вы можете обойтись и без оператора. Оператор присваивания отличается. Он производит значение, но даже если вы игнорируете значение, присваивание всё равно ощущается через изменение переменной. Мы называем это побочным эффектом.

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

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

octave:13> foo = 1
foo = 1
octave:13> foo = "bar"
foo = bar

Когда второе присваивание присваивает foo строковое значение, тот факт, что она ранее имела числовое значение, забывается.

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

a(:, 2) = 5

устанавливает все элементы во втором столбце a в 5.

Присваивание пустой матрицы ‘[]’ в большинстве случаев позволяет вам удалять строки или столбцы матриц и векторов. См. Пустые матрицы. Например, задана 4×5 матрица A, присваивание

A (3, :) = []

удаляет третью строку из A, а присваивание

A (:, 1:2:5) = []

удаляет первый, третий и пятый столбцы.

Присваивание — это выражение, поэтому оно имеет значение. Таким образом, z = 1 как выражение имеет значение 1. Следствием этого является то, что вы можете записать несколько присваиваний вместе:

x = y = z = 0

сохраняет значение 0 во всех трёх переменных. Это происходит потому, что значение z = 0, которое равно 0, сохраняется в y, а затем значение y = z = 0, которое равно 0, сохраняется в x.

Это также верно для присваиваний спискам значений, поэтому следующее является допустимым выражением

[a, b, c] = [u, s, v] = svd (a)

что точно эквивалентно

[u, s, v] = svd (a)
a = u
b = s
c = v

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

[a, b] = [u, s, v] = svd (a)

эквивалентно

[u, s, v] = svd (a)
a = u
b = s

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

[a, b, c, d] = [u, s, v] = svd (a);
-| error: element number 4 undefined in return list

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

[~, s, v] = svd (a);

Это более чисто и более эффективно с точки зрения памяти, чем использование фиктивной переменной. Значение nargout для выражения правой части не затрагивается. Если присваивание используется как выражение, возвращаемое значение представляет собой список, разделённый запятыми, с опущенными проигнорированными значениями.

Очень распространённый шаблон программирования — это инкрементирование существующей переменной на заданное значение, как в этом примере

a = a + 2;

Это можно записать более ясно и компактно, используя оператор +=

a += 2;

Аналогичные операторы также существуют для вычитания (-=), умножения (*=) и деления (/=). Выражение вида

expr1 op= expr2

вычисляется как

expr1 = (expr1) op (expr2)

где op может быть либо +, либо -, либо *, либо /, при условии, что expr2 — это простое выражение без побочных эффектов. Если expr2 также содержит оператор присваивания, то это выражение вычисляется как

temp = expr2
expr1 = (expr1) op temp

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

a *= b+1

вычисляется как

a = a * (b+1)

и не

a = a * b + 1

Вы можете использовать присваивание там, где требуется выражение. Например, допустимо написать x != (y = 1) для установки y в 1 и затем проверки, равно ли x 1. Однако такой стиль затрудняет чтение программ. За исключением одноразовой программы, вы должны переписать её, избавившись от таких вложенных присваиваний. Это никогда не сложно.

© 1996–2022 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v6.4.0/Assignment-Ops.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API