C Pointers

Variable Values & Locations

A variable

  • is a piece of data - size depends on type
  • is stored in memory
  • has a name - chosen when the variable is created
  • has an address, its location in memory
Variables, values, address in memory

Pointers to Memory Addresses

C allows us to work directly with memory addresses. On the previous page we used this to view the location variables are stored in.

#include <stdio.h>
#include <stdalign.h>

int main(void) {

int integer1=1;
int integer2=2;
int integer3=3;

printf("integer1 = %d Memory address %p\n",integer1,&integer1);
printf("integer2 = %d Memory address %p\n",integer2,&integer2);
printf("integer3 = %d Memory address %p\n",integer3,&integer3);

return 0;
}
integer1 = 1 Memory address 0x7ffe196e4ad8
integer2 = 2 Memory address 0x7ffe196e4ad4
integer3 = 3 Memory address 0x7ffe196e4ad0

We can use the ampersand & to get the memory address of a variable. We can store the address in a pointer. A pointer is a variable whose value is the address of another variable. The general form of a pointer declaration is -
type *var-name;
type is the pointer’s base type, based on the data being stored at the memory address. We use an asterisk

int     *intPointer;      /* Pointer to an integer */
double  *dblPointer;      /* Pointer to a double */
float   *fltPointer;      /* Pointer to an float */
char    *chrPointer;      /* Pointer to an char */

The code above can be written using pointer variables.

int  integer1 = 1;
int* integer1_p = &integer1;

printf("integer1 = %d Memory address %p\n", integer1, integer1_p);

Using Pointers

We can use the memory address, the pointer, to access the contents of the memory. We use the asterisk to ask the data from the pointer.

#include <stdio.h>

int main () {

  int var = 20;    /* actual variable declaration */
  int * ip;        /* pointer variable declaration */

  ip = &var;       /* store address of var in pointer variable*/

  printf("value of var variable: %d\n", var);

  printf("Address of var variable: %p\n", &var  );

  /* address stored in pointer variable */
  printf("Address stored in ip variable: %p\n", ip );

  /* access the value using the pointer */
  printf("Value of *ip variable: %d\n", *ip );

  return 0;
}
value of var variable: 20
Address of var variable: 0x7ffe00b8ca08
Address stored in ip variable: 0x7ffe00b8ca08
Value of *ip variable: 20
*(&i) &i i
Value Address Value

Note pointers are not initialised when created by int *i_pointer. When we use *i_pointer to access the memory of whatever i_pointer is pointing at C will interpret whatever is in that memory location as an integer, regardless of what that data actually is. This is potentially dangerous. As such we should always initialise pointers when we create them, either to a valid address or to NULL (int *i_pointer = NULL), and then test to see if a pointer is NULL before using it.

#include <stdio.h>

int main () {

  int var = 20;       
  int *ip1 = &var;    
  int *ip2 = NULL;

  if (ip1!=NULL)
  {
    printf("Address stored in ip1 variable: %p\n", ip1 );
  }
  else
  {
    printf("ip2 invalid pointer\n");
  }

  if (ip2!=NULL)
  {
    printf("Address stored in ip2 variable: %p\n", ip2 );
  }
  else
  {
    printf("ip2 invalid pointer\n");
  }

  return 0;
}
Address stored in ip1 variable: 0x7ffdafff5b28
ip2 invalid pointer