我正在为我的编程课程学习,最后一个测试中的一个问题有这个代码,必须"计算".

#include <stdio.h>

int main(void) {
    short a[4] = {66, 066, 0x66};
    int i = 0, s = 0, p = 15;

    for (++a[i]; !i, p = a[i]; s += a[i++]) {
        p = a[i] >> 2 | p;
        a[i] &= p;
    }

    printf("%d", s);
}

最初的问题是找到s的值,但我有一个问题,理解为什么p = 67是"第一次迭代之前",如果它被声明为p = 15.p = a[i]不是循环条件而不是声明值的方法吗?

我试着"计算"p = 15,我没有得到正确的结果,p = 67,我得到正确的结果.

推荐答案

我知道这是故意写得很糟糕的考试,但我希望你意识到它有多糟糕,为什么它不应该这样做.解构它可能有助于澄清它实际上在做什么.

首先,它有太多的副作用,以及太多与循环控制无关的动作.将for循环转换为while会有所帮助,所以如下:

    for (++a[i]; !i, p = a[i]; s += a[i++]) {
        ...
    }

变成这样:

    ++a[i];
    while (!i, p = a[i]) {
        ...
        s += a[i++];
    }

,操作符执行两个操作,但只返回第二个操作的结果.如果您希望第一个操作的副作用影响第二个操作,它可能是有用的,但!i没有副作用,所以可以丢弃.循环现在是:

    ++a[i];
    while (p = a[i]) {
        ...
        s += a[i++];
    }

测试表达式是一个任务,乍一看可能会令人困惑,所以不是一个好主意.条件表达式不应该出现在条件表达式中.它可以被移出,并替换为分配的变量p,但是p在两个地方被更新,一个是在循环之前,另一个是在循环结束之前.

    ++a[i];
    p = a[i];  // Update p here first.
    while (p) {
        ...
        s += a[i++];
        p = a[i];  // Update p before looping again.
    }

这应该会让循环清晰.在里面,p是在=符号两侧的表达式中,虽然这是允许的,它意味着一个变量用于两个东西,当发生这种情况时,你需要转换你的 idea —如果你错过了它,你会认为变量的错误含义.每次意义改变时添加一个新变量:

    short a[4] = {66, 066, 0x66};
    int i = 0, s = 0, p = 15;

    ++a[i];
    p = a[i];
    while (p) {
        int m = a[i] >> 2 | p;
        a[i] &= m;
        s += a[i++];
        p = a[i];
    }

应该很清楚,p可以在任何地方被a[i]取代,但我会保持原样.这应该清楚地说明代码现在做什么,以及为什么.如果需要,可以将while循环转换回for循环:

    for (p = a[i];p;p = a[i]) {

它看起来并不太有用,但这就是它最终的用途,所以我会把它作为while循环.

C++相关问答推荐

使用NameSurname扫描到两个单独的字符串

如何在C中从函数返回指向数组的指针?

如何将字符串argv[]赋给C中的整型数组?

Char变量如何在不使用方括号或花括号的情况下存储字符串,以及它如何迭代到下一个字符?

GCC不顾-fno-Builtin-SINCOS旗帜向SINCOS发出呼唤

加密解密工作正常,但返回错误0x80090005

用gcc-msse 2编译的C程序包含AVX 1指令

S的这种管道实施有什么问题吗?

<;unistd.h>;和<;sys/unistd.h>;之间有什么区别?

添加函数会 destruct 嵌入式C代码(无IDE)

在进程之间重定向输出和输入流的问题

在vfork()之后,链接器如何在不 destruct 父内存的情况下解析execve()?

使用%f格式说明符打印整数值

为什么这个分配做得不好呢?

Fscanf打印除退出C代码为1的程序外的所有内容

某些EAX值的不同调用方的CPUID结果不一致

生成一个半RNG,结果用C表示(无随机/随机)

';malloc():损坏的顶部大小';分配超过20万整数后

浮点正零何时不全为零?

如何转义包含指令中的字符?