Although the concept of “array” in a
    programming language is intuitive, in C arrays are manipulated in a special
    way that must be clear to the programmer to avoid mistakes when combining
    its use with dynamic memory. In the C programming language, a table is
    internally represented only as the memory address from which the first
    element is stored. Another way of look at it, in C a table with 100 elements
    of type T is defined as T table[100], but once defined (and
    allocated the corresponding space in memory), the table (its name) and the address of
    its first element are exactly the same. This peculiar behavior can be
    summarized by saying that for any array in C the following expression is
    always true:
table == &table[0]The main consequence is that when dynamic memory space is
    required for a table, the allocation returns a pointer, but this pointer can
    be used directly as an array. For example, the following code creates a
    table with as many elements as the value of variable size and
    initializes all of them:
struct element 
{
  float number1;
  int number2;
  char letter;
};
struct element *table;
table = (struct element *)malloc(sizeof(struct element) * size);
for (i = 0; i < size; i++) 
{
  table[i].number1 = 0.0;
  table[i].number2 = 10;
  table[i].letter = 'B';
}It should be noted that the access to the elements in the array, after including the index in brackets, it is one as a regular structure an not as a pointer.
Therefore, there is a strong relationship between pointers and arrays. A pointer variable which points to the first element of an array can be used with the same operations (and with the same notation) than the ones defined for arrays. However, not all the operations over pointers are also valid with arrays. A pointer can be assigned the initial address of an array, but an array can not be assigned the value of a pointer or the address of another array. This is because when an array is declared, its address remains fixed, whereas a pointer can be assigned different values. The following code shows this situation.
1 2 3 4 5  | #define SIZE 30 char string1[SIZE]; char *string2; string1 = "Press space to continue"; /* Incorrect */ string2 = "Press space to continue"; /* Correct */  | 
Line 4 is incorrect because the array string1
    cannot be assigned a new address, its address is fixed when
    defined. string2 on the other hand, is declared as a pointer,
    and it can be assigned any address, and line 5 assigns the address of the
    string “Press space to continue"”.