C назначение нескольких переменных - PullRequest
3 голосов
/ 10 апреля 2020

Я студент первого курса программной инженерии и в своем последнем задании я использовал (цепное назначение) множественное назначение значений.

Лектор утверждает, что присвоение значений таким способом недопустимо.

X = Y = Z;

(Три переменные объявлены в начале функции).

I был бы рад, если бы вы могли объяснить мне, является ли задание правильным действием и правильно ли заявлено учителем.

Заранее спасибо.

Ответы [ 6 ]

3 голосов
/ 10 апреля 2020

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

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

Если Z был инициализирован или назначен ранее, и все объекты были правильно объявлены, тогда:

X = Y = Z;

является полностью правильным и законным, поскольку присваивает значение, содержащееся в Z, Y и X - присвоение происходит справа налево.

Например:

int X,Y,Z;      // All objects are declared.

Z = 24;         // `Z` is assigned with the integer value 24.
X = Y = Z;      // `X` and `Y` get assigned by 24 which is the value in `Z`.

Иначе, если Z имеет неопределенное значение (например, если оно не было объявлено с ключевым словом extern или static или объявлено в глобальной области видимости), и вы бы присвоили это значение до Y и X с этим утверждением. Хотя само назначение было бы даже тогда недопустимым, если бы вы использовали один из назначенных объектов, программа выдала бы неопределенные результаты / вывод.


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

O = P = Q = R = S = T = U = V = W = X = Y = Z;

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


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

Если это возможно, я бы спросил ее / его или вашего учителя, что он / она имел в виду под этим. Возможно, в вашем курсе есть что-то конкретное c, о котором вы должны заботиться.

2 голосов
/ 10 апреля 2020

Почти каждое выражение имеет значение.
Присвоение является выражением со значением.
Значение выражения i = 42 равно 42.

Назначение связывает справа налево, поэтому выражение a = b = c совпадает с a = (b = c).

Итак

int i;
double d;
char c;
c = i = d = 42;

Преобразует 42 в double и присваивает d. Значение этого присваивания равно 42.0.
Затем это значение преобразуется в int и присваивается i. Значение этого назначения: 42.
Наконец, значение int преобразуется в char и присваивается c.

c = (i = (d = 42));
.
2 голосов
/ 10 апреля 2020

Это законно, например:

float x;
int y;
float z = 3.5;
x = y = z;

это похоже на y = z; x = y;. Так что в этом случае z = 3.5, y = 3 and x = 3;

Но это выдаст предупреждение, если вы не инициализировали значение z.

int x,y, z;
x = 0;
y = 1;
//z = 2;
x = y = z;
1 голос
/ 10 апреля 2020

Назначение значений нескольким переменным в одной строке совершенно нормально и допускается языком программирования C.

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

Ожидаемое математическое уравнение X = Y = Z может быть:

Y = Z и X = Z (IE, присвоить значение Z X и Y)

Но C язык обрабатывает несколько назначений как цепочку, например:

В C, "X = Y = Z " означает, что значение Z должно быть сначала присвоено Y, а затем значение Y должно быть присвоено X.

Вот пример программы, чтобы увидеть, как несколько заданий в одной строке:

#include <stdio.h>

int main() {   
    int n;
    int X, Y, Z;

    printf("Enter an integer: ");  
    scanf("%d", &n);

    printf("You entered: %d\n", n);

    printf("Performing multiple assignments:\n X = Y = Z = n++ \n");
    X = Y = Z = n++;
    printf("n = %d\n", n);
    printf("X = %d \n", X);
    printf("Y = %d \n", Y);
    printf("Z = %d \n", Z);

    return 0;
}

Вывод:

Enter an integer: 100                                                                                                                                                                      
You entered: 100                                                                                                                                                                            
Performing multiple assignments:                                                                                                                                                            
 X = Y = Z = n++                                                                                                                                                                            
n = 101
X = 100
Y = 100
Z = 100

Указывает на примечание в приведенном выше примере:

Строка X = Y = Z = n ++ была обработана так:

Шаг 1: Присвойте значение n (100) Z

Шаг 2: Увеличение значения n (n становится 101)

Шаг 3: Назначение значения Z для Y (Y становится 100)

Шаг 4: Назначьте значение Y для X (X становится 100)

Вывод:

«Несколько назначений в одной строке» - это поддерживаемый стиль. Это имеет свои преимущества.

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

Чтобы избежать этого сценария, несколько назначений не рекомендуется.

1 голос
/ 10 апреля 2020

Вместе с правой ассоциативностью оценки и допущением энергонезависимых a, b и c это означает, что a = b = c эквивалентно a = (b = c), и снова эквивалентно b = c; а = б

1 голос
/ 10 апреля 2020

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

x = y = z;
x = y = z = x + 1;
x = y++ + --z;
x += (y = (z += 1)) - 6;

Но следующие имеют поведение undefined , и их следует избегать:

x = y = x = z;
x = x++;
x = y++ + y++
x = func(y++, y++);
...