这个循环完成的顺序是什么?

时间:2016-05-10 20:09:49

标签: c

char destination[6];
char source[] = "hello";
char* a = destination;
char* b = source;

while (*a++ = *b++);
return destination;

是否将* a设置为* b,然后检查值!= 0然后递增指针?

或者它是否会像增加指针一样,然后检查* a = * b之前的值,然后检查!= 0?

5 个答案:

答案 0 :(得分:3)

while循环如:

while (<expr>) <body>;

的执行方式如同:

while (true) {
    int temp = <expr>;
    if (!temp) {
        break;
    }
    <body>
}

因此,在测试值是否为零之前,它会评估整个<expr>,包括任何副作用(例如赋值和增量)。

表达式temp = *a++ = *b++的评估结果为:

int new_a = a + 1; int new_b = b + 1; // These may be evaluated in either order
temp = (*a = *b); // value of temp will be that value that was assigned to *a
a = new_a; b = new_b; // Also in either order

因此,测试的值是在变量递增之前分配的值。

答案 1 :(得分:3)

首先,评估* b,并将值分配给* a 其次,++的副作用发生了(a ++和b ++) 第三,使用后增量之前的* a值来决定是进入还是退出循环。

换句话说,您可以将程序翻译成以下等效表示:

int main(){
  char  destination[6];
  char  source[] = "hello";
  char* a = destination;
  char* b = source;

  while (1){
    *a=*b;
    int tmp=*a;
    a = a + 1;
    b = b + 1;
    if (!(tmp))
      break;
    // the original loop body comes here
  }
  return 0;
}

答案 2 :(得分:0)

postincrement 运算符首先在其表达式的上下文中使用其操作数,然后递增其值。

所以在这种情况下,你是对的。它将*a设置为*b,然后递增ab,因为后递增++运算符的优先级高于取消引用运算符*。由于最后评估了赋值,所以赋值是表达式的值,while然后检查true / false,即非零或零。

实际增量在其操作数被计算之后的某个点发生。因此,在没有序列点的同一表达式中对同一变量使用++--运算符会导致未定义的行为。

答案 3 :(得分:-1)

  

是否将* a设置为* b,然后检查值!= 0然后递增指针?

它递增指针,递减它们,赋值,表达式产生该值,即在它指定NULL之后,它将被评估为false并停止。

优先顺序

  1. ++
  2. *
  3. =

答案 4 :(得分:-1)

赋值运算符的计算范围为right-to-left,优先级(评估顺序)低于++(后增量)运算符。

要回答你的问题,

while (*a++ = *b++);

首先评估*b++,然后评估*a++。由于这是后增量,因此*a的先前值获得*b的先前值。最后,表达式转换为布尔值,如果b未指向空地址,则表达式的计算结果为true,否则为false。

相当于:

while (*a = *b) {
    ++a, ++b;
}