Why is this done? This is done so changes to the array can be made without making other changes, reducing the chances of introducing bugs and/or outright failures from incorrect code.
TLDR answer:
This construct automates the counting of the elements of the array so that it doesn't depend on a human typing in a number - a number that can be wrong...
Full Answer
If the code were
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
int main()
{
int i;
for (i = 0; i < 6; i++)
sum += arr[i];
}
instead, if the array is changed by removing an element to
static int arr[] = { 1, 10, 4, 5, 6 };
the code would be broken.
This code
static const int n = sizeof(arr) / sizeof(arr[0]);
would work with all of the following definitions of arr
:
static int arr[] = { 1, 10, 4, 5, 6, 7 };
or
unsigned long long arr[ NUM_ELEMENTS ];
or
static float arr[] = { 12.4, 54.2 };
Your original code
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]); //RIGHT HERE!!!!!
int main()
{
int i;
for (i = 0; i < n; i++)
sum += arr[i];
}
would (mostly) work with any of those definitions of arr
.
(Undefined behavior from signed integer overflow could be more likely to happen for some of those definitions, but that's not addressed in the original code either)