This guide introduces some common data management techniques. While database uses are common in the computer world, data records can also be used to make more than one core execute the same piece of code differently.
Up to now, each function has been launched into its own core. With data, your code can make a single function get executed by different cores with different configurations, running at different rates, etc.
Just follow the links at the bottom of the page to get started.
As we learned in the Propeller C – Start Simple guide’s Variable Values and Addresses activity, each variable has its own memory address where its value is stored. This activity introduces pointer variables: variables that are declared for storing addresses instead of values. It also demonstrates how to use pointer variables to store variable addresses, and even find the value stored at a given address. Later on, these techniques will be useful for writing functions that are designed to receive variable addresses instead of variable values.
This first example program declares two int variables named varA and varB, along with a pointer variable named addr. It then sets addr to the address of varA and demonstrates how to use addr to get varA’s value as well as its address. Then, addr is set to varB’s address, and then it uses addr to get both varB’s value and address.
If you haven’t already installed the latest USB driver, SimpleIDE, or Learn folder, go to Propeller C – Set up SimpleIDE and Propeller C – Start Simple.
/* Pointers and Variables.c */ #include "simpletools.h" // Include simpletools library int varA = 100; // Declare & initialize varA int varB = 200; // Declare & initialize varB int *addr; // Address pointer variable int main() // Main function { addr = &varA; // Set pointer to varA address print("addr = &varA;\n\n"); // Show statement followed by... print(" &varA = %d\n", &varA); // varA address print(" varA = %d\n", varA); // varA value print(" addr = %d\n", addr); // Address addr stores print(" *addr = %d\n", *addr); // Value at address addr stores addr = &varB; // Set pointer to varB address print("\n\naddr = &varB;\n\n"); // Show statement followed by... print(" &varB = %d\n", &varB); // varB address print(" varB = %d\n", varB); // varB value print(" addr = %d\n", addr); // Address addr stores print(" *addr = %d\n", *addr); // Value at address addr stores }
The code starts by declaring and initializing two int variables, varA, and varB. These variables store values, with the varA variable initialized to 100, and varB variable to 200.
int varA = 100; int varB = 200;
This addr variable will store addresses. The * to the left of the variable tells the C compiler that it stores int variable addresses.
int *addr;
Now that the addr variable has been declared to store int addresses, this statement uses the & operator to get the address of varA and store it in addr.
addr = &varA;
This print statement just shows a text copy of the statement above so that it’s clear what happened in the SimpleIDE Terminal.
print("addr = &varA;\n\n");
This statement displays the address of varA using the & operator.
print(" &varA = %d\n", &varA);
This statement displays the varA variable’s value.
print(" varA = %d\n", varA);
Earlier, we saw that addr = &varA copied the address of varA to the addr variable. This print statement below displays the value addr stored, which should match the value displayed by the print statement that showed the value of &varA.
print(" addr = %d\n", addr);
This one is important. Let’s say the code needs to know the value varA stores, but all it has is varA’s address in the addr variable. The way to find out what’s stored at the address in the addr pointer variable is with the * operator. By placing it to the left of a pointer variable like addr, it returns the value stored at the address pointed to by the addr variable. If everything is correct, this will display the same value as the print statement that displays the value of varA.
print(" *addr = %d\n", *addr);
A pointer variable can be assigned different values as needed. Up to this point, it stored the address of varA. This next addr = &varB statement copies the address of the varB variable into addr. Then, a print statement displays a text copy of that statement.
addr = &varB; print("\n\naddr = &varB;\n\n");
This code repeats the same process for varB. First, it displays the address of varB with &varB. Then, it displays the value of varB. Third, it displays the address addr stores, which is the address of varB. Last, but not least, it displays the value varB stores with *addr.
print(" &varB = %d\n", &varB); print(" varB = %d\n", varB); print(" addr = %d\n", addr); print(" *addr = %d\n", *addr); }
The * operator to the left of a variable in a declaration makes it a pointer variable that will store addresses, not values.
After a pointer variable has been declared, the * operator to the left of it returns the value at the address the pointer variable currently stores. When addr stored the address of varA, the *addr operation returned the varA variable’s value. When addr stored the address of varB, the *addr operation returned the varB variable’s value.
Without the * operator, all we get from a pointer variable like addr is the address it stores.
Pointer variables can be used with arrays too. If an int array named arrayVar is declared, the starting address or the address of any of its elements can be copied to addr.
If addr stores the address of arrayVar[0], your code can add 1 to addr, and it’ll point to the address of arrayVar[1] even though that address is 4 bytes higher. In other words, addr = addr + 1 or addr++ will automatically add 4 to the addr variable to make it point at the next element in the array. If a character array were declared, like char myChars[10], each element would only be one byte apart. So, addr = myChars would make addr store the address of myChars[0], and addr++ would only increase the addr variables value by 1 to make it store the address of myChars[1].
Although array variables have addresses that increase sequentially, individual variables might not. For example, &varB is not necessarily &varA + 4. The compiler might decide to store those individual variables at addresses that are not sequential as part of its optimization process. So remember, addr +1 works for array variables, but not necessarily for individual variables declared sequentially.
The program can be expanded to make addr store array element addresses. For example addr = array copies the address of the first element in an array named array. (Remember, instead of using &array[0], we can just use array.) Here is a first step toward having more power with pointer variables. Instead of pointing at array[1] with addr = &array[1], the program can simply add 1 to addr. This can be done with addr = addr + 1, addr += 1, or even addr++. That’s all it takes, and adding 1 to addr causes the address it stores to increase by 4 since each int variable takes up 4 bytes. So, the next int variable has an address that is 4 higher than the previous.
There’s another way to get a value at the address a pointer variable. Instead of *addr, you can simply treat it like an array and use addr[0], which will return the value at the address of addr. Likewise, instead of addr += 1 to make it point at the next variable address, your code can just use addr[1].