while循环条件中的语法是什么?

时间:2014-03-08 14:11:53

标签: c++ c syntax

while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );

我在codegolf上遇到过这个问题

请解释?:的用法,为什么while循环后没有声明?为什么在括号后面有;

7 个答案:

答案 0 :(得分:4)

在while循环的括号内有一个布尔运算:

while (boolean);

由于三元运算符是布尔运算符,因此它非常合法。

这是做什么的?看起来像模数运算,打印范围高达101。

我同意它的含义和含糊不清。它看起来更像是代码混淆亚军。但它似乎是可编辑和可运行的。你试过吗?它做了什么?

答案 1 :(得分:3)

?:是三元运营商。

表单<A> ? <B> : <C>的表达式求值为:

  • 如果<A>为真,则评估为<B>
  • 如果<A>为false,则评估为<C>

;循环后的while表示空指令。它相当于写作

while (<condition>) {}

您发布的代码似乎被混淆了。

答案 2 :(得分:2)

  

请解释?:

的用法

那是条件运算符a ? b : c评估a并将其转换为布尔值。然后它评估b是否为真,或c如果为假,则表达式的总值是评估bc的结果。

所以第一个子表达式:

  • t-i%10分配给i。该表达式的结果是i
  • 的新值
  • 如果i不为零,则表达式的结果为i/10
  • 否则,打印j,表达式的结果为零(因为printf返回打印的非零字符数,!转换为零。

然后,仅在第一个表达式的结果为零时才评估第二个子表达式||之后。我会告诉你弄清楚那是做什么的。

  

为什么while循环后没有语句?

有一个空语句;,所以循环体无效。所有动作都发生在条件表达式的副作用中。当代码的目的是困扰读者时,这是一种常见的技术;但是在编写任何你关心的人可能需要维护的代码时,请不要这样做。

答案 3 :(得分:0)

这是Conditional Operator(也称为三元运算符)。

这是一种单行语法,与if (?)条件doA else (:) doB相同;

在你的例子中:

(i=t-i%10 ? i/10 : !printf("%d\n",j)

相当于

if (i=t-i%10)
  i/10;
else
  !printf("%d\n",j);

答案 4 :(得分:0)

?:是if if else的简写符号

(i=t-i%10 ? i/10 : !printf("%d\n",j)<br>

等于

if( i= t-i%10 )
then { i/10 }
else { !printf("%d\n",j) }

你的while循环将在||之前的语句中运行是真的或在||之后的陈述是的。

请注意您的代码没有任何意义。

答案 5 :(得分:0)

while((i = ti%10?i / 10:!printf(&#34;%d \ n&#34;,j))||(i = ++ j&lt; 0?-j:j) &lt; 101);

在人类最可读的情况下,我可以为你做,它相当于:

while (i < 101)
{
  i = (t - i) % 10;
  if (i > 0)
  {
    i = i / 10;
  }
  else
  {
    printf("%d\n",j);
  }

  i = ++j;
  if (i < 0)
  {
    i = i - j;
  }
  else
  {
    i = j;
  }
}

问候。

答案 6 :(得分:0)

我是该代码的骄傲犯罪者。这里是完整版:

main()
{
    int t=getchar()-48,i=100,j=-i;
    while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101  );
}

这是我提交的编程挑战或#34;代码高尔夫&#34;要求您创建最接近数字作为参数的程序,并打印包含给定数字的-100到100范围内的所有数字。禁止使用字符串或正则表达式。

Here是挑战的链接。

关键是它正在将所有工作完成到一个评估为布尔值的语句中。实际上,这是将两个不同的while循环合并为一个循环的结果。它等同于以下代码:

main()
{
  int i,t=getchar()-'0',j=-100;
  do 
  {
      i = j<0? -j : j;
      do
      {
          if (t == i%10) 
          {
             printf("%d\n",j);
             break;
          }
      }
      while(i/=10);
  }
  while (j++<100);       
}

现在让我们解析一下这个循环。

首先,初始化。

int t=getchar()-48,i=100,j=-i;

将从标准输入中读取一个字符。您应该键入0到9之间的数字.48是零字符的值(&#39; 0&#39;),因此t最终将保持0到9之间的整数。

我和j将是100和-100。 j将从-100到100(包括)运行,并且我将始终保持j的绝对值。

现在循环:

while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101  );

让我们把它读成

while ( A || B ) /* do nothing */ ;

A等于(i = ti%10?i / 10:!printf(&#34;%d \ n&#34;,j))并且B等于(i = ++ j <0? - Y:j)的&LT; 101

重点是A被评估为布尔值。如果为真,则B根本不会被评估,循环将再次执行。如果为假,则将评估B,反过来,如果B为真,我们将再次重复,一旦B为假,则将退出循环。

所以A是内环,B是外环。让我们解剖一下

(i=t-i%10?i/10:!printf("%d\n",j))

它是i = CONDITION形式的三元运算符? X:Y;这意味着将评估第一个CONDITION。如果为true,我将被设置为X的值;否则我将被设置为Y.

此处条件(t-i%10)可以读作t - (i%10)。如果i modulo 10与t不同,则将评估为true;如果i%10和t为相同值,则为false。

如果不同,则相当于i = i / 10; 如果相同,操作将是i =!printf(&#34;%d \ n&#34;,j)

如果你考虑得足够困难,你会发现它只是一个循环来检查i中整数中的任何小数位是否等于t。

循环将继续运行直到耗尽i的所有数字(i / 10将为零)或运行printf语句。 Printf返回打印的位数,该位数应始终大于零,因此!printf(...)应始终求值为false,同时终止循环。

现在对于B部分(外部循环),它只会递增j直到达到101,并且将i设置为j的绝对值。


希望我有任何意义。

是的,我通过在谷歌搜索我的代码找到了这个帖子,因为我无法找到挑战帖。