编辑:这不是我的代码,这是考试的一部分。
这是输出:
60 -3 //从-5到-3
59 0 //从-3到0
58 3
57 6
2
我不知道为什么在第一个循环中将“ i”变量增加两次,而在第二个循环中将变量增加三倍。
int a=61,i=-5;
for(int *p=&i;(a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1);(*p)++){
--a;
printf("%d %d \n",a,*p);
if(*p>3){
a=(!(--a)&&a++)?3:2;
break;
}
else continue;
}
printf("%d\n",a);
答案 0 :(得分:1)
与这样的代码唯一有意义的事情(除了在此处向作者说不允许的单词外)是重写它。 else continue
可以删除。它什么也没做。
然后我们去找野兽(a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1)
。这将在每个循环的开始执行,因此我们可以这样重写它:
bool cond = (a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1);
for(int *p=&i; cond; (*p)++){
cond = (a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1);
--a;
printf("%d %d \n",a,*p);
if(*p>3){
a=(!(--a)&&a++)?3:2;
break;
}
}
现在,当它从标题中删除时,我们可以开始反汇编它了。首先,将a++
提取为if语句:
a++;
if((*p)++)
cond = (++(*p),(a--)-1)
else
cond = ((*p)+=3,a-1);
已经看起来更加清晰了。现在,让我们摆脱那些逗号:
if((*p)++) {
++(*p);
cond = (a--)-1;
}
else {
(*p)+=3;
cond = a-1;
}
让我们继续分离
if((*p)++) {
(*p)++; // Does not make a difference here, but it's easier to not mix pre and post
a--;
cond = a;
}
else {
(*p)+=3;
cond = a-1;
}
就我们仅仅通过机械分解就可以得到。为了进一步发展,我们需要三思。因此,让我们继续下一个a=(!(--a)&&a++)?3:2;
,我们也将对其进行简化。
--a; // Will be executed no matter what
if(!a) {
a++; // Will only be executed if !(--a) evaluates to true
a = 3; // But it does not matter since we are reassigning a
} else {
a = 2;
}
这将在简化后给出此代码。
bool cond;
a++;
if((*p)++) {
(*p)++;
a--;
cond = a;
} else {
(*p)+=3;
cond = a-1;
}
for(int *p=&i; cond; (*p)++){
a++;
if((*p)++) {
(*p)++;
a--;
cond = a;
} else {
(*p)+=3;
cond = a-1;
}
--a;
printf("%d %d \n",a,*p);
if(!a) {
a = 3;
} else {
a = 2;
}
}
printf("%d\n",a);
现在实际上可以对此进行推理了,只需一步一步在纸上执行此代码就应该很容易。
答案 1 :(得分:0)
在for循环声明末尾的(*p)++
语句不会在第一次迭代中执行。它只能在两个连续的迭代之间执行。
答案 2 :(得分:0)
首先,int a=61,i=-5;
给出a
= 61且i
= −5。
然后,for
的初始子句int *p=&i
将p
设置为指向i
。从这一点开始,我们可以将*p
等同于i
。
然后计算for
,(a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1)
的控制表达式。其最高/最外面的运算符是? :
。该(a++,(*p)++)
的第一个操作数被求值。这会将a
设置为62,并将i
设置为-4。来自逗号运算符的结果是增量之前的i
(*p
)的值,所以它是-5。
在? :
操作中使用-5进行选择。由于它不为零,因此将评估?
和:
之间的操作数。那就是(++(*p),(a--)-1)
。这会将i
设置为-3,将a
设置为61。值是a
在增量减1之前,即62-1 =61。因此表达式为非零,表示循环应该继续。
程序控制流到for
的主体中,其中--a
递减a
到60。
然后printf
向我们显示a
为60,而i
为-3。
测试*p>3
为假,因为i
为-3,所以执行了continue
。
这将导致对for
的迭代表达式求值。即(*p)++
,因此i
设置为-2。
然后对控制表达式求值。和以前一样,对? :
的第一个操作数(a++,(*p)++)
进行求值。这会将a
设置为61,将i
设置为-1,表达式的值为-2。
再次计算第二个操作数(++(* p),(a-)-1)。将i
设置为0,将a
设置为60,其值为59。
在身体内部,--a
减少a
至59。
printf
向我们显示a
为59,i
为0。
再次*p>3
为假,因此执行了continue
。
这将控制迭代表达式(*p)++
,该表达式将i
设置为1。
然后从? :
的第一个操作数开始计算控制表达式。现在(a++,(*p)++)
将a
设置为60,将i
设置为2,表达式值为1。
计算? :
的第二个操作数(++(* p),(a-)-1),将i
设置为3,将a
设置为59 ,表达式值为59,因此循环继续。
--a
将a设置为58。
printf
向我们显示a
是58,而i
是3。
再次*p>3
为假,因此执行了continue
。
这将控制迭代表达式(*p)++
,该表达式将i
设置为4。
然后从? :
的第一个操作数开始计算控制表达式。现在(a++,(*p)++)
将a
设置为59,将i
设置为5,表达式值为4。
求值? :
的第二个操作数(++(* p),(a-)-1),将i
设置为6,将a
设置为58 ,表达式值为58,因此循环继续。
--a
将a设置为57。
printf
显示a
是57,i
是6。
现在*p>3
是正确的,因此if
内部的语句将被执行。
这些以a=(!(--a)&&a++)?3:2;
开头。在这里--a
将a
设置为56并求出该值。然后!
对其进行逻辑反转,生成0。这将导致&&
生成0,而不计算其第二个操作数。因此? :
的第一个操作数为0,这导致? :
的第三个操作数被求值。该操作数为2,因此是分配给a
的值。
最后的printf
向我们显示了a
的当前值2。