Setting up arrays in C - fixed size at compile time, or dynamic
Archive - Originally posted on "The Horse's Mouth" - 2011-01-24 08:30:08 - Graham EllisYou can store a whole series of data values of the same type in an array in C.
The easiest way to declare an array is something like:
int history[20];
and that will give you an array of 20 elements - which you can refer to as elements number 0 to 19, so:
history[4] = 1234;
to set the fifth element (care - counting starts at 0), or in a more general case"
history[iposn] = 2345;
where iposn is an integer variable itself, somewhere in the range 0 to 19, or looping through the values 0 to 19.
You won't always know when you write your program how big you need your array to be, and a very basic but simple solution is sometimes simply to allow as many elements as the maximum will ever be, then a few more for safety. This is a very crude technique, wasteful of memory, and prone to problems when it turns out that the figure you chose was not enough. I remember an example I wrote a year or two back on a course where I chose to have 10 elements in an array, which was to hold the ages of all the brothers and sisters of someone .... then I went round the room asking "how many siblings have you" to each of my class. One lady replied "22", and in subsequent conversation that turned out to be the actual truth, though she sis admit that about a half of them were halfbrothers and halfsisters.
You can easily change the size of the array at the time you compile the program by using a defined constant to the preprocessor - so:
#define TOP 6
and then:
int history[TOP];
and indeed you can also can also make the setting of such a variable from the compile line if you wish:
munchkin:cj grahamellis$ gcc -o afp -D TOP=3 afp.c
but you then need to amend your preprocessor directives to ensure that the setting within the code is merely a fallback:
#ifndef TOP
#define TOP 6
#endif
However, you're still looking at changing the size at compile time - if you want a program that can be altered at runtime, based on user inputs, values read from files or other resources, or passed in at the command line, you'll want to set up the memory area using functions such as malloc, calloc or realloc.
int *history = (int *)calloc(howmany, sizeof(int));
The variable "howmany" is an int, which - by the time calloc is called - needs to have been set up to the array size that's required. The memory is allocated on the "heap" so it has a different scope - it's not released at the end of the block in which it is declared, and that turns out to be both useful ad dangerous (if you've ever heard people talk about "memory leaks", they're talking about a long running program that does a lot of things like calloc, but never releases the memory again).
There is a complete example showing fixed size arrays [here], and one that uses calloc [here]. You'll note that - once the array has been set up - BOTH examples go on to access the data using both the [] and the * notation ... and that's because an array name is simply a pointer to the first element of the memory block that's allocated, be it at compile or run time, and be it on the stack (lost at the end of the block) or heap (retained until the program ends or you release it).
Bear in mind that - with all arrays - you as the programmer are responsible for ensuring that you don't use the array name to address off the end of the allocated memory. That means that you have to do a lot of checking, and that you'll need in your code to have some sort of way of knowing how big an array is. You may do that by passing a count around, or by having a specific value in the end of the array that indicates "end of data". That's how strings work - with a null character at the end. With double quoted strings, that's automatic ([example]) but at other times - such as when you're handling a string as an array oc characters - you MUST check - [example].