No, you cannot reassign an array as you do here:
int q[3];
q = *(int [3]) arrayReturn(z);
If you want to copy the contents of z to q, you can do that with the memcpy library function:
memcpy( q, z, sizeof z );
but the = operator isn't defined to copy array contents.
Otherwise, the best you can do is declare q as a pointer and have it point to the first element of z:
int *q = z; // equivalent to &z[0]
Unless it is the operand of the sizeof or unary * operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T" will be converted, or "decay", to an expression of type "pointer to T" and the value of the expression will be the address of the first element of the array - that's why the above assignment works.
Arrays in C are simple sequences of elements - there's no metadata indicating their size or type, and there's no separate pointer to the first element. As declared, the arrays are
+---+
z: | 1 | z[0]
+---+
| 2 | z[1]
+---+
| 3 | z[2]
+---+
...
+---+
q: | ? | q[0]
+---+
| ? | q[1]
+---+
| ? | q[2]
+---+
There's no separate object q to assign to.