Most of your questions have been answered, but just to give an answer that made my life a lot easier: 
Qualitatively the maximum size of the non-dynamically allocated array depends on the amount of RAM that you have. Also it depends on the type of the array, e.g. an int may be 4 bytes while a double may be 8 bytes (they are also system dependent), thus you will be able to have an array that is double in number of elements if you use int instead of double.
Having said that and keeping in mind that sometimes numbers are indeed important, here is a very noobish code snippet to help you extract the maximum number in your system.
#include <stdio.h>
#include <stdlib.h>
#define UPPER_LIMIT 10000000000000 // a very big number
int main (int argc, const char * argv[])
{
    long int_size = sizeof(int);
    for (int i = 1; i < UPPER_LIMIT; i++)
    {
        int c[i];
        for (int j = 0; j < i; j++)
        {
            c[j] = j;
        }
        printf("You can set the array size at %d, which means %ld bytes. \n", c[i-1], int_size*c[i-1]);
    }    
}
P.S.: It may take a while until you reach your system's maximum and produce the expected Segmentation Fault, so you may want to change the initial value of i to something closer to your system's RAM, expressed in bytes.