理解写得不好的代码,第二年CS过去的论文

时间:2012-04-16 15:44:57

标签: c++ c algorithm coding-style

问题是描述代码的作用,功能的作用。

以下代码是过去第二年C和C ++模块考试试卷的一部分。任务是描述以下代码的作用。我完全按照提交的方式编写了代码,并自己添加了一些注释。

int g(int * y, unsigned size, int z) {
    int tmp = y[0];
    // what type is unsigned size? Int I presume. Why would you add an int to an array of ints?
    int * b = y + size; 
    y[0] = z;
    // I have the most difficulty understanding the following.
    while (1) if (*(--b)==z){y[0] = tmp; return b - y;};
    // are the following 3 lines ever even reached?
    y[0] = tmp;
    if (tmp == z) return 0;
    else return -1;
}

3 个答案:

答案 0 :(得分:10)

// what type is unsigned size?

这是一个名为unsigned int的{​​{1}}。您可以像在普通指针算术中一样将它添加到指针 - 将此指针前进到数组的最末端。

size

好的,我们有

  • while (1) if (*(--b)==z){y[0] = tmp; return b - y;}; = while(true)或'loop forever'
  • while(1)预先递减b并从数组索引中读取值
  • 如果我们找到z,用我们从中读取的值替换第一个元素并返回*(--b) - 我们所在的数组索引的指针算法

即。我们正在向后扫描数组以查找b-y的最后一个实例并返回我们找到它的索引。我们总是在数组中找到z,因为我们将它作为第一个元素放在那里,即如果z不在数组中,那么我们返回0。

z

不,我不这么认为。

答案 1 :(得分:7)

  

什么类型是无符号大小

unsignedunsigned int的缩写。

  

为什么要在int数组中添加int?

指针和数组不是一回事。您显示的代码是使用指针,而不是数组。在int * b = y + size;行之后,b是一个指针,指向size所指向的条目y条目。例如,如果size2,则b将指向第三个条目。 ASCII艺术:

+---------+
| entry 0 |<--- `y` points here
| entry 1 |
| entry 2 |<--- `b` points here if `size` is `2`
| entry 3 |
| entry 4 |
+---------+
  

我最难理解以下内容。

     

while (1) if (*(--b)==z){y[0] = tmp; return b - y;};

循环查看y指向的内存中的条目,从之前的条目开始 size标识的条目。如果条目为==z,则会将y[0]设置为tmp并返回找到条目的索引(通过使用指针算法b - y返回b指向的位置和y的开头之间的条目数。由于--b递减指针,循环向后通过内存。

  

是否有以下3条线路?

没有。 return将在找到第一个匹配条目时退出该函数,该条目可能位于开头(因为y[0]早期设置为z)。正如Ted Hoff在评论中指出的那样,如果ysize处于0时,循环将开始并继续经过开头({{1}}指向的地方),这可能最终会导致程序因内存访问冲突而失败。

答案 2 :(得分:5)

这段代码的第一件事就是证明作者不称职。 但我认为这是作业的一部分:理解编写的代码 无能的人。

首先:

  • unsigned是一种有效的C ++类型,是unsigned int的缩写。它的 通常最好避免,除非你做一点操作。

  • 您的代码中没有数组;你要为a添加一个整数 指针。奇怪的是,[]不是数组索引,而是 定义为a[b]完全等同于*(a+b)。 (至少对于 类型的构建。)你可能想找一本关于C的书来解释 这个;在C ++中,我们通常使用std::vector,正是为了避免全部 这种关于指针算术的困惑。

至于你难以理解的部分:首先,让我们来 以理智的方式写下来:

while ( true ) {
    -- b;
    if ( *b == z ) {
        y[0] = tmp;
        return b - y;
    }
}

关于唯一应该引起问题的事情就是回归 声明:这是指针减法;在这种情况下,因为y是 数组的第一个元素(从代码的其余部分判断),b - y 计算b指向的元素的索引。

这里指针的使用将是纯粹的混淆,除了 成语在C中无处不在,并且在C ++中使用迭代器进行。

你是对的,循环后的代码永远不能执行;该 离开循环的唯一方法是通过return

编写循环的更简洁的方法是:

int i = size;
while ( i != 0 && y[i - 1] != z ) {
    -- i;
}
y[0] = tmp;
return i;