I found that was a trap made by our C Compiler!
(So is it a standard of CPL? C99 or something else?)
I wrote following code in visual studio 2010 on platform x86.
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a[3] = { 0xa, 0xb, 0xc }; // Declare an array which include 3 items.
    int len = sizeof(a) / sizeof(a[0]); // And the variable len refer to the code like @Neil Chowdhury o_O
    int * pa0 = a; // Then i declared a pointer point to the first element to the source array a.
    int len2 = sizeof(a) / sizeof(pa0[0]); // Len2 refer to the same action like previous statement.
    int len3 = sizeof(a) / sizeof(pa0); // Len3 refer to a's size(one int's size)divide may be a int pointer's size.
    int len4 = sizeof(pa0); // Len4 is the size of int pointer pa0.
    int len5 = sizeof(a); // And len5 is the size of pa0, the same theory as previous stmt represented.
    int len6 = sizeof(a[0]); // Len6 equal to sizeof(int)
    int len7 = sizeof(pa0[0]); // Len7 equal to sizeof(int) too.
    return 0;
}
Then i built them, And showed disassembly code. the results likes:
    int a[3] = { 0xa, 0xb, 0xc };
00D13108  mov         dword ptr [ebp-14h],0Ah  
00D1310F  mov         dword ptr [ebp-10h],0Bh  
00D13116  mov         dword ptr [ebp-0Ch],0Ch  
    int len = sizeof(a) / sizeof(a[0]);
00D1311D  mov         dword ptr [ebp-20h],3  // caution!
    int * pa0 = a;
00D13124  lea         eax,[ebp-14h]  
00D13127  mov         dword ptr [ebp-2Ch],eax  
    int len2 = sizeof(a) / sizeof(pa0[0]);
00D1312A  mov         dword ptr [ebp-38h],3   // caution!
    int len3 = sizeof(a) / sizeof(pa0);
00D13131  mov         dword ptr [ebp-44h],3   // caution!
    int len4 = sizeof(pa0);
00D13138  mov         dword ptr [ebp-50h],4  
    int len5 = sizeof(a);
00D1313F  mov         dword ptr [ebp-5Ch],0Ch  
    int len6 = sizeof(a[0]);
00D13146  mov         dword ptr [ebp-68h],4  
    int len7 = sizeof(pa0[0]);
00D1314D  mov         dword ptr [ebp-74h],4  
    return 0;
00D13154  xor         eax,eax  
So, what? look at these "caution" marked lines!
How did our c compiler treated our C code?
When a pointer comes, especially when we wrote a sentence like 
something = sizeof(one element of an array) / sizeof(the first element of that array)
the Compiler parse our syntax as the number of an array!
It's not finished yet.
I tested a "dynamic array", too. An array which allocate by malloc etc.
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int * a = NULL;
    int len = 0;
    a = (int *) calloc(7, sizeof(int));
    len = sizeof(a) / sizeof(a[0]);
    return 0;
}
Build.. Disassemble...
    int * a = NULL;
013830FE  mov         dword ptr [a],0  
    int len = 0;
01383105  mov         dword ptr [len],0  
    a = (int *) calloc(7, sizeof(int)); 
0138310C  mov         esi,esp  
0138310E  push        4  
01383110  push        7  
01383112  call        dword ptr [__imp__calloc (13882CCh)]  
01383118  add         esp,8  
0138311B  cmp         esi,esp  
0138311D  call        @ILT+300(__RTC_CheckEsp) (1381131h)  
01383122  mov         dword ptr [a],eax  
    len = sizeof(a) / sizeof(a[0]);
01383125  mov         dword ptr [len],1  // Hey!
    return 0;
0138312C  xor         eax,eax  
}
Do you see that? compiler missed our syntax at this time.
So the conclusion is:
When you write a sentence especially like:
something = sizeof(one element of an array) / sizeof(the first element of that array)
Compiler will understand and parse our code, and sign the array capacity to something. Only if the source array is a fixed array, or an array has already declared size previously. (At this time, the size is a constant may be stored in compiler's variable table.)
It basically like @rmn said.
That's what i found. May be worthless.