C语言多变量赋值

3

我是软件工程专业的一年级学生,上一次任务中我使用了(链式赋值)多个变量同时赋值的方法。

但是讲师声称这种方式是不合法的。

X = Y = Z;

(这三个变量在函数开始时声明)。

如果您能解释一下赋值是否为正确操作以及老师声称的是否正确,那我会很高兴。


你为什么会认为你的老师可能是错误的呢? - machine_1
6个回答

3

这取决于在此语句之前是否正确声明了所有对象并初始化或分配了适当的值给 Z

由于隐式转换,您甚至可以将不同类型的对象的值赋给变量,但被赋值的对象需要能够容纳赋给它的对象的值。

如果在此之前已经初始化或赋值了 Z 并且所有对象都正确声明,则:

X = Y = Z;

这是完全正确和合法的,它将Z中保存的值赋给YX - 赋值是从右到左进行的。

例如:

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具有不确定的值(例如,如果它没有使用externstatic关键字声明或在全局范围内声明),并且您将此值分配给YX,则该语句的分配本身即使合法,但如果您使用其中一个被赋值的对象,程序将会产生未定义的结果/输出。


仅就多个赋值而言,这样做是没有任何问题的,您甚至可以使用:

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

如果所有使用的对象都已正确声明,并且Z具有确定的值。


讲师声称以这种方式分配值是不合法的。

如果可能的话,我建议您向讲师或您的教师询问他/她的意思。也许有一些特定于您课程的事情需要关注。


通常情况下,单词“correct”被用来代替“right”,表示特定的表达式或语句在语法上是有效的。 - machine_1
1
涉及的类型需要是可赋值兼容的,而不是相同的。 - pmg
@pmg 我在你发表评论时已经在测试你的版本了。我进行了更正。隐式转换很有趣...但是如果使用不同类型的对象,需要注意一件事情:被分配的对象需要能够容纳分配给它的对象的值。 - RobertS supports Monica Cellio
也许你的讲师试图阻止你分配指针而不是文字常量,而不是告诉你永远不要使用那种语法类型! - Saadi Toumi Fouad

3

几乎每个表达式都有一个值。
赋值是具有值的表达式。
表达式i = 42的值为42。

赋值从右到左关联,因此表达式a = b = ca = (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

例如,这是合法的:

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

这类似于y = z; x = y;。所以在这种情况下,z = 3.5,y = 3,x = 3;

但是如果您没有初始化z的值,它会发出警告。

int x,y, z;
x = 0;
y = 1;
//z = 2;
x = y = z;

1
只要每个变量仅被修改一次,这样做是合法的。例如,以下所有内容都有明确定义的行为:
x = y = z;
x = y = z = x + 1;
x = y++ + --z;
x += (y = (z += 1)) - 6;

但是以下内容具有未定义的行为,应该避免使用:

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

考虑说“以下是不合法的”意味着什么。C标准中没有规定你不能这样做的规则。有一条规则说C标准没有指定你这样做时会发生什么。但是,C标准也没有指定当你打开并写入Unix特殊设备时会发生什么。这在C标准方面也具有“未定义行为”,但你可能不会说它是非法的。有些程序需要这样做。你能给出一个“合法”的定义,允许后者而不允许前者吗? - Eric Postpischil
@EricPostpischil,我把它改成了未定义行为。对我来说没有区别,因为在我看来,应该始终避免未定义行为,所以我把它视为非法的。但你是正确的,它确实可以编译(尽管最好不要这样)。 - Tom Karzes

1

假设a、b和c都是非易失性的,并且考虑到评估的右结合性,这意味着a = b = c等价于a = (b = c),再次等价于b = c; a = b。


1
你还应该添加关于右/左值等的注释。 - alinsoar

1
在C编程语言中,一行代码中为多个变量赋值是完全可以的。
然而,通常不建议使用这种风格,因为它可能会在某些情况下导致不良副作用。
数学方程X = Y = Z的期望可能是:Y = Z并且X = Z(即将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)

结论:

'单行多个赋值'是一种支持的风格。它有其优点。

但是,如果程序员不知道涉及多个赋值语句的操作顺序,那么它可能会导致读取程序的人的期望与执行的实际结果之间的不一致。

为避免这种情况,应避免使用多个赋值语句。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接