10

问题是描述代码做什么,函数做什么。

以下代码是第二年 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;
}
4

3 回答 3

10
// what type is unsigned size?

这是一个unsigned intsize. 您可以像在普通指针算术中一样将它添加到指针 - 将此指针推进到数组的最末端。

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

好的,我们有

  • while(1)= while(true),或“永远循环”
  • *(--b)预减 b 并从数组的索引中读取值
  • 如果我们找到了 z,用我们从中读取的值替换第一个元素并返回b-y- 我们所在的数组索引的指针算法

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

// are the following 3 lines ever even reached?

不,我不这么认为。

于 2012-04-16T15:55:38.020 回答
7

what type is unsigned size

unsigned is short for unsigned int.

Why would you add an int to an array of ints?

Pointers and arrays are not the same thing. The code you've shown is using pointers, not arrays. After the int * b = y + size; line, b is a pointer that points to the entry size entries from where y is pointing. For example, if size were 2, b would be pointing to the third entry. ASCII-art:

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

I have the most difficulty understanding the following.

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

The loop looks at the entries in the memory pointed to by y starting with the entry before the one identified by size. If the entry is == to z, it sets y[0] to tmp and returns the index at which the entry was found (by using pointer arithmetic, b - y returns the number of entries between where b is pointing and the beginning of y. Since --b decrements the pointer, the loop works backward through the memory.

are the following 3 lines ever even reached?

No. The return will exit the function when the first matching entry is found, which may be at the beginning (as y[0] is set to z early on). As Ted Hoff points out in the comments, though, the loop will start and continue past the beginning (where y is pointing) if size is 0 on entry, which would probably eventually cause the program to fail with a memory access violation.

于 2012-04-16T15:55:35.340 回答
5

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

对于初学者:

  • unsigned是一个有效的 C++ 类型,是unsigned int. 通常最好避免,除非您进行位操作。

  • 您的代码中没有数组;您正在向指针添加一个整数。奇怪的[]是,不是数组索引,而是
    定义a[b]为完全等价于*(a+b). (至少对于内置类型。)你可能想找一本关于 C 的书来解释这一点;在 C++ 中,我们通常使用std::vector, 正是为了避免所有关于指针运算的混淆。

至于你难以理解的部分:对于初学者,让我们以理智的方式编写它:

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

唯一会引起问题的是 return 语句:这是指针减法;在这种情况下,因为y是数组的第一个元素(从代码的其余部分判断),b - y 所以计算 指向的元素的索引b

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

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

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

int i = size;
while ( i != 0 && y[i - 1] != z ) {
    -- i;
}
y[0] = tmp;
return i;
于 2012-04-16T16:16:14.347 回答