sizeof returns the size of a variable (bytes, e.g. sizeof(int) on most PCs will be 4; sizeof(char) will be 1 on most PCs, etc). In this case it is returning the amount of elements in the arrays, so ten.
The sizeof operator always returns the number of bytes used by its argument, using the most complete information available.
The int arr[WHATEVER] is the same as an int*, which has the size of a pointer to int.
However, the 'b' on line 6 is a known array type, so its size is the same as the size of ten ints.
Keep in mind that the argument to your 'size' function on line 4 is not necessarily the 'arr' aray declared on line 13. It makes no difference that they are declared with the same name and subscripts -- they are, quite simply, not necessarily the same objects. Hence, no further information about the original object is available inside the function (lines 5 through 9).
When used as a pointer, an array will degrade its type to a pointer to the first element. The reverse is not possible.
I was fairly sure it would return the amount of elements in an array. It usually does, anyway... Theoretically it should return the same value as (strlen(arr)) * int* but it never seems to.