I suggest a trip to the bookstore to pickup a copy of Kernighan and Ritchie's The C Programming Language, and optionally, a copy of Harbison & Steele's C: A Reference Manual.
The first case gives you an array of 100 ints, allocated on the stack. The latter case gives you a pointer to an int, whose address is that of a buffer allocated on the heap, the size of which is large enough to contain 100 ints.
The C language is fundamentally a hardware agnostic assembly language. The distinction between a pointer and an array is intentionally fuzzy, since array reference notation is syntactic sugar for pointer arithmetic. This:
int foo( int a )
{
int x[100] = load_X() ;
int y = x[ a ] ;
return y ;
}
is identical to
int foo( int a )
{
int *x = load_X() ;
int y = *( x + a ) ;
// note that the use of sizeof() isn't required. For the pointer carries around
// an implicit increment size (the size of the object to which it points). The above
// is equivalent to
//
// int y = *(int*)((char*)x + (a*sizeof(*x)) ) ;
}
Further, the compiler will (or should) whine about type mismatches, given function foo()
:
public void foo( int a[] )
{
...
}
The invocation:
int *p = malloc(...) ;
foo(p) ;
should results in a compiler whine regarding type mismatches.