Arduino C Pointers


Below is an arduino program which demonstrates some basic principles about pointers.

Keep in mind, memory pointers (i.e. pointers to variables) are pointers to SRAM memory, while function pointers are pointers to flash memory. The AVR uses a modified Harvard Architecture, which allows the contents of the instruction memory to be accessed as if it were data. However, there are restrictions imposed upon access to flash memory. Most modern computers that are documented as Harvard Architecture (like the arduino) are, in fact, Modified Harvard Architecture.

memory map

So, considering the different types of memory in an 8-bit AVR µC, there are several overlapping addresses. For example, there is a 0x0000 address for each type, SRAM, flash and EEPROM. SRAM can be addressed via standard C pointers. Flash functions can be addresses per standard C pointers, however data placed in flash requires the use of the PROGMEM routines found in pgmspace.h. And finally EEPROM requires the use of the EEPROM routines found in eeprom.h.

Simple demonstration program:

//pointers by example

void setup() {
  char text[32];

  //pointer basics
  uint8_t n;  //declare a byte
  uint8_t *p; //declare a pointer to any uint8_t size variable
  n = 0x11;   //initialize n
  p = &n;     //initialize p to the address of n (p points to n)
  sprintf(text, " n = %x (n)\n", n); Serial.print(text);
  sprintf(text, "&n = %x (address of n)\n", &n); Serial.print(text);
  sprintf(text, " p = %x (address of n)\n", p); Serial.print(text);
  sprintf(text, "&p = %x (address of p)\n", &p); Serial.print(text);
  sprintf(text, "*p = %x (n)\n", *p); Serial.print(text);
  *p = 0x22;   //assign value to what p points at (n)
  sprintf(text, "After *p = 0x22, n = %x\n", n); Serial.print(text);

  //pointer arithmetic
  uint8_t a[] = { 1, 2, 3 }; //declare an array
  uint8_t *pa = a;           //declare pa and initailize to point to a
  pa = a;                    //does same as above
  sprintf(text, " a[0] = %x\n", a[0]); Serial.print(text);
  sprintf(text, "&a[0] = %04x (address of a)\n", &a[0]); Serial.print(text);
  sprintf(text, "   pa = %04x (address of a)\n", pa); Serial.print(text);
  sprintf(text, "  *pa = %x (a[0])\n", *pa); Serial.print(text);
  pa += 1;                   //increment pointer
  sprintf(text, "After increment, pa = %04x\n", pa); Serial.print(text);
  sprintf(text, "  *pa = %x (a[1])\n", *pa); Serial.print(text);
  //machine endianness == little endian
  uint32_t n32 = 0x12345678;     //declare and initialize 32-bit number (not order of digits)
  uint8_t* pn = (uint8_t *)&n32; //declare uint8_t pointer to 1st byte of 32-bit number
  for (uint8_t i=0; i<4; i++) {
    //iterate through all 4-bytes of n32, noting order of digits
    sprintf(text, "%p: %02x \n", pn, (uint8_t)*pn++); Serial.print(text);
  //function pointer
  int16_t (*fptr)(int16_t); //declare a function pointer
  int16_t x = 5;            //initalze x for demonstration
  fptr = square;            //point fptr to square() function
  //call square using function pointer
  sprintf(text, "%d squared is %d\n", x, fptr(x)); Serial.print(text);
  //note: fptr is a word address 
  sprintf(text, " fptr = %04x (address of function square()\n", fptr); Serial.print(text);
  sprintf(text, "&fptr = %04x (address of fptr)\n", &fptr); Serial.print(text);

//example function
int16_t square(int16_t n) {
  return n*n;

void loop() { }

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

1 Response to Arduino C Pointers

  1. lu says:

    Clear explanation to help to understand addresses and pointers!!!!! Thank you!!!!!!!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s