C中的指针(while(* s1 ++ = * s2 ++))

时间:2016-08-19 11:04:38

标签: c pointers operator-precedence

以下程序

#include<stdio.h>

int main()
{
    char str1[] = "India";
    char str2[] = "BIX";
    char *s1 = str1, *s2=str2;
    while(*s1++ = *s2++)
        printf("%s", str1);

    printf("\n");
    return 0;
}

如何评估while循环中的条件?我可以在堆栈溢出here中看到类似的帖子,但是他们没有解释*运算符如何比postfix运算符具有更高的优先级。但实际上,postfix运算符比*(Derefernce)运算符具有更高的优先级。我们的参考here

的优先顺序表

请解释此代码如何打印输出

BndiaBIdiaBIXia 

5 个答案:

答案 0 :(得分:1)

条件内的赋值加上%s格式字符串解释了这一点:

分裂条件

c2 = s2;
c1 = s1;
condition = *c1 = *s2;
++s1, ++s2;

因此条件评估指针s2是否未指向空字符。

BIX属于这种情况。第三次迭代s2将位于字符串文字BIX的空终止符。

对于每次迭代,都会打印str1的内容。对于第一次运行,第一个字符已被B中的BIX覆盖。对于第二次运行,第二个字符已被I覆盖。对于上次运行,您获得BIXia。如果你想附加一个换行符,那就更清楚了:printf("%s\n", str1);会在不同的行上打印每次迭代。

注意:您可能会将===混淆,并且您真的在寻找不匹配的内容;这是一个非常常见的错误。

while(*s1++ == *s2++) {...}

答案 1 :(得分:1)

运算符优先级和执行顺序不一定相同。

*s1++ = *s2++

由编译器评估如下:

  1. 编译器看到“++”具有最高优先级。因为它是后增量运算符,所以它只是注意到在表达式的求值完成之后指针需要递增的事实。
  2. 编译器看到“*”运算符,告诉它应该取消引用s2,并将其用作RHS
  3. 在作业左侧相同的情况下,s1的char设置为s {的char
  4. 编译器回到它的注意,指针需要在表达式评估后递增,并且这样做。
  5. 即使++的优先级高于*,它仍然是最后完成的。这里的优先级只意味着必须对指针进行后增量操作,而不是对指针的值进行

答案 2 :(得分:0)

如果我没有弄错你,你必须写

while(*s1++ == *s2++)
    printf("%s",str1);

否则你只是替换而不是将str1 [i]与str2 [i]进行比较。

答案 3 :(得分:0)

表达式*s1++ = *s2++被评估为*(s1++) = *(s2++),表达式的值是s2先前值指向的char。所以条件检查s2是否指向str2的结尾(字符串以0结尾)。

所以while循环等于:

*s1 = *s2;
while(*s1 != 0){
    printf("%s",str1);
    s1++;
    s2++;
    *s1 = *s2;
}

所以循环基本上将str2复制到str1(只要str2更短)

答案 4 :(得分:0)

一元星号'*'运算符具有从右到左的关联,而不是从左到右的关联作为后缀增量'++'运算符。因此,在此示例中首先评估一元星号。这与LALR解析器的工作方式有关。

请参阅http://www.swansontec.com/sopc.html