6. Arrays, Structs, Pointers
6.1. Purpose
This activity introduces “more advanced” features of the C language; useful in building programs or implementing TI DriverLib functions.
6.2. Hardware and Tools
[Optional] MSP-EXP432P401R Launchpad Development Board or TI-RSLK Robotic Car
6.3. Preparation
Review the website descriptions for Arrays, Structs, and Pointers.
6.4. Instructions
The following steps will guide you through implementing and using arrays and structs. Pointers are also used, but to a much more limited extent.
Let’s first take a look at arrays.
6.4.1. Arrays
This task will build a multiplication table from the numbers contained in two arrays.
First, download and import the course template project:
TemplateProject.zip
. You should rename the imported project to something like “Activity-Arrays.”Alternatively: use the default template for an online C-Compiler. You may need to add #include<stdint.h> to the top of the default template for it to recognize the
[u]intN_t
types.
Let’s create an array full of numbers. Copy and paste the below line such that the array variable,
array1
, will be a global variable.uint32_t array1[] = {1,2,3,4,5,6,7,8,9,10};
This code will create an array of length 10 with the shown values.
Let’s ensure that the array is created appropriately. Add the below
for
loop to print out each element of the array within themain
function, just prior to thewhile(1)
. Compile and run the code to test (ensure the terminal is connected).uint8_t i; // Loop count variable for(i=0;i<10;i++){ // Loop through the indices of the array printf("Element %u is:\t%u\r\n",i,array1[i]); }
Now we need a second array. Create an empty second array of length 10 and then fill the array with random values between 0 and 20. You can use the
for
loop in the previous step to accomplish this. You should use the function rand() to generate the random values.Modify the
printf
statement to print out the values stored into the second array after they are generated. Compile and run the code to test.Now build out the multiplication table formed by our two arrays. We’ll need a 2D array to store the values into. Create an empty 2D array that is 10x10 (same size as each array). A 2D array may be created by using the format
<type> var[m][n]
, wherem
andn
are the dimension sizes.The easiest way to do fill the table is with two nested
for
loops, something like:uint8_t i,j; // Two loop variables for(i=0;i<10;i++){ // Outer loop for(j=0;j<10;j++){ // Inner loop // In here we can use i and j to loop through elements, // where i and j will be the row/column index of the 2d matrix } }
Add code to print out the multiplication table. You may remove the previous
printf
commands used. As this print is fairly complicated, the code to do so is provided below, with some portions missing, marked with???
.// This portion prints one of the input arrays column header (horizontal) printf("\n\n\t"); // Move down a couple lines and skip the first "column" for(i=0;i<10;i++){ printf("\t%u",???); // Print each element in the array, one each column (tab) } printf("\r\n"); // move to the next line to print the table // This portion prints the other input array as the row headers (vertical) // and the multiplication table (2D array) for(i=0;i<10;i++){ printf("\t%u",???); // Print the i-th element of the input array for(j=0;j<10;j++){ printf("\t%u",???); // print all the elements of the i-th row for the table } printf("\r\n"); // move to next line }
If all is successful, you should see output like below; where the blue box marks a set of input array elements, the red box marks the other set of input array elements, and the green box is the calculated multiplication table 2D array. Of course, this output assumes that both input arrays have the values 1-10 instead of one being random. It must be ensured that the multiplication table matches that of the input arrays used and that the table is not flipped
Finally, modify the length of the randomly generated array to 15. This will require that several items (
for
loop conditions) be adjusted as well to ensure the code still works appropriately.
Tip
At this point, you may have noticed that the “random numbers” that are being generated to fill the array are always the same sequence and therefore not actually random. See srand for information on how to avoid this situation. It is not necessary to fix this in this program.
6.4.2. Structs
This task will provide an example on how to use predefined structs in programming tasks. In this case, we will use a struct to store information about the set of homework grades below:
Homework
1
2
3
4
5
Average
94.2
76.7
84.5
92.1
66.3
Std. Dev.
10.8
12.6
15.9
12.6
27.3
Minimum
55
40
25
45
10
Maximum
100
100
100
100
100
Submissions
109
106
101
99
99
First, let’s prepare another fresh template project:
TemplateProject.zip
. You should rename the imported project to something like “Activity-Structs”.Alternatively: use the default template for an online C-Compiler.
We don’t expect students to know how to create a struct in this course, just how to use them; therefore, a struct definition is given below for storing the homework information. Copy and paste this code above where function prototypes would exist.
// This is one implementation for creating a custom struct variable type named "homework_t" typedef struct _homework_t { float average; // The struct has a "field" for each value listed float stdev; // in the "Homework Gradebook" table. uint8_t min; // Note that the fields can be all different types uint8_t max; uint16_t subs; } homework_t;
Now create a global variable and store the values of homework 1 from the table. The commands to store the values may be done within the
main
function.Tip
The variable type to create the homework struct is
homework_t
. This should be used the exact same way that you would useuint32_t
, etc.Tip
Dot notation is used to assign values to each struct field; for example:
struct_name.field
. If CCS recognizes the type of the struct, then as you type the variable name followed by a period, CCS should pop up a list of the available fields. This features is extremely useful when using unfamiliar and/or complicated struct types.You may check if your work was correct by using the print statement below and replacing the
???
instances with the variable name you used. The Edit → Find/Replace… function may be useful in doing this.printf("Homework 1 Stats\r\n" " Average: %.2f\r\n" " Std. Dev.: %.2f\r\n" " Minimum: %u\r\n" " Maximum: %u\r\n" "Submissions: %u\r\n", ???.average,???.stdev,???.min, ???.max,???.subs);
We could make a new
homework_t
variable for each homework; however, this implementation would be tedious and inflexible. Instead, it would make sense to make an array ofhomework_t
variables, where index 0 is homework 1, index 1 is homework 2, etc. Make this array now as a global variable and populate at least two of the indices with homework stats. Make sure to leave the non-arrayhomework_t
variable created in step 3.Tip
Accessing fields of an array element works the same way as if it was a single variable:
array[n].field = value;
.Modify the print statement such that all homework stats are printed consecutively. You’ll want to wrap the print statement in a
for
loop. You do not need to format the print statement to match the table format above, just print all of each homework’s stats one at a time.
6.4.3. Passing Structs as Pointers
Add the following function to your struct program. This function calculates a homework average without the minimum grade included.
// Prototype. Add above main function, below the homework_t definition. float remove_min_from_avg(homework_t *homework); // Declaration. Add below main function // This function calculates the average of a homework without the minimum grade. // The function will return the value of the new average. float remove_min_from_avg(homework_t *homework){ float homework_sum = homework->average*homework->subs; homework_sum -= homework->min; return homework_sum/(homework->subs-1); }
Using this function, calculate the modified average of homework 1 new
float
value. Use the singlehomework_t
variable created in step 3, not the array created in step 5. You will need to use the&
operated as discussed here: Pointers.Print out the value of the calculated average to verify it worked.
Repeat the calculation for homework 2. This can be done using the homework array using the format
&array[n]
.
6.4.4. Submit Work
Submit both final code files to the corresponding Gradescope activities. You should rename the files to an appropriate name prior to submission (e.g., arrays.c and structs.c).