Q:

Understanding poorly written code, 2nd year CS past paper

The question is to describe what the code does, what the function does.
The following code is part of the past exam papers for a 2nd year C and C++ module. The task is to describe what the following piece of code does. I've written the code exactly as presented, with some comments added by myself.    
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;
}

A:

// what type is unsigned size?

It's an unsigned int called size. You add it to a pointer as in normal pointer arithmetic - advance this pointer to the very end of the array.
while (1) if (*(--b)==z){y[0] = tmp; return b - y;};

OK, we've got

while(1) = while(true), or 'loop forever'
*(--b) pre-decrement b and read the value from that index of the array
if we've found z, replace the first element with the value we read from it and return b-y - pointer arithmetic for the array index we're at

i.e. we're scanning backwards through the array to find the last instance of z and returning the index at which we found it. We will always find z in the array because we put it there as the first element, i.e. if z isn't in the array then we return 0.
// are the following 3 lines ever even reached?

No, I don't think so.

A:

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.

A:

The first thing this code does is prove that the author is incompetent.
But I gather that's part of the assignment: understanding code written
by incompetent people.
For starters: 

unsigned is a valid C++ type, a contraction for unsigned int.  It's
generally best avoided, unless your doing bit manipulations.
There are no arrays in your code; you're adding an integer to a
pointer.  And curiously enough, [] is not array indexation, but
defined so that a[b] is exactly equivalent to *(a+b).  (At least for
the build in types.)  You might want to find a book about C, to explain
this; in C++, we generally use std::vector, precisely to avoid all of
this confusion about pointer arithmetic.

As for the part you have difficulty understanding: for starters, let's
write it in a sane manner:
while ( true ) {
    -- b;
    if ( *b == z ) {
        y[0] = tmp;
        return b - y;
    }
}

About the only thing which should cause an issue there is the return
statement: this is pointer subtraction; in this case, since y is the
first element of an array (judging from the rest of the code), b - y
calculates the index of the element pointed to by b.
The use of pointers here would be pure obfuscation, except that the
idiom is ubiquitous in C, and is carried on with iterators in C++.
And you're right that the code after the loop can never be executed; the
only way of leaving the loop is through the return.
A much cleaner way of writing the loop would be:
int i = size;
while ( i != 0 && y[i - 1] != z ) {
    -- i;
}
y[0] = tmp;
return i;

