Intro to Pointer Variables

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.

 

Test Code

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.

  • Click SimpleIDE’s New Project button, and browse to …Documents/SimpleIDE/Learn/
  • Use the New Folder button to create a folder named Pointers on Data
  • Open Pointers on Data
  • Set the File Name of the new project to Pointers and Variables
  • Enter the code below into SimpleIDE
  • Click the Run with Terminal button
  • Check the addr = &varA section in SimpleIDE Terminal. Verify that &varA and addr match, and that varA and *addr are both 100
  • In the addr = &varB section, verify that &varB and addr match, and that varB and *addr are both 200
/*
  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
}

 

How it Works

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);
}

 


Did You Know?

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. 


 

Try This

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.

  • Use the Save Project As button to save a copy of your project as Pointers and Variables (Try This) in …Documents\SimpleIDE\My Projects
  • Add the lines shown below
  • Run the program and verify the output

Your Turn

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].   

  • Use Save Project As to make a copy of the Try This code as Pointers and Variables (Your Turn).
  • Modify the array section as shown here.
  • Verify that the modified addr[0] can be used in place of  *addr and addr[1] can be used in place of addr += 1; ... *addr;.
  • Another combination that works is to use *(addr + 1) in place of addr[1].  Try that too.