Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C for循环中变量增加的奇怪行为_C - Fatal编程技术网

C for循环中变量增加的奇怪行为

C for循环中变量增加的奇怪行为,c,C,编辑:这不是我的代码,这是考试的一部分 这是输出: 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){

编辑:这不是我的代码,这是考试的一部分

这是输出:

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);  

for循环声明末尾的
(*p)+
语句将不会在第一次迭代中执行。它只在两次连续迭代之间执行。

首先,
inta=61,i=-5
给我们提供了
a
=61和
i
=−五,

然后,
int*p=&i
的初始子句将
p
设置为指向
i
。从这一点开始,我们可以将
*p
等同于
i

然后计算
(a++,(*p)++)?(++(*p),(a-)-1):((*p)+=3,a-1)
的控制表达式。其最高/最外层运算符是
?:。计算
(a++,(*p)+)+
的第一个操作数。这会将
a
设置为62,将
i
设置为62−4.逗号运算符的结果是增量之前的
i
*p
)值,因此−五,

那−5用于在
中选择:操作。因为它不是零,所以计算
之间的操作数。那就是
(++(*p),(a-)-1)
。这将
i
设置为−3和
a
至61。增量减1之前的值为
a
,即62−1 = 61. 因此,表达式为非零,表示循环应继续

程序控制流入
主体,其中
--a
a
减至60

然后,
printf
告诉我们,
a
是60,
i
是60−三,

测试
*p>3
为假,因为
i
为假−3,因此执行
continue

这将导致对
的迭代表达式求值。即
(*p)+
,因此
i
设置为−二,

然后计算控制表达式。与前面一样,
的第一个操作数:
(a++,(*p)++)
,进行计算。这会将
a
设置为61,将
i
设置为−1,表达式的值为−二,

再次计算第二个操作数(++(*p),(a--)-1。这将
i
设置为0,
a
设置为60,其值为59

在车身内部,
--a
a
减至59

printf
显示
a
为59,
i
为0

同样,
*p>3
为假,因此执行
继续

这将控制迭代表达式,
(*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
为假,因此执行
继续

这将控制迭代表达式,
(*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的当前值。

对这样的代码唯一明智的做法是重写它(除了向作者说出此处不允许的单词)。可以删除
否则继续
。它一事无成

然后我们看野兽
(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;
    }
}
现在,当它从收割台上拆下时,我们可以开始拆解它了。首先,将EXTRACT
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);  

现在,我们可以对其进行推理了,只需在纸上一步一步地执行该代码就相当容易了。

该代码实际上是无法理解的。让您的目标是编写不仅编译器能够理解的代码,而且