【问题标题】:C multiple variable assignmentC 多变量赋值
【发布时间】:2020-07-23 01:35:52
【问题描述】:

我是软件工程专业的一年级学生,在我的上一个任务中,我使用了(链式分配)多重赋值。

讲师声称以这种方式赋值是非法的。

X = Y = Z;

(三个变量在函数开头声明)。

如果你能向我解释分配的行为是否正确以及老师声称的内容是否正确,我会很高兴。

【问题讨论】:

  • 你为什么会认为你的老师可能弄错了?

标签: c expression variable-assignment expression-evaluation


【解决方案1】:

这是合法的,例如:

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;

【讨论】:

    【解决方案2】:

    只要每个变量只修改一次,这没有什么不合法的。例如,以下都具有明确定义的行为:

    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 标准而言,这也具有“未定义的行为”,但您可能不会说它是非法的。有些程序需要这样做。你能给出一个允许后者但不允许前者的“合法”的定义吗?
    • @EricPostpischil 我将其更改为未定义的行为。对我来说这没有什么区别,因为就我而言,总是要避免未定义的行为,所以我认为它是非法的。但是你是正确的,它确实可以编译(尽管如果它没有编译会更好)。
    【解决方案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 关键字声明或声明在全局范围内,则为 fe),您可以将此值分配给 YX那句话。 尽管分配本身即使在那时也不是非法的,但如果您使用分配的对象之一,程序将给出未定义的结果/输出。


    只针对多个作业,没有什么违法的,你甚至可以使用:

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

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


    讲师声称以这种方式赋值是非法的。

    如果可能的话,我会问她/他或你的老师,她/他的意思是什么。也许您应该关心您的课程的某些特定内容。

    【讨论】:

    • 通常用“正确”一词代替“正确”来表示特定的表达式或语句在语法上是有效的。
    • 所涉及的类型需要赋值兼容,不能相同。
    • @pmg 在您发布评论时,我已经在测试您的版本。我纠正了它。有趣的隐式转换......但有一点是要关心是否使用不同类型的对象:被分配的对象需要能够保存分配给这个对象的对象的值。
    • 也许你的讲师试图阻止你分配指针而不是文字,而不是说他告诉你永远不要使用那种语法!
    【解决方案4】:

    几乎每个表达式都有一个值。
    赋值是一个有值的表达式。
    表达式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));
    

    【讨论】:

      【解决方案5】:

      在一行中为多个变量赋值完全没问题,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++ 处理如下:

      第一步:将n(100)的值赋给Z

      第二步:增加n的值(n变成101)

      第 3 步:将 Z 的值赋给 Y(Y 变为 100)

      第 4 步:将 Y 的值赋给 X(X 变为 100)

      结论:

      “单行中的多个分配”是受支持的样式。它有它的好处。

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

      为避免这种情况,不鼓励多次分配。

      【讨论】:

        【解决方案6】:

        连同求值的右结合性,假设a、b、c是非易失性的,则a = b = c等价于a = (b = c),又等价于b = c; a = b

        【讨论】:

        • 您还应该添加有关右/左值等的 cmets。
        猜你喜欢
        • 2014-03-22
        • 1970-01-01
        • 2010-12-29
        • 2014-09-03
        • 1970-01-01
        • 1970-01-01
        • 2014-11-27
        • 2012-07-18
        • 1970-01-01
        相关资源
        最近更新 更多