3.
char (*abc)[];


Rewrite it with all parentheses explicitly shown:
char ((*abc)[]);

and read it from the inside out:
  1. abc is being declared,
  2. it is a pointer to something,
  3. the something is an array of things,
  4. they are characters.
So abc is a pointer to an array of characters.

         Important Note
This is how number 2 really should have been written. In C, you are only supposed to mention the size of an array when you are actually allocating memory for it.
With number 1:
char *abc[100];

And the even simpler:
char abc[500];

In both cases we are actually creating a real array. The size is needed, otherwise it will be impossible to work out how much memory it needs.
But, with number 2:
char (*abc)[100];

We are creating a pointer that can point to an array. We are not creating the array itself, so there is no need to specify how big it will be. C actually ignores the 100. Putting the size there can be confusing because abc is actually capable of pointing to an array of any size at all.

         Remember Only give the size when an array is being created. Always give the size when an array is being created. Never give the size when no new array is being created by this declaration.
         That is why arrays never have a size when they are declared as parameters to functions. The parameter will really just be a pointer to another array that already exists.


A pointer usually requires 4 bytes, so (sizeof abc) is 4.