In the last chapter, we worked with C strings, and a C string turned out to be a list of characters packed one next to the other in memory. C arrays are lists of other data types packed one next to the other in memory. Just as with strings, you deal with the list by holding onto the address of the first one.
Imagine that you wanted to write a program that would calculate the average of 3 grades. Create a new C Command Line Tool project and name it gradeInTheShade.
Edit main.c:
#include <stdio.h> #include <stdlib.h> // malloc(), free() float averageFloats(float *data, int dataCount) { float sum = 0.0; for (int i = 0; i < dataCount; i++) { sum = sum + data[i]; } return sum / dataCount; } int main (int argc, const char * argv[]) { // Create an array of floats float *gradeBook = malloc(3 * sizeof(float)); gradeBook[0] = 60.2; gradeBook[1] = 94.5; gradeBook[2] = 81.1; // Calculate the average float average = averageFloats(gradeBook, 3); // Free the array free(gradeBook); gradeBook = NULL; printf("Average = %.2fn", average); return 0; }
Build and run it.
malloc() allocates a buffer on the heap, so you need to make sure that you free it when you are done. Wouldn’t it be great if you could declare that buffer as part of the frame (on the stack) so that it would be deallocated automatically when the function is done executing? You can. Change main.c:
import <stdio.h> float averageFloats(float *data, int dataCount) { float sum = 0.0; for (int i = 0; i < dataCount; i++) { sum = sum + data[i]; } return sum / dataCount; } int main (int argc, const char * argv[]) { // Declares the array as part of the frame float gradeBook[3]; gradeBook[0] = 60.2; gradeBook[1] = 94.5; gradeBook[2] = 81.1; // Calculate the average float average = averageFloats(gradeBook, 3); // No need to free the array! // Cleanup happens automatically when the function returns printf("Average = %.2fn", average); return 0; }
Build and run it.
The string literal made it easy to pack an array with characters. There are also array literals. Use one to initialize gradeBook:
int main (int argc, const char *argv[]) { float gradeBook[] = {60.2, 94.5, 81.1}; float average = averageFloats(gradeBook, 3); printf("Average = %.2f", average); return 0; }
Build and run the program.
Notice that you didn’t need to specify the length of gradeBook as 3; the compiler figures that out from the array literal. You can use this type in many places where you might use *. For example, change the declaration of averageFloats() to do this:
float averageFloats(float data[], int dataCount) { float sum = 0.0; for (int i = 0; i < dataCount; i++) { sum = sum + data[i]; } return sum / dataCount; }