Fundamental C - Starting Pointers
Written by Harry Fairhead   
Monday, 15 June 2020
Article Index
Fundamental C - Starting Pointers
Address Operator
Arrays As Pointers

Initializing a Pointer – The Address Operator

The most direct, although not the most common way, to do the job is to simply assign an address to the pointer.

For example:

int *myPointer;
myPointer=0xFFFF;

where 0xFFFF is a hexadecimal literal. You can now try and print the int stored at address 0xFFFF:

printf("%d",*myPointer);

You are unlikely to see anything printed and your program should crash because there is little chance that address 0xFFFF is within your legal address space. However, if it was, and if you are working with a small embedded system it might be, then you would see whatever bits are stored at the address interpreted as an int. There is nothing illegal about the program, but you might see a warning due to the assignment of an int to a pointer to int. To do the job properly needs a cast – more of which later – for the moment we can ignore the problem. Direct assignment of this sort is not commonplace, but it is essential if you need to access memory-mapped hardware. You can learn more about this in Applying C For The IoT With Linux ISBN: 978-1871962611.

So how do you get an address that is valid within your program and which refers to a valid int, or whatever type the pointer is to reference?

There are a number of possible answers, but the most basic is the & or address operator.

This returns the address of any variable you apply it to.

This is literally what & does – it finds the address of what you apply it to, but a much better way to think of it is as converting a type into a pointer to that type.

For example:

int myVar;

is an int variable but:

&myVar;

is a pointer to int. At a slightly lower level it is also obvious that it is the address associated with myVar.

To be clear, if myVar is a type then &myVar is a pointer to the type. In most cases you can interpret this as the address of myVar.

 

You can see that * and & are inverse operators. The * operator makes a type from a pointer, whereas the & operator makes a pointer from a type.

For example:

int myVar=42;
int *myPointer;
myPointer=&myVar;
*myPointer=123;
printf("%d",*myPointer);

The first declaration creates an int and sets it to 42. Keep in mind that this int is just an area of memory at an address storing the bit pattern corresponding to 42 in binary.

The second declaration creates a pointer to int which is initialized in the next instruction to the address of myVar. You can say that myPointer is now a pointer to myVar or you could say that *myPointer is the same as myVar.

The next line stores 123 in the memory pointed to by myPointer, i.e. it has the same effect as myVar=123.

Finally we print *myPointer and see 123.

Pointer beginners often have difficult in following what is going on.

If you always think that if myPointer is a pointer to an int then *myPointer is an int and if myVar is an int then &myVar is a pointer to an int, then you should find it easier.

What do the following print?

printf("%d \n",*myPointer);
printf("%p \n",myPointer);
printf("%p \n",&myPointer);

The first prints the int that is *myPointer i.e. 123, the second prints the address of *myPointer and the third prints the address of the variable myPointer. Notice the use of %p to format an address in hex. You can use %d if you want to see the address in decimal.

To summarize:

 

  • type *variable declares *variable to be the type and hence variable to be a pointer to type.

  • If variable is a pointer to type, the dereference operator makes it a type. That is, if variable is a pointer to type, *variable is the type.

  • If variable is declared to be type then &variable is a pointer to type, i.e. an address.

  • That is, * makes a type out of a pointer and & makes a pointer out of a type.



Last Updated ( Monday, 15 June 2020 )