In the context of function parameters, there's no difference. However, the sub-script form is used to declare an array, whereas the asterisk form is used to declare a pointer to a T.
So basically, the two forms are equivalent in most, if not all, contexts.
Right now they are equivalent, but it's good to have background understanding and not just treat them equally. Difference start emerging when array assignment is done. For example. Dynamic memory allocation and unallocation is different in both cases. Pointer increment/decrement behaves differently, etc.
Because there are semicolons at the end of these lines, I doubt this is a question about function parameters.
The first line creates an object of type pointer to int, and leaves it uninitialized, that is, it's not pointing at any int in particular.
The second line is an error. But if you put a constant expression between those brackets, e.g. int i[10];, it will create an array containing the specified number of ints.
Wazzak: same reason you can take a square root of 2 in C. When you're attempting an invalid operation, the compiler will check if there exist implicit conversions from the argument you've supplied to some overload of operator* or sqrt(). The existence of a conversion doesn't mean that arrays are pointers anymore than that ints are doubles.
"if there exist implicit conversions from the argument you've supplied to some overload of operator*" ...got me thinking. Maybe dereferencing an array yields a pointer holding the address of an array element, giving the impression an array was implemented with pointers? Anyway, I'm not going to hijack this thread.
The first declaration is a pointer to a int. A pointer, if you don't already know, points to the location of another int. With that said, it's safe to say a pointer holds the address of another int object.
The second declaration is an array of ints (a group).
And when I said, "In the context of function parameters, there's no difference", I mean the two forms are pointers if they were parameters.