代码之家  ›  专栏  ›  技术社区  ›  Ahmed

int[]arr={0};int值=arr[arr[0]+];值=1?

  •  12
  • Ahmed  · 技术社区  · 17 年前

    今天我偶然看到一篇文章 Eric Lippert 他试图澄清运算符优先级和评估顺序之间的神话。最后有两段代码让我感到困惑,这是第一段:

          int[] arr = {0};
          int value = arr[arr[0]++];
    

    现在,当我考虑变量值的值时,我简单地计算它为一。下面是我认为它是如何工作的。

    1. 里面有一件物品;这 项的值为0。
    2. 第二步获取arr[0]--0的值
    3. 第三步得到arr的值[值 arr[0]再次–仍然是0。
    4. 第四,指定步骤3的值 (0)设置为变量值--价值观= 现在0
    5. 加上步骤2的值1——现在 arr[0]=1。

    显然这是错误的。我试图在c#规范中搜索一些关于增量何时实际发生的明确声明,但没有找到任何。
    第二个片段来自Eric的评论 blog post

     int[] data = { 11, 22, 33 }; 
     int i = 1;
     data[i++] = data[i] + 5;
    

    下面是我认为这个程序将如何执行——在声明数组并将1分配给I之后。[请耐心听我说]

    1. 获取数据[i]--1
    2. 将该值添加到步骤1的值中 5 --6
    3. 步骤2的值——数据[i]=6

    根据我的理解,这个数组现在应该包含值{11, 27 , 33}. 然而,当我循环打印数组值时,我得到:{11,38,33}。这意味着 增量发生在取消引用数组之前!
    怎么会?这个帖子不是应该是帖子吗?i、 发生在其他事情之后。
    我错过了什么?

    6 回复  |  直到 6 年前
        1
  •  19
  •   Jon Skeet    17 年前

    后增量操作是计算整个表达式的一部分。这是一种副作用,它发生在计算值之后,但在计算任何其他表达式之前。

    换句话说,对于任何表达式E,E++(如果合法)表示类似(伪代码):

    T tmp = E;
    E += 1;
    return tmp;
    

    那是 评估E++的一部分,然后再评估其他内容。

    有关更多详细信息,请参见C#3.0规范第7.5.9节。


    之前 对RHS进行了评估。

    在你的例子中:

    int[] data = { 11, 22, 33 }; 
    int i = 1;
    data[i++] = data[i] + 5;
    

    相当于:

    int[] data = { 11, 22, 33 }; 
    int i = 1;
    // Work out what the LHS is going to mean...
    int index = i;
    i++;
    // We're going to assign to data[index], i.e. data[1]. Now i=2.
    
    // Now evaluate the RHS
    int rhs = data[i] + 5; // rhs = data[2] + 5 == 38
    
    // Now assign:
    data[index] = rhs;
    

        2
  •  5
  •   VoteyDisciple    17 年前

    对于第一个代码段,顺序是:

    1. 按照您的描述声明arr:
    2. 检索arr[0]的值,即0
    3. 将arr[0]的值增加到1。
    4. 检索arr[(#2的结果)]的值,该值为arr[0],其(per#3)为1。
    5. value .
    6. 值=1

    对于第二个代码段,计算仍然是从左到右的。

    1. 我们将结果存储在哪里?在data[i++]中,即data[1],但现在i=2
    2. 我们要补充什么?数据[i]+5,即现在的数据[2]+5,即38。

        3
  •  2
  •   Max    17 年前
    data[i++] // => data[1], then i is incremented to 2
    
    data[1] = data[2] + 5 // => 33 + 5
    
        4
  •  0
  •   Kiam Kiam    17 年前

    我希望post increment操作符在使用变量的值后对其进行递增。 在这种情况下,变量在第二次引用变量之前递增。

    data[i++] = data[i++] + data[i++] + data[i++] + 5
    

    如果它像你说的那样,那么你可以删除增量操作符,因为它实际上什么都不做,在我报告的指令中。

        5
  •  0
  •   Daniel    17 年前

    你必须分三步思考作业:

    1. 评估右手侧
    2. 将步骤2中的值分配给步骤1中的内存位置。

    A().B = C()
    

    然后首先运行A(),然后运行C(),然后运行属性设置器B。

    本质上,你必须把你的陈述看作

    StoreInArray(data, i++, data[i] + 5);
    
        6
  •  -4
  •   Leahn Novash    17 年前

    原因可能是一些编译器将i++优化为+i。大多数情况下,最终结果都是一样的,但在我看来,这是编译器出错的少数情况之一。

    我现在无法访问VisualStudio来确认这一点,但请尝试禁用代码优化,看看结果是否会保持不变。

    推荐文章