why this error happens?
Objects with static storage duration are instantiated (have memory set aside for them) before the program begins execution; that means the size of the arr has to be known at compile time. Even though we have an initializer for num, that's not the same thing as the value num being known at compile time; num doesn't exist until after the program begins execution.
Arrays declared at file scope (outside of any function) or with the static keyword have to be declared with a size that's a constant expression - either an integer constant like 1024, a sizeof expression like sizeof (some-type) or sizeof some-expression, an arithmetic expression involving either of the previous (such as 1024*1024 or 5000 * sizeof (int)), or a macro that expands to any of the above. Or they can be declared without a size and the size is taken from the number of elements in the initializer.
why a constant is not a constant in C?
500 is a constant - num is not. Again, num doesn't exist until run time, but the size of arr has to be known before run time. Adding the const keyword such as
const int num = 500;
doesn't help - all that const does is tell the compiler to yell at you if you try to assign a new value to num. It doesn't make num a constant expression (in C, anyway - in C++ it does).
how could i solve it without using a ture constant,like 5000?
At this point, you're pretty much limited to using dynamic memory.
what function can take the place of static to storage large array?
Use either malloc or calloc to allocate space for the array at runtime:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
size_t num = 500; // or whatever value you ultimately need
/**
* Dynamically allocate enough space for "num" objects of type "int".
*
* calloc will zero out the allocated memory (malloc does not).
*
* calloc will return NULL if it cannot satisfy the request, so we
* want to make sure "arr" isn't NULL before trying to use it.
*
* The type of the *expression* "*arr" is "int", so "sizeof *arr" == "sizeof (int)"
*/
int *arr = calloc( num, sizeof *arr );
if ( arr )
{
printf( "%d\n", arr[0] );
/**
* Deallocate "arr" when you're done with it
*/
free( arr );
}
return 0;
}
A big advantage of using dynamic memory like this is that you can resize the array as necessary using realloc - can't do that with fixed-sized arrays (static or not).
As of C99, you can declare arrays with runtime variables as the size:
int num = 500;
int arr[num];
These are called variable length arrays and work just fine (in most C99 and later implementations), but because their size isn't known until runtime they cannot be declared static or at file scope, and they can't be declared with any initializers. Like other auto arrays, they can't be arbitrarily large. And despite their name, they cannot be resized once defined - the "variable" in "variable length" just means their size can be different each time they are instantiated.